Power Series Methods#
The class PowerSeries_poly
provides additional methods for univariate power series.
- class sage.rings.power_series_poly.BaseRingFloorDivAction[source]#
Bases:
Action
The floor division action of the base ring on a formal power series.
- class sage.rings.power_series_poly.PowerSeries_poly[source]#
Bases:
PowerSeries
EXAMPLES:
sage: R.<q> = PowerSeriesRing(CC); R # needs sage.rings.real_mpfr Power Series Ring in q over Complex Field with 53 bits of precision sage: loads(q.dumps()) == q # needs sage.rings.real_mpfr True sage: R.<t> = QQ[[]] sage: f = 3 - t^3 + O(t^5) sage: a = f^3; a 27 - 27*t^3 + O(t^5) sage: b = f^-3; b 1/27 + 1/27*t^3 + O(t^5) sage: a*b 1 + O(t^5)
>>> from sage.all import * >>> R = PowerSeriesRing(CC, names=('q',)); (q,) = R._first_ngens(1); R # needs sage.rings.real_mpfr Power Series Ring in q over Complex Field with 53 bits of precision >>> loads(q.dumps()) == q # needs sage.rings.real_mpfr True >>> R = QQ[['t']]; (t,) = R._first_ngens(1) >>> f = Integer(3) - t**Integer(3) + O(t**Integer(5)) >>> a = f**Integer(3); a 27 - 27*t^3 + O(t^5) >>> b = f**-Integer(3); b 1/27 + 1/27*t^3 + O(t^5) >>> a*b 1 + O(t^5)
Check that Issue #22216 is fixed:
sage: R.<T> = PowerSeriesRing(QQ) sage: R(pari('1 + O(T)')) # needs sage.libs.pari 1 + O(T) sage: R(pari('1/T + O(T)')) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: series has negative valuation
>>> from sage.all import * >>> R = PowerSeriesRing(QQ, names=('T',)); (T,) = R._first_ngens(1) >>> R(pari('1 + O(T)')) # needs sage.libs.pari 1 + O(T) >>> R(pari('1/T + O(T)')) # needs sage.libs.pari Traceback (most recent call last): ... ValueError: series has negative valuation
- degree()[source]#
Return the degree of the underlying polynomial of
self
.That is, if
self
is of the form \(f(x) + O(x^n)\), we return the degree of \(f(x)\). Note that if \(f(x)\) is \(0\), we return \(-1\), just as with polynomials.EXAMPLES:
sage: R.<t> = ZZ[[]] sage: (5 + t^3 + O(t^4)).degree() 3 sage: (5 + O(t^4)).degree() 0 sage: O(t^4).degree() -1
>>> from sage.all import * >>> R = ZZ[['t']]; (t,) = R._first_ngens(1) >>> (Integer(5) + t**Integer(3) + O(t**Integer(4))).degree() 3 >>> (Integer(5) + O(t**Integer(4))).degree() 0 >>> O(t**Integer(4)).degree() -1
- dict()[source]#
Return a dictionary of coefficients for
self
.This is simply a dict for the underlying polynomial, so need not have keys corresponding to every number smaller than
self.prec()
.EXAMPLES:
sage: R.<t> = ZZ[[]] sage: f = 1 + t^10 + O(t^12) sage: f.dict() {0: 1, 10: 1}
>>> from sage.all import * >>> R = ZZ[['t']]; (t,) = R._first_ngens(1) >>> f = Integer(1) + t**Integer(10) + O(t**Integer(12)) >>> f.dict() {0: 1, 10: 1}
- integral(var=None)[source]#
Return 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.<w> = QQ[[]] sage: (1+17*w+15*w^3+O(w^5)).integral() 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
>>> from sage.all import * >>> k = QQ[['w']]; (w,) = k._first_ngens(1) >>> (Integer(1)+Integer(17)*w+Integer(15)*w**Integer(3)+O(w**Integer(5))).integral() w + 17/2*w^2 + 15/4*w^4 + O(w^6) >>> (w**Integer(3) + Integer(4)*w**Integer(4) + O(w**Integer(7))).integral() 1/4*w^4 + 4/5*w^5 + O(w^8) >>> (Integer(3)*w**Integer(2)).integral() w^3
- list()[source]#
Return the list of known coefficients for
self
.This is just the list of coefficients of the underlying polynomial, so in particular, need not have length equal to
self.prec()
.EXAMPLES:
sage: R.<t> = ZZ[[]] sage: f = 1 - 5*t^3 + t^5 + O(t^7) sage: f.list() [1, 0, 0, -5, 0, 1]
>>> from sage.all import * >>> R = ZZ[['t']]; (t,) = R._first_ngens(1) >>> f = Integer(1) - Integer(5)*t**Integer(3) + t**Integer(5) + O(t**Integer(7)) >>> f.list() [1, 0, 0, -5, 0, 1]
- pade(m, n)[source]#
Return the Padé approximant of
self
of index \((m, n)\).The Padé approximant of index \((m, n)\) of a formal power series \(f\) is the quotient \(Q/P\) of two polynomials \(Q\) and \(P\) such that \(\deg(Q)\leq m\), \(\deg(P)\leq n\) and
\[f(z) - Q(z)/P(z) = O(z^{m+n+1}).\]The formal power series \(f\) must be known up to order \(n + m\).
See Wikipedia article Padé_approximant
INPUT:
m
,n
– integers, describing the degrees of the polynomials
OUTPUT:
a ratio of two polynomials
ALGORITHM:
This method uses the formula as a quotient of two determinants.
See also
EXAMPLES:
sage: z = PowerSeriesRing(QQ, 'z').gen() sage: exp(z).pade(4, 0) 1/24*z^4 + 1/6*z^3 + 1/2*z^2 + z + 1 sage: exp(z).pade(1, 1) (-z - 2)/(z - 2) sage: exp(z).pade(3, 3) (-z^3 - 12*z^2 - 60*z - 120)/(z^3 - 12*z^2 + 60*z - 120) sage: log(1-z).pade(4, 4) (25/6*z^4 - 130/3*z^3 + 105*z^2 - 70*z)/(z^4 - 20*z^3 + 90*z^2 - 140*z + 70) sage: sqrt(1+z).pade(3, 2) (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) sage: exp(2*z).pade(3, 3) (-z^3 - 6*z^2 - 15*z - 15)/(z^3 - 6*z^2 + 15*z - 15)
>>> from sage.all import * >>> z = PowerSeriesRing(QQ, 'z').gen() >>> exp(z).pade(Integer(4), Integer(0)) 1/24*z^4 + 1/6*z^3 + 1/2*z^2 + z + 1 >>> exp(z).pade(Integer(1), Integer(1)) (-z - 2)/(z - 2) >>> exp(z).pade(Integer(3), Integer(3)) (-z^3 - 12*z^2 - 60*z - 120)/(z^3 - 12*z^2 + 60*z - 120) >>> log(Integer(1)-z).pade(Integer(4), Integer(4)) (25/6*z^4 - 130/3*z^3 + 105*z^2 - 70*z)/(z^4 - 20*z^3 + 90*z^2 - 140*z + 70) >>> sqrt(Integer(1)+z).pade(Integer(3), Integer(2)) (1/6*z^3 + 3*z^2 + 8*z + 16/3)/(z^2 + 16/3*z + 16/3) >>> exp(Integer(2)*z).pade(Integer(3), Integer(3)) (-z^3 - 6*z^2 - 15*z - 15)/(z^3 - 6*z^2 + 15*z - 15)
- polynomial()[source]#
Return the underlying polynomial of
self
.EXAMPLES:
sage: R.<t> = GF(7)[[]] sage: f = 3 - t^3 + O(t^5) sage: f.polynomial() 6*t^3 + 3
>>> from sage.all import * >>> R = GF(Integer(7))[['t']]; (t,) = R._first_ngens(1) >>> f = Integer(3) - t**Integer(3) + O(t**Integer(5)) >>> f.polynomial() 6*t^3 + 3
- reverse(precision=None)[source]#
Return the reverse of \(f\), i.e., the series \(g\) such that \(g(f(x)) = x\).
Given an optional argument
precision
, return the reverse with given precision (note that the reverse can have precision at mostf.prec()
). If \(f\) has infinite precision, and the argumentprecision
is not given, then the precision of the reverse defaults to the default precision off.parent()
.Note that this is only possible if the valuation of
self
is exactly 1.ALGORITHM:
We first attempt to pass the computation to pari; if this fails, we use Lagrange inversion. Using
sage: set_verbose(1)
will print a message if passing to pari fails.If the base ring has positive characteristic, then we attempt to lift to a characteristic zero ring and perform the reverse there. If this fails, an error is raised.
EXAMPLES:
sage: R.<x> = PowerSeriesRing(QQ) sage: f = 2*x + 3*x^2 - x^4 + O(x^5) sage: g = f.reverse() sage: g 1/2*x - 3/8*x^2 + 9/16*x^3 - 131/128*x^4 + O(x^5) sage: f(g) x + O(x^5) sage: g(f) x + O(x^5) sage: A.<t> = PowerSeriesRing(ZZ) sage: a = t - t^2 - 2*t^4 + t^5 + O(t^6) sage: b = a.reverse(); b t + t^2 + 2*t^3 + 7*t^4 + 25*t^5 + O(t^6) sage: a(b) t + O(t^6) sage: b(a) t + O(t^6) sage: B.<b,c> = PolynomialRing(ZZ) sage: A.<t> = PowerSeriesRing(B) sage: f = t + b*t^2 + c*t^3 + O(t^4) sage: g = f.reverse(); g t - b*t^2 + (2*b^2 - c)*t^3 + O(t^4) sage: f(g) t + O(t^4) sage: g(f) t + O(t^4) sage: A.<t> = PowerSeriesRing(ZZ) sage: B.<s> = A[[]] sage: f = (1 - 3*t + 4*t^3 + O(t^4))*s + (2 + t + t^2 + O(t^3))*s^2 + O(s^3) sage: from sage.misc.verbose import set_verbose sage: set_verbose(1) sage: g = f.reverse(); g verbose 1 (<module>) passing to pari failed; trying Lagrange inversion (1 + 3*t + 9*t^2 + 23*t^3 + O(t^4))*s + (-2 - 19*t - 118*t^2 + O(t^3))*s^2 + O(s^3) sage: set_verbose(0) sage: f(g) == g(f) == s True
>>> from sage.all import * >>> R = PowerSeriesRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = Integer(2)*x + Integer(3)*x**Integer(2) - x**Integer(4) + O(x**Integer(5)) >>> g = f.reverse() >>> g 1/2*x - 3/8*x^2 + 9/16*x^3 - 131/128*x^4 + O(x^5) >>> f(g) x + O(x^5) >>> g(f) x + O(x^5) >>> A = PowerSeriesRing(ZZ, names=('t',)); (t,) = A._first_ngens(1) >>> a = t - t**Integer(2) - Integer(2)*t**Integer(4) + t**Integer(5) + O(t**Integer(6)) >>> b = a.reverse(); b t + t^2 + 2*t^3 + 7*t^4 + 25*t^5 + O(t^6) >>> a(b) t + O(t^6) >>> b(a) t + O(t^6) >>> B = PolynomialRing(ZZ, names=('b', 'c',)); (b, c,) = B._first_ngens(2) >>> A = PowerSeriesRing(B, names=('t',)); (t,) = A._first_ngens(1) >>> f = t + b*t**Integer(2) + c*t**Integer(3) + O(t**Integer(4)) >>> g = f.reverse(); g t - b*t^2 + (2*b^2 - c)*t^3 + O(t^4) >>> f(g) t + O(t^4) >>> g(f) t + O(t^4) >>> A = PowerSeriesRing(ZZ, names=('t',)); (t,) = A._first_ngens(1) >>> B = A[['s']]; (s,) = B._first_ngens(1) >>> f = (Integer(1) - Integer(3)*t + Integer(4)*t**Integer(3) + O(t**Integer(4)))*s + (Integer(2) + t + t**Integer(2) + O(t**Integer(3)))*s**Integer(2) + O(s**Integer(3)) >>> from sage.misc.verbose import set_verbose >>> set_verbose(Integer(1)) >>> g = f.reverse(); g verbose 1 (<module>) passing to pari failed; trying Lagrange inversion (1 + 3*t + 9*t^2 + 23*t^3 + O(t^4))*s + (-2 - 19*t - 118*t^2 + O(t^3))*s^2 + O(s^3) >>> set_verbose(Integer(0)) >>> f(g) == g(f) == s True
If the leading coefficient is not a unit, we pass to its fraction field if possible:
sage: A.<t> = PowerSeriesRing(ZZ) sage: a = 2*t - 4*t^2 + t^4 - t^5 + O(t^6) sage: a.reverse() 1/2*t + 1/2*t^2 + t^3 + 79/32*t^4 + 437/64*t^5 + O(t^6) sage: B.<b> = PolynomialRing(ZZ) sage: A.<t> = PowerSeriesRing(B) sage: f = 2*b*t + b*t^2 + 3*b^2*t^3 + O(t^4) sage: g = f.reverse(); g 1/(2*b)*t - 1/(8*b^2)*t^2 + ((-3*b + 1)/(16*b^3))*t^3 + O(t^4) sage: f(g) t + O(t^4) sage: g(f) t + O(t^4)
>>> from sage.all import * >>> A = PowerSeriesRing(ZZ, names=('t',)); (t,) = A._first_ngens(1) >>> a = Integer(2)*t - Integer(4)*t**Integer(2) + t**Integer(4) - t**Integer(5) + O(t**Integer(6)) >>> a.reverse() 1/2*t + 1/2*t^2 + t^3 + 79/32*t^4 + 437/64*t^5 + O(t^6) >>> B = PolynomialRing(ZZ, names=('b',)); (b,) = B._first_ngens(1) >>> A = PowerSeriesRing(B, names=('t',)); (t,) = A._first_ngens(1) >>> f = Integer(2)*b*t + b*t**Integer(2) + Integer(3)*b**Integer(2)*t**Integer(3) + O(t**Integer(4)) >>> g = f.reverse(); g 1/(2*b)*t - 1/(8*b^2)*t^2 + ((-3*b + 1)/(16*b^3))*t^3 + O(t^4) >>> f(g) t + O(t^4) >>> g(f) t + O(t^4)
We can handle some base rings of positive characteristic:
sage: A8.<t> = PowerSeriesRing(Zmod(8)) sage: a = t - 15*t^2 - 2*t^4 + t^5 + O(t^6) sage: b = a.reverse(); b t + 7*t^2 + 2*t^3 + 5*t^4 + t^5 + O(t^6) sage: a(b) t + O(t^6) sage: b(a) t + O(t^6)
>>> from sage.all import * >>> A8 = PowerSeriesRing(Zmod(Integer(8)), names=('t',)); (t,) = A8._first_ngens(1) >>> a = t - Integer(15)*t**Integer(2) - Integer(2)*t**Integer(4) + t**Integer(5) + O(t**Integer(6)) >>> b = a.reverse(); b t + 7*t^2 + 2*t^3 + 5*t^4 + t^5 + O(t^6) >>> a(b) t + O(t^6) >>> b(a) t + O(t^6)
The optional argument
precision
sets the precision of the output:sage: R.<x> = PowerSeriesRing(QQ) sage: f = 2*x + 3*x^2 - 7*x^3 + x^4 + O(x^5) sage: g = f.reverse(precision=3); g 1/2*x - 3/8*x^2 + O(x^3) sage: f(g) x + O(x^3) sage: g(f) x + O(x^3)
>>> from sage.all import * >>> R = PowerSeriesRing(QQ, names=('x',)); (x,) = R._first_ngens(1) >>> f = Integer(2)*x + Integer(3)*x**Integer(2) - Integer(7)*x**Integer(3) + x**Integer(4) + O(x**Integer(5)) >>> g = f.reverse(precision=Integer(3)); g 1/2*x - 3/8*x^2 + O(x^3) >>> f(g) x + O(x^3) >>> g(f) x + O(x^3)
If the input series has infinite precision, the precision of the output is automatically set to the default precision of the parent ring:
sage: R.<x> = PowerSeriesRing(QQ, default_prec=20) sage: (x - x^2).reverse() # get some Catalan numbers x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + 477638700*x^19 + O(x^20) sage: (x - x^2).reverse(precision=3) x + x^2 + O(x^3)
>>> from sage.all import * >>> R = PowerSeriesRing(QQ, default_prec=Integer(20), names=('x',)); (x,) = R._first_ngens(1) >>> (x - x**Integer(2)).reverse() # get some Catalan numbers x + x^2 + 2*x^3 + 5*x^4 + 14*x^5 + 42*x^6 + 132*x^7 + 429*x^8 + 1430*x^9 + 4862*x^10 + 16796*x^11 + 58786*x^12 + 208012*x^13 + 742900*x^14 + 2674440*x^15 + 9694845*x^16 + 35357670*x^17 + 129644790*x^18 + 477638700*x^19 + O(x^20) >>> (x - x**Integer(2)).reverse(precision=Integer(3)) x + x^2 + O(x^3)
- truncate(prec='infinity')[source]#
The polynomial obtained from power series by truncation at precision
prec
.EXAMPLES:
sage: R.<I> = GF(2)[[]] sage: f = 1/(1+I+O(I^8)); f 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) sage: f.truncate(5) I^4 + I^3 + I^2 + I + 1
>>> from sage.all import * >>> R = GF(Integer(2))[['I']]; (I,) = R._first_ngens(1) >>> f = Integer(1)/(Integer(1)+I+O(I**Integer(8))); f 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) >>> f.truncate(Integer(5)) I^4 + I^3 + I^2 + I + 1
- truncate_powerseries(prec)[source]#
Given input
prec
= \(n\), returns the power series of degree \(< n\) which is equivalent to self modulo \(x^n\).EXAMPLES:
sage: R.<I> = GF(2)[[]] sage: f = 1/(1+I+O(I^8)); f 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) sage: f.truncate_powerseries(5) 1 + I + I^2 + I^3 + I^4 + O(I^5)
>>> from sage.all import * >>> R = GF(Integer(2))[['I']]; (I,) = R._first_ngens(1) >>> f = Integer(1)/(Integer(1)+I+O(I**Integer(8))); f 1 + I + I^2 + I^3 + I^4 + I^5 + I^6 + I^7 + O(I^8) >>> f.truncate_powerseries(Integer(5)) 1 + I + I^2 + I^3 + I^4 + O(I^5)
- valuation()[source]#
Return the valuation of
self
.EXAMPLES:
sage: R.<t> = QQ[[]] sage: (5 - t^8 + O(t^11)).valuation() 0 sage: (-t^8 + O(t^11)).valuation() 8 sage: O(t^7).valuation() 7 sage: R(0).valuation() +Infinity
>>> from sage.all import * >>> R = QQ[['t']]; (t,) = R._first_ngens(1) >>> (Integer(5) - t**Integer(8) + O(t**Integer(11))).valuation() 0 >>> (-t**Integer(8) + O(t**Integer(11))).valuation() 8 >>> O(t**Integer(7)).valuation() 7 >>> R(Integer(0)).valuation() +Infinity
- sage.rings.power_series_poly.make_powerseries_poly_v0(parent, f, prec, is_gen)[source]#
Return the power series specified by
f
,prec
, andis_gen
.This function exists for the purposes of pickling. Do not delete this function – if you change the internal representation, instead make a new function and make sure that both kinds of objects correctly unpickle as the new type.
EXAMPLES:
sage: R.<t> = QQ[[]] sage: sage.rings.power_series_poly.make_powerseries_poly_v0(R, t, infinity, True) t
>>> from sage.all import * >>> R = QQ[['t']]; (t,) = R._first_ngens(1) >>> sage.rings.power_series_poly.make_powerseries_poly_v0(R, t, infinity, True) t