Ticket #14334: trac_14334_integration_multipoly-fc.patch

File trac_14334_integration_multipoly-fc.patch, 13.3 KB (added by chapoton, 8 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 b def symbolic_sum(expression, *args, **kw 
    658658        from sage.symbolic.ring import SR
    659659        return SR(expression).sum(*args, **kwds)
    660660
     661
    661662def integral(x, *args, **kwds):
    662663    """
    663664    Returns an indefinite or definite integral of an object x.
    664665   
    665     First call x.integrate() and if that fails make an object and
     666    First call x.integral() and if that fails make an object and
    666667    integrate it using Maxima, maple, etc, as specified by algorithm.
    667668
    668669    For symbolic expression calls
    669     ``sage.calculus.calculus.integral`` - see this function for
     670    :func:`sage.calculus.calculus.integral` - see this function for
    670671    available options.
    671672   
    672673    EXAMPLES::
    def integral(x, *args, **kwds): 
    751752
    752753integrate = integral
    753754
     755
    754756def integral_closure(x):
    755757    """
    756758    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 b class MPolynomial_polydict(Polynomial_si 
    14231423        Q, _ = self.quo_rem(right)
    14241424        return Q
    14251425
    1426 
    14271426    def _derivative(self, var=None):
    14281427        r"""
    1429         Differentiates self with respect to variable var.
    1430        
    1431         If var is not one of the generators of this ring, _derivative(var)
     1428        Differentiates ``self`` with respect to variable ``var``.
     1429
     1430        If ``var`` is not one of the generators of this ring, _derivative(var)
    14321431        is called recursively on each coefficient of this polynomial.
    1433        
    1434         .. seealso::
    14351432
    1436            :meth:`derivative`
    1437        
     1433        .. SEEALSO::
     1434
     1435            :meth:`derivative`
     1436
    14381437        EXAMPLES::
    1439        
     1438
    14401439            sage: R.<t> = PowerSeriesRing(QQbar)
    14411440            sage: S.<x, y> = PolynomialRing(R)
    14421441            sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
    1443             sage: type(f)
    1444             <class 'sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict'>
     1442            sage: f.parent()
     1443            Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field
    14451444            sage: f._derivative(x)   # with respect to x
    14461445            (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2
     1446            sage: f._derivative(x).parent()
     1447            Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field
    14471448            sage: f._derivative(y)   # with respect to y
    14481449            (3*t^2 + O(t^3))*x^2*y^2
    14491450            sage: f._derivative(t)   # with respect to t (recurses into base ring)
    class MPolynomial_polydict(Polynomial_si 
    14581459            ValueError: must specify which variable to differentiate with respect to
    14591460        """
    14601461        if var is None:
    1461             raise ValueError, "must specify which variable to differentiate with respect to"
     1462            raise ValueError("must specify which variable to differentiate with respect to")
    14621463
    14631464        gens = list(self.parent().gens())
    14641465
    class MPolynomial_polydict(Polynomial_si 
    14811482        d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True)
    14821483        return MPolynomial_polydict(self.parent(), d)
    14831484
     1485    def integral(self, var=None):
     1486        r"""
     1487        Integrates ``self`` with respect to variable ``var``.
     1488
     1489        .. NOTE::
     1490
     1491            The integral is always chosen so the constant term is 0.
     1492
     1493        If ``var`` is not one of the generators of this ring, integral(var)
     1494        is called recursively on each coefficient of this polynomial.
     1495
     1496        EXAMPLES:
     1497
     1498        On polynomials with rational coefficients::
     1499
     1500            sage: x, y = PolynomialRing(QQ, 'x, y').gens()
     1501            sage: ex = x*y + x - y
     1502            sage: it = ex.integral(x); it
     1503            1/2*x^2*y + 1/2*x^2 - x*y
     1504            sage: it.parent() == x.parent()
     1505            True
     1506
     1507        On polynomials with coefficients in power series::
     1508
     1509            sage: R.<t> = PowerSeriesRing(QQbar)
     1510            sage: S.<x, y> = PolynomialRing(R)
     1511            sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
     1512            sage: f.parent()
     1513            Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field
     1514            sage: f.integral(x)   # with respect to x
     1515            (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4
     1516            sage: f.integral(x).parent()
     1517            Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field
     1518
     1519            sage: f.integral(y)   # with respect to y
     1520            (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y
     1521            sage: f.integral(t)   # with respect to t (recurses into base ring)
     1522            (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3
     1523
     1524        TESTS::
     1525
     1526            sage: f.integral()    # can't figure out the variable
     1527            Traceback (most recent call last):
     1528            ...
     1529            ValueError: must specify which variable to integrate with respect to
     1530        """
     1531        if var is None:
     1532            raise ValueError("must specify which variable to integrate "
     1533                             "with respect to")
     1534
     1535        gens = list(self.parent().gens())
     1536
     1537        # check if var is one of the generators
     1538        try:
     1539            index = gens.index(var)
     1540        except ValueError:
     1541            # var is not a generator; do term-by-term integration recursively
     1542            # var may be, for example, a generator of the base ring
     1543            d = dict([(e, x.integral(var))
     1544                      for (e, x) in self.dict().iteritems()])
     1545            d = polydict.PolyDict(d, self.parent().base_ring()(0),
     1546                                  remove_zero=True)
     1547            return MPolynomial_polydict(self.parent(), d)
     1548
     1549        # integrate w.r.t. indicated variable
     1550        d = {}
     1551        v = polydict.ETuple({index:1}, len(gens))
     1552        for (exp, coeff) in self.dict().iteritems():
     1553            d[exp.eadd(v)] = coeff / (1+exp[index])
     1554        d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True)
     1555        return MPolynomial_polydict(self.parent(), d)
     1556
    14841557    def factor(self, proof=True):
    14851558        r"""
    14861559        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 b cdef class MPolynomial_libsingular(sage. 
    47644764        return new_MP(self._parent,p)
    47654765
    47664766
     4767    def integral(self, MPolynomial_libsingular var):
     4768        """
     4769        Integrates this polynomial with respect to the provided
     4770        variable.
     4771
     4772        One requires that `\QQ` is contained in the ring.
     4773
     4774        INPUT:
     4775
     4776        - ``variable`` - the integral is taken with respect to variable
     4777
     4778        EXAMPLES::
     4779
     4780            sage: R.<x, y> = PolynomialRing(QQ, 2)
     4781            sage: f = 3*x^3*y^2 + 5*y^2 + 3*x + 2
     4782            sage: f.integral(x)
     4783            3/4*x^4*y^2 + 5*x*y^2 + 3/2*x^2 + 2*x
     4784            sage: f.integral(y)
     4785            x^3*y^3 + 5/3*y^3 + 3*x*y + 2*y
     4786
     4787        TESTS::
     4788
     4789            sage: z, w = polygen(QQ, 'z, w')
     4790            sage: f.integral(z)
     4791            Traceback (most recent call last):
     4792            ...
     4793            TypeError: the variable is not in the same ring as self
     4794        """
     4795        if var is None:
     4796            raise ValueError("please specify a variable")
     4797
     4798        ring = var.parent()
     4799        if ring is not self._parent:
     4800            raise TypeError("the variable is not in the same ring as self")
     4801
     4802        if not ring.has_coerce_map_from(RationalField()):
     4803            raise TypeError("the ring must contain the rational numbers")
     4804
     4805        gens = ring.gens()
     4806
     4807        try:
     4808            index = gens.index(var)
     4809        except ValueError:
     4810            raise TypeError("not a variable in the same ring as self")
     4811
     4812        d = {}
     4813        v = ETuple({index:1}, len(gens))
     4814        for (exp, coeff) in self.dict().iteritems():
     4815            d[exp.eadd(v)] = coeff / (1+exp[index])
     4816        return MPolynomial_polydict(self.parent(), d)
     4817
     4818
    47674819    def resultant(self, MPolynomial_libsingular other, variable=None):
    47684820        """
    47694821        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 b cdef class Polynomial(CommutativeAlgebra 
    23662366        coeffs = self.list()
    23672367        return self._parent([n*coeffs[n] for n from 1 <= n <= degree])
    23682368
    2369     def integral(self):
     2369    def integral(self,var=None):
    23702370        """
    23712371        Return the integral of this polynomial.
    2372        
    2373         .. note::
    2374 
    2375            The integral is always chosen so the constant term is 0.
    2376        
     2372
     2373        By default, the integration variable is the variable of the
     2374        polynomial.
     2375
     2376        Otherwise, the integration variable is the optional parameter ``var``
     2377
     2378        .. NOTE::
     2379
     2380            The integral is always chosen so the constant term is 0.
     2381
    23772382        EXAMPLES::
    2378        
     2383
    23792384            sage: R.<x> = ZZ[]
    23802385            sage: R(0).integral()
    23812386            0
    23822387            sage: f = R(2).integral(); f
    23832388            2*x
    2384        
     2389
    23852390        Note that the integral lives over the fraction field of the
    23862391        scalar coefficients::
    2387        
     2392
    23882393            sage: f.parent()
    23892394            Univariate Polynomial Ring in x over Rational Field
    23902395            sage: R(0).integral().parent()
    23912396            Univariate Polynomial Ring in x over Rational Field
    2392        
     2397
    23932398            sage: f = x^3 + x - 2
    23942399            sage: g = f.integral(); g
    23952400            1/4*x^4 + 1/2*x^2 - 2*x
    23962401            sage: g.parent()
    23972402            Univariate Polynomial Ring in x over Rational Field
    23982403
    2399         This shows that the issue at trac #7711 is resolved::
     2404        This shows that the issue at :trac:`7711` is resolved::
    24002405
    24012406            sage: P.<x,z> = PolynomialRing(GF(2147483647))
    24022407            sage: Q.<y> = PolynomialRing(P)
    cdef class Polynomial(CommutativeAlgebra 
    24342439            Univariate Polynomial Ring in x over Power Series Ring in c
    24352440            over Univariate Polynomial Ring in b over Multivariate Polynomial
    24362441            Ring in a1, a2 over Rational Field
    2437         """
     2442
     2443        Integration with respect to a variable in the base ring::
     2444
     2445            sage: R.<x> = QQ[]
     2446            sage: t = PolynomialRing(R,'t').gen()
     2447            sage: f = x*t +5*t^2
     2448            sage: f.integral(x)
     2449            5*x*t^2 + 1/2*x^2*t
     2450        """
     2451        if var is not None and var != self._parent.gen():
     2452            # call integral() recursively on coefficients
     2453            return self._parent([coeff.integral(var) for coeff in self.list()])
    24382454        cdef Py_ssize_t n, degree = self.degree()
    24392455        R = self.parent()
    24402456        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 b cdef class PowerSeries_poly(PowerSeries) 
    862862        return PowerSeries_poly(self._parent, self.__f._derivative(),
    863863                                self.prec()-1, check=False)
    864864
    865     def integral(self):
     865    def integral(self,var=None):
    866866        """
    867         The integral of this power series with 0 constant term.
     867        The integral of this power series
     868
     869        By default, the integration variable is the variable of the
     870        power series.
     871
     872        Otherwise, the integration variable is the optional parameter ``var``
     873
     874        .. NOTE::
     875
     876            The integral is always chosen so the constant term is 0.
    868877
    869878        EXAMPLES::
    870        
     879
    871880            sage: k.<w> = QQ[[]]
    872881            sage: (1+17*w+15*w^3+O(w^5)).integral()
    873             w + 17/2*w^2 + 15/4*w^4 + O(w^6)       
     882            w + 17/2*w^2 + 15/4*w^4 + O(w^6)
    874883            sage: (w^3 + 4*w^4 + O(w^7)).integral()
    875884            1/4*w^4 + 4/5*w^5 + O(w^8)
    876885            sage: (3*w^2).integral()
    877886            w^3
     887
     888        TESTS::
     889
     890            sage: t = PowerSeriesRing(QQ,'t').gen()
     891            sage: f = t + 5*t^2 + 21*t^3
     892            sage: g = f.integral() ; g
     893            1/2*t^2 + 5/3*t^3 + 21/4*t^4
     894            sage: g.parent()
     895            Power Series Ring in t over Rational Field
     896
     897            sage: R.<x> = QQ[]
     898            sage: t = PowerSeriesRing(R,'t').gen()
     899            sage: f = x*t +5*t^2
     900            sage: f.integral()
     901            1/2*x*t^2 + 5/3*t^3
     902            sage: f.integral(x)
     903            1/2*x^2*t + 5*x*t^2
    878904        """
    879         return PowerSeries_poly(self._parent, self.__f.integral(),
    880                                          self.prec()+1, check=False)
     905        return PowerSeries_poly(self._parent, self.__f.integral(var),
     906                                self.prec()+1, check=False)
    881907
    882908    def reversion(self, precision=None):
    883909        """