# Ticket #14334: trac_14334_integration_multipoly-fc.patch

File trac_14334_integration_multipoly-fc.patch, 13.3 KB (added by Frédéric Chapoton, 9 years ago)
• ## sage/misc/functional.py

```# HG changeset patch
# User Frederic Chapoton <chapoton at math.univ-lyon1.fr>
# Date 1363961837 -3600
# Node ID 766b21557f67b9b74b5a9b3462f0a82e67a46e3c
# Parent  5683d7fca739649ee135a5b897383633444765a5
trac #14334 : integration of polynomials and power series wrt any variable

diff --git a/sage/misc/functional.py b/sage/misc/functional.py```
 a def symbolic_sum(expression, *args, **kw from sage.symbolic.ring import SR return SR(expression).sum(*args, **kwds) def integral(x, *args, **kwds): """ Returns an indefinite or definite integral of an object x. First call x.integrate() and if that fails make an object and First call x.integral() and if that fails make an object and integrate it using Maxima, maple, etc, as specified by algorithm. For symbolic expression calls ``sage.calculus.calculus.integral`` - see this function for :func:`sage.calculus.calculus.integral` - see this function for available options. EXAMPLES:: def integral(x, *args, **kwds): integrate = integral def integral_closure(x): """ Returns the integral closure of x.
• ## sage/rings/polynomial/multi_polynomial_element.py

`diff --git a/sage/rings/polynomial/multi_polynomial_element.py b/sage/rings/polynomial/multi_polynomial_element.py`
 a class MPolynomial_polydict(Polynomial_si Q, _ = self.quo_rem(right) return Q def _derivative(self, var=None): r""" Differentiates self with respect to variable var. If var is not one of the generators of this ring, _derivative(var) Differentiates ``self`` with respect to variable ``var``. If ``var`` is not one of the generators of this ring, _derivative(var) is called recursively on each coefficient of this polynomial. .. seealso:: :meth:`derivative` .. SEEALSO:: :meth:`derivative` EXAMPLES:: sage: R. = PowerSeriesRing(QQbar) sage: S. = PolynomialRing(R) sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 sage: type(f) sage: f.parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field sage: f._derivative(x)   # with respect to x (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 sage: f._derivative(x).parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field sage: f._derivative(y)   # with respect to y (3*t^2 + O(t^3))*x^2*y^2 sage: f._derivative(t)   # with respect to t (recurses into base ring) class MPolynomial_polydict(Polynomial_si ValueError: must specify which variable to differentiate with respect to """ if var is None: raise ValueError, "must specify which variable to differentiate with respect to" raise ValueError("must specify which variable to differentiate with respect to") gens = list(self.parent().gens()) class MPolynomial_polydict(Polynomial_si d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) return MPolynomial_polydict(self.parent(), d) def integral(self, var=None): r""" Integrates ``self`` with respect to variable ``var``. .. NOTE:: The integral is always chosen so the constant term is 0. If ``var`` is not one of the generators of this ring, integral(var) is called recursively on each coefficient of this polynomial. EXAMPLES: On polynomials with rational coefficients:: sage: x, y = PolynomialRing(QQ, 'x, y').gens() sage: ex = x*y + x - y sage: it = ex.integral(x); it 1/2*x^2*y + 1/2*x^2 - x*y sage: it.parent() == x.parent() True On polynomials with coefficients in power series:: sage: R. = PowerSeriesRing(QQbar) sage: S. = PolynomialRing(R) sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 sage: f.parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field sage: f.integral(x)   # with respect to x (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4 sage: f.integral(x).parent() Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field sage: f.integral(y)   # with respect to y (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y sage: f.integral(t)   # with respect to t (recurses into base ring) (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3 TESTS:: sage: f.integral()    # can't figure out the variable Traceback (most recent call last): ... ValueError: must specify which variable to integrate with respect to """ if var is None: raise ValueError("must specify which variable to integrate " "with respect to") gens = list(self.parent().gens()) # check if var is one of the generators try: index = gens.index(var) except ValueError: # var is not a generator; do term-by-term integration recursively # var may be, for example, a generator of the base ring d = dict([(e, x.integral(var)) for (e, x) in self.dict().iteritems()]) d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) return MPolynomial_polydict(self.parent(), d) # integrate w.r.t. indicated variable d = {} v = polydict.ETuple({index:1}, len(gens)) for (exp, coeff) in self.dict().iteritems(): d[exp.eadd(v)] = coeff / (1+exp[index]) d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) return MPolynomial_polydict(self.parent(), d) def factor(self, proof=True): r""" Compute the irreducible factorization of this polynomial.
• ## sage/rings/polynomial/multi_polynomial_libsingular.pyx

`diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx`
 a cdef class MPolynomial_libsingular(sage. return new_MP(self._parent,p) def integral(self, MPolynomial_libsingular var): """ Integrates this polynomial with respect to the provided variable. One requires that `\QQ` is contained in the ring. INPUT: - ``variable`` - the integral is taken with respect to variable EXAMPLES:: sage: R. = PolynomialRing(QQ, 2) sage: f = 3*x^3*y^2 + 5*y^2 + 3*x + 2 sage: f.integral(x) 3/4*x^4*y^2 + 5*x*y^2 + 3/2*x^2 + 2*x sage: f.integral(y) x^3*y^3 + 5/3*y^3 + 3*x*y + 2*y TESTS:: sage: z, w = polygen(QQ, 'z, w') sage: f.integral(z) Traceback (most recent call last): ... TypeError: the variable is not in the same ring as self """ if var is None: raise ValueError("please specify a variable") ring = var.parent() if ring is not self._parent: raise TypeError("the variable is not in the same ring as self") if not ring.has_coerce_map_from(RationalField()): raise TypeError("the ring must contain the rational numbers") gens = ring.gens() try: index = gens.index(var) except ValueError: raise TypeError("not a variable in the same ring as self") d = {} v = ETuple({index:1}, len(gens)) for (exp, coeff) in self.dict().iteritems(): d[exp.eadd(v)] = coeff / (1+exp[index]) return MPolynomial_polydict(self.parent(), d) def resultant(self, MPolynomial_libsingular other, variable=None): """ Compute the resultant of this polynomial and the first
• ## sage/rings/polynomial/polynomial_element.pyx

`diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx`
 a cdef class Polynomial(CommutativeAlgebra coeffs = self.list() return self._parent([n*coeffs[n] for n from 1 <= n <= degree]) def integral(self): def integral(self,var=None): """ Return the integral of this polynomial. .. note:: The integral is always chosen so the constant term is 0. By default, the integration variable is the variable of the polynomial. Otherwise, the integration variable is the optional parameter ``var`` .. NOTE:: The integral is always chosen so the constant term is 0. EXAMPLES:: sage: R. = ZZ[] sage: R(0).integral() 0 sage: f = R(2).integral(); f 2*x Note that the integral lives over the fraction field of the scalar coefficients:: sage: f.parent() Univariate Polynomial Ring in x over Rational Field sage: R(0).integral().parent() Univariate Polynomial Ring in x over Rational Field sage: f = x^3 + x - 2 sage: g = f.integral(); g 1/4*x^4 + 1/2*x^2 - 2*x sage: g.parent() Univariate Polynomial Ring in x over Rational Field This shows that the issue at trac #7711 is resolved:: This shows that the issue at :trac:`7711` is resolved:: sage: P. = PolynomialRing(GF(2147483647)) sage: Q. = PolynomialRing(P) cdef class Polynomial(CommutativeAlgebra Univariate Polynomial Ring in x over Power Series Ring in c over Univariate Polynomial Ring in b over Multivariate Polynomial Ring in a1, a2 over Rational Field """ Integration with respect to a variable in the base ring:: sage: R. = QQ[] sage: t = PolynomialRing(R,'t').gen() sage: f = x*t +5*t^2 sage: f.integral(x) 5*x*t^2 + 1/2*x^2*t """ if var is not None and var != self._parent.gen(): # call integral() recursively on coefficients return self._parent([coeff.integral(var) for coeff in self.list()]) cdef Py_ssize_t n, degree = self.degree() R = self.parent() Q = (self.constant_coefficient()/1).parent()
• ## sage/rings/power_series_poly.pyx

`diff --git a/sage/rings/power_series_poly.pyx b/sage/rings/power_series_poly.pyx`
 a cdef class PowerSeries_poly(PowerSeries) return PowerSeries_poly(self._parent, self.__f._derivative(), self.prec()-1, check=False) def integral(self): def integral(self,var=None): """ The integral of this power series with 0 constant term. The integral of this power series By default, the integration variable is the variable of the power series. Otherwise, the integration variable is the optional parameter ``var`` .. NOTE:: The integral is always chosen so the constant term is 0. EXAMPLES:: sage: k. = QQ[[]] sage: (1+17*w+15*w^3+O(w^5)).integral() w + 17/2*w^2 + 15/4*w^4 + O(w^6) w + 17/2*w^2 + 15/4*w^4 + O(w^6) sage: (w^3 + 4*w^4 + O(w^7)).integral() 1/4*w^4 + 4/5*w^5 + O(w^8) sage: (3*w^2).integral() w^3 TESTS:: sage: t = PowerSeriesRing(QQ,'t').gen() sage: f = t + 5*t^2 + 21*t^3 sage: g = f.integral() ; g 1/2*t^2 + 5/3*t^3 + 21/4*t^4 sage: g.parent() Power Series Ring in t over Rational Field sage: R. = QQ[] sage: t = PowerSeriesRing(R,'t').gen() sage: f = x*t +5*t^2 sage: f.integral() 1/2*x*t^2 + 5/3*t^3 sage: f.integral(x) 1/2*x^2*t + 5*x*t^2 """ return PowerSeries_poly(self._parent, self.__f.integral(), self.prec()+1, check=False) return PowerSeries_poly(self._parent, self.__f.integral(var), self.prec()+1, check=False) def reversion(self, precision=None): """