Ticket #14334: trac_14334_integration_multipoly-fc.patch
File trac_14334_integration_multipoly-fc.patch, 13.3 KB (added by , 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 b def symbolic_sum(expression, *args, **kw 658 658 from sage.symbolic.ring import SR 659 659 return SR(expression).sum(*args, **kwds) 660 660 661 661 662 def integral(x, *args, **kwds): 662 663 """ 663 664 Returns an indefinite or definite integral of an object x. 664 665 665 First call x.integra te() and if that fails make an object and666 First call x.integral() and if that fails make an object and 666 667 integrate it using Maxima, maple, etc, as specified by algorithm. 667 668 668 669 For symbolic expression calls 669 ``sage.calculus.calculus.integral`` - see this function for670 :func:`sage.calculus.calculus.integral` - see this function for 670 671 available options. 671 672 672 673 EXAMPLES:: … … def integral(x, *args, **kwds): 751 752 752 753 integrate = integral 753 754 755 754 756 def integral_closure(x): 755 757 """ 756 758 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 1423 1423 Q, _ = self.quo_rem(right) 1424 1424 return Q 1425 1425 1426 1427 1426 def _derivative(self, var=None): 1428 1427 r""" 1429 Differentiates self with respect to variable var.1430 1431 If varis 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) 1432 1431 is called recursively on each coefficient of this polynomial. 1433 1434 .. seealso::1435 1432 1436 :meth:`derivative` 1437 1433 .. SEEALSO:: 1434 1435 :meth:`derivative` 1436 1438 1437 EXAMPLES:: 1439 1438 1440 1439 sage: R.<t> = PowerSeriesRing(QQbar) 1441 1440 sage: S.<x, y> = PolynomialRing(R) 1442 1441 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 1445 1444 sage: f._derivative(x) # with respect to x 1446 1445 (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 1447 1448 sage: f._derivative(y) # with respect to y 1448 1449 (3*t^2 + O(t^3))*x^2*y^2 1449 1450 sage: f._derivative(t) # with respect to t (recurses into base ring) … … class MPolynomial_polydict(Polynomial_si 1458 1459 ValueError: must specify which variable to differentiate with respect to 1459 1460 """ 1460 1461 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") 1462 1463 1463 1464 gens = list(self.parent().gens()) 1464 1465 … … class MPolynomial_polydict(Polynomial_si 1481 1482 d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) 1482 1483 return MPolynomial_polydict(self.parent(), d) 1483 1484 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 1484 1557 def factor(self, proof=True): 1485 1558 r""" 1486 1559 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. 4764 4764 return new_MP(self._parent,p) 4765 4765 4766 4766 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 4767 4819 def resultant(self, MPolynomial_libsingular other, variable=None): 4768 4820 """ 4769 4821 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 2366 2366 coeffs = self.list() 2367 2367 return self._parent([n*coeffs[n] for n from 1 <= n <= degree]) 2368 2368 2369 def integral(self ):2369 def integral(self,var=None): 2370 2370 """ 2371 2371 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 2377 2382 EXAMPLES:: 2378 2383 2379 2384 sage: R.<x> = ZZ[] 2380 2385 sage: R(0).integral() 2381 2386 0 2382 2387 sage: f = R(2).integral(); f 2383 2388 2*x 2384 2389 2385 2390 Note that the integral lives over the fraction field of the 2386 2391 scalar coefficients:: 2387 2392 2388 2393 sage: f.parent() 2389 2394 Univariate Polynomial Ring in x over Rational Field 2390 2395 sage: R(0).integral().parent() 2391 2396 Univariate Polynomial Ring in x over Rational Field 2392 2397 2393 2398 sage: f = x^3 + x - 2 2394 2399 sage: g = f.integral(); g 2395 2400 1/4*x^4 + 1/2*x^2 - 2*x 2396 2401 sage: g.parent() 2397 2402 Univariate Polynomial Ring in x over Rational Field 2398 2403 2399 This shows that the issue at trac #7711is resolved::2404 This shows that the issue at :trac:`7711` is resolved:: 2400 2405 2401 2406 sage: P.<x,z> = PolynomialRing(GF(2147483647)) 2402 2407 sage: Q.<y> = PolynomialRing(P) … … cdef class Polynomial(CommutativeAlgebra 2434 2439 Univariate Polynomial Ring in x over Power Series Ring in c 2435 2440 over Univariate Polynomial Ring in b over Multivariate Polynomial 2436 2441 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()]) 2438 2454 cdef Py_ssize_t n, degree = self.degree() 2439 2455 R = self.parent() 2440 2456 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) 862 862 return PowerSeries_poly(self._parent, self.__f._derivative(), 863 863 self.prec()-1, check=False) 864 864 865 def integral(self ):865 def integral(self,var=None): 866 866 """ 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. 868 877 869 878 EXAMPLES:: 870 879 871 880 sage: k.<w> = QQ[[]] 872 881 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) 874 883 sage: (w^3 + 4*w^4 + O(w^7)).integral() 875 884 1/4*w^4 + 4/5*w^5 + O(w^8) 876 885 sage: (3*w^2).integral() 877 886 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 878 904 """ 879 return PowerSeries_poly(self._parent, self.__f.integral( ),880 905 return PowerSeries_poly(self._parent, self.__f.integral(var), 906 self.prec()+1, check=False) 881 907 882 908 def reversion(self, precision=None): 883 909 """