Lazy Series#
Coefficients of lazy series are computed on demand. They have infinite precision, although equality can only be decided in special cases.
AUTHORS:
Kwankyu Lee (2019-02-24): initial version
Tejasvi Chebrolu, Martin Rubey, Travis Scrimshaw (2021-08): refactored and expanded functionality
EXAMPLES:
Laurent series over the integer ring are particularly useful as generating functions for sequences arising in combinatorics.
sage: L.<z> = LazyLaurentSeriesRing(ZZ)
>>> from sage.all import *
>>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1)
The generating function of the Fibonacci sequence is:
sage: f = 1 / (1 - z - z^2)
sage: f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
>>> from sage.all import *
>>> f = Integer(1) / (Integer(1) - z - z**Integer(2))
>>> f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
In principle, we can now compute any coefficient of \(f\):
sage: f.coefficient(100)
573147844013817084101
>>> from sage.all import *
>>> f.coefficient(Integer(100))
573147844013817084101
Which coefficients are actually computed depends on the type of implementation. For the sparse implementation, only the coefficients which are needed are computed.
sage: s = L(lambda n: n, valuation=0); s
z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7)
sage: s.coefficient(10)
10
sage: s._coeff_stream._cache
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 10: 10}
>>> from sage.all import *
>>> s = L(lambda n: n, valuation=Integer(0)); s
z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7)
>>> s.coefficient(Integer(10))
10
>>> s._coeff_stream._cache
{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 10: 10}
Using the dense implementation, all coefficients up to the required coefficient are computed.
sage: L.<x> = LazyLaurentSeriesRing(ZZ, sparse=False)
sage: s = L(lambda n: n, valuation=0); s
x + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5 + 6*x^6 + O(x^7)
sage: s.coefficient(10)
10
sage: s._coeff_stream._cache
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> from sage.all import *
>>> L = LazyLaurentSeriesRing(ZZ, sparse=False, names=('x',)); (x,) = L._first_ngens(1)
>>> s = L(lambda n: n, valuation=Integer(0)); s
x + 2*x^2 + 3*x^3 + 4*x^4 + 5*x^5 + 6*x^6 + O(x^7)
>>> s.coefficient(Integer(10))
10
>>> s._coeff_stream._cache
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
We can do arithmetic with lazy power series:
sage: f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
sage: f^-1
1 - z - z^2 + O(z^7)
sage: f + f^-1
2 + z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
sage: g = (f + f^-1)*(f - f^-1); g
4*z + 6*z^2 + 8*z^3 + 19*z^4 + 38*z^5 + 71*z^6 + O(z^7)
>>> from sage.all import *
>>> f
1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
>>> f**-Integer(1)
1 - z - z^2 + O(z^7)
>>> f + f**-Integer(1)
2 + z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7)
>>> g = (f + f**-Integer(1))*(f - f**-Integer(1)); g
4*z + 6*z^2 + 8*z^3 + 19*z^4 + 38*z^5 + 71*z^6 + O(z^7)
We call lazy power series whose coefficients are known to be eventually constant ‘exact’. In some cases, computations with such series are much faster. Moreover, these are the series where equality can be decided. For example:
sage: L.<z> = LazyPowerSeriesRing(ZZ)
sage: f = 1 + 2*z^2 / (1 - z)
sage: f - 2 / (1 - z) + 1 + 2*z
0
>>> from sage.all import *
>>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1)
>>> f = Integer(1) + Integer(2)*z**Integer(2) / (Integer(1) - z)
>>> f - Integer(2) / (Integer(1) - z) + Integer(1) + Integer(2)*z
0
However, multivariate Taylor series are actually represented as streams of multivariate polynomials. Therefore, the only exact series in this case are polynomials:
sage: L.<x,y> = LazyPowerSeriesRing(ZZ)
sage: 1 / (1-x)
1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + O(x,y)^7
>>> from sage.all import *
>>> L = LazyPowerSeriesRing(ZZ, names=('x', 'y',)); (x, y,) = L._first_ngens(2)
>>> Integer(1) / (Integer(1)-x)
1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + O(x,y)^7
A similar statement is true for lazy symmetric functions:
sage: h = SymmetricFunctions(QQ).h() # needs sage.combinat
sage: L = LazySymmetricFunctions(h) # needs sage.combinat
sage: 1 / (1-L(h[1])) # needs sage.combinat
h[] + h[1] + (h[1,1]) + (h[1,1,1]) + (h[1,1,1,1]) + (h[1,1,1,1,1]) + (h[1,1,1,1,1,1]) + O^7
>>> from sage.all import *
>>> h = SymmetricFunctions(QQ).h() # needs sage.combinat
>>> L = LazySymmetricFunctions(h) # needs sage.combinat
>>> Integer(1) / (Integer(1)-L(h[Integer(1)])) # needs sage.combinat
h[] + h[1] + (h[1,1]) + (h[1,1,1]) + (h[1,1,1,1]) + (h[1,1,1,1,1]) + (h[1,1,1,1,1,1]) + O^7
We can change the base ring:
sage: h = g.change_ring(QQ)
sage: h.parent() # needs sage.combinat
Lazy Laurent Series Ring in z over Rational Field
sage: h # needs sage.combinat
4*z + 6*z^2 + 8*z^3 + 19*z^4 + 38*z^5 + 71*z^6 + 130*z^7 + O(z^8)
sage: hinv = h^-1; hinv # needs sage.combinat
1/4*z^-1 - 3/8 + 1/16*z - 17/32*z^2 + 5/64*z^3 - 29/128*z^4 + 165/256*z^5 + O(z^6)
sage: hinv.valuation() # needs sage.combinat
-1
>>> from sage.all import *
>>> h = g.change_ring(QQ)
>>> h.parent() # needs sage.combinat
Lazy Laurent Series Ring in z over Rational Field
>>> h # needs sage.combinat
4*z + 6*z^2 + 8*z^3 + 19*z^4 + 38*z^5 + 71*z^6 + 130*z^7 + O(z^8)
>>> hinv = h**-Integer(1); hinv # needs sage.combinat
1/4*z^-1 - 3/8 + 1/16*z - 17/32*z^2 + 5/64*z^3 - 29/128*z^4 + 165/256*z^5 + O(z^6)
>>> hinv.valuation() # needs sage.combinat
-1
- class sage.rings.lazy_series.LazyCauchyProductSeries(parent, coeff_stream)[source]#
Bases:
LazyModuleElement
A class for series where multiplication is the Cauchy product.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = 1 / (1 - z) sage: f 1 + z + z^2 + O(z^3) sage: f * (1 - z) 1 sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=True) sage: f = 1 / (1 - z) sage: f 1 + z + z^2 + O(z^3)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) - z) >>> f 1 + z + z^2 + O(z^3) >>> f * (Integer(1) - z) 1 >>> L = LazyLaurentSeriesRing(ZZ, sparse=True, names=('z',)); (z,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) - z) >>> f 1 + z + z^2 + O(z^3)
- exp()[source]#
Return the exponential series of
self
.We use the identity
\[\exp(s) = 1 + \int s' \exp(s).\]EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: exp(z) 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 + 1/120*z^5 + 1/720*z^6 + O(z^7) sage: exp(z + z^2) 1 + z + 3/2*z^2 + 7/6*z^3 + 25/24*z^4 + 27/40*z^5 + 331/720*z^6 + O(z^7) sage: exp(0) # needs sage.symbolic 1 sage: exp(1 + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: exp(x+y)[4].factor() (1/24) * (x + y)^4 sage: exp(x/(1-y)).polynomial(3) 1/6*x^3 + x^2*y + x*y^2 + 1/2*x^2 + x*y + x + 1
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> exp(z) 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 + 1/120*z^5 + 1/720*z^6 + O(z^7) >>> exp(z + z**Integer(2)) 1 + z + 3/2*z^2 + 7/6*z^3 + 25/24*z^4 + 27/40*z^5 + 331/720*z^6 + O(z^7) >>> exp(Integer(0)) # needs sage.symbolic 1 >>> exp(Integer(1) + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> exp(x+y)[Integer(4)].factor() (1/24) * (x + y)^4 >>> exp(x/(Integer(1)-y)).polynomial(Integer(3)) 1/6*x^3 + x^2*y + x*y^2 + 1/2*x^2 + x*y + x + 1
- log()[source]#
Return the series for the natural logarithm of
self
.We use the identity
\[\log(s) = \int s' / s.\]EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: log(1/(1-z)) z + 1/2*z^2 + 1/3*z^3 + 1/4*z^4 + 1/5*z^5 + 1/6*z^6 + 1/7*z^7 + O(z^8) sage: L.<x, y> = LazyPowerSeriesRing(QQ) sage: log((1 + x/(1-y))).polynomial(3) 1/3*x^3 - x^2*y + x*y^2 - 1/2*x^2 + x*y + x
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> log(Integer(1)/(Integer(1)-z)) z + 1/2*z^2 + 1/3*z^3 + 1/4*z^4 + 1/5*z^5 + 1/6*z^6 + 1/7*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> log((Integer(1) + x/(Integer(1)-y))).polynomial(Integer(3)) 1/3*x^3 - x^2*y + x*y^2 - 1/2*x^2 + x*y + x
- valuation()[source]#
Return the valuation of
self
.This method determines the valuation of the series by looking for a nonzero coefficient. Hence if the series happens to be zero, then it may run forever.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: s = 1/(1 - z) - 1/(1 - 2*z) sage: s.valuation() 1 sage: t = z - z sage: t.valuation() +Infinity sage: M = L(lambda n: n^2, 0) sage: M.valuation() 1 sage: (M - M).valuation() +Infinity
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> s = Integer(1)/(Integer(1) - z) - Integer(1)/(Integer(1) - Integer(2)*z) >>> s.valuation() 1 >>> t = z - z >>> t.valuation() +Infinity >>> M = L(lambda n: n**Integer(2), Integer(0)) >>> M.valuation() 1 >>> (M - M).valuation() +Infinity
- class sage.rings.lazy_series.LazyCompletionGradedAlgebraElement(parent, coeff_stream)[source]#
Bases:
LazyCauchyProductSeries
An element of a completion of a graded algebra that is computed lazily.
- class sage.rings.lazy_series.LazyDirichletSeries(parent, coeff_stream)[source]#
Bases:
LazyModuleElement
A Dirichlet series where the coefficients are computed lazily.
EXAMPLES:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: f = L(constant=1)^2 sage: f # needs sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) sage: f.coefficient(100) == number_of_divisors(100) # needs sage.libs.pari True
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> f = L(constant=Integer(1))**Integer(2) >>> f # needs sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) >>> f.coefficient(Integer(100)) == number_of_divisors(Integer(100)) # needs sage.libs.pari True
Lazy Dirichlet series is picklable:
sage: g = loads(dumps(f)) sage: g # needs sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) sage: g == f True
>>> from sage.all import * >>> g = loads(dumps(f)) >>> g # needs sage.symbolic 1 + 2/2^z + 2/3^z + 3/4^z + 2/5^z + 4/6^z + 2/7^z + O(1/(8^z)) >>> g == f True
- is_unit()[source]#
Return whether this element is a unit in the ring.
EXAMPLES:
sage: D = LazyDirichletSeriesRing(ZZ, "s") sage: D([0, 2]).is_unit() False sage: D([-1, 2]).is_unit() True sage: D([3, 2]).is_unit() False sage: D = LazyDirichletSeriesRing(QQ, "s") sage: D([3, 2]).is_unit() True
>>> from sage.all import * >>> D = LazyDirichletSeriesRing(ZZ, "s") >>> D([Integer(0), Integer(2)]).is_unit() False >>> D([-Integer(1), Integer(2)]).is_unit() True >>> D([Integer(3), Integer(2)]).is_unit() False >>> D = LazyDirichletSeriesRing(QQ, "s") >>> D([Integer(3), Integer(2)]).is_unit() True
- valuation()[source]#
Return the valuation of
self
.This method determines the valuation of the series by looking for a nonzero coefficient. Hence if the series happens to be zero, then it may run forever.
EXAMPLES:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: mu = L(moebius); mu.valuation() # needs sage.libs.pari 0 sage: (mu - mu).valuation() # needs sage.libs.pari +Infinity sage: g = L(constant=1, valuation=2) sage: g.valuation() # needs sage.symbolic log(2) sage: (g*g).valuation() # needs sage.symbolic 2*log(2)
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> mu = L(moebius); mu.valuation() # needs sage.libs.pari 0 >>> (mu - mu).valuation() # needs sage.libs.pari +Infinity >>> g = L(constant=Integer(1), valuation=Integer(2)) >>> g.valuation() # needs sage.symbolic log(2) >>> (g*g).valuation() # needs sage.symbolic 2*log(2)
- class sage.rings.lazy_series.LazyLaurentSeries(parent, coeff_stream)[source]#
Bases:
LazyCauchyProductSeries
A Laurent series where the coefficients are computed lazily.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1)
We can build a series from a function and specify if the series eventually takes a constant value:
sage: f = L(lambda i: i, valuation=-3, constant=-1, degree=3) sage: f -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 - z^3 - z^4 - z^5 + O(z^6) sage: f[-2] -2 sage: f[10] -1 sage: f[-5] 0 sage: f = L(lambda i: i, valuation=-3) sage: f -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 + 3*z^3 + O(z^4) sage: f[20] 20
>>> from sage.all import * >>> f = L(lambda i: i, valuation=-Integer(3), constant=-Integer(1), degree=Integer(3)) >>> f -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 - z^3 - z^4 - z^5 + O(z^6) >>> f[-Integer(2)] -2 >>> f[Integer(10)] -1 >>> f[-Integer(5)] 0 >>> f = L(lambda i: i, valuation=-Integer(3)) >>> f -3*z^-3 - 2*z^-2 - z^-1 + z + 2*z^2 + 3*z^3 + O(z^4) >>> f[Integer(20)] 20
Anything that converts into a polynomial can be input, where we can also specify the valuation or if the series eventually takes a constant value:
sage: L([-5,2,0,5]) -5 + 2*z + 5*z^3 sage: L([-5,2,0,5], constant=6) -5 + 2*z + 5*z^3 + 6*z^4 + 6*z^5 + 6*z^6 + O(z^7) sage: L([-5,2,0,5], degree=6, constant=6) -5 + 2*z + 5*z^3 + 6*z^6 + 6*z^7 + 6*z^8 + O(z^9) sage: L([-5,2,0,5], valuation=-2, degree=3, constant=6) -5*z^-2 + 2*z^-1 + 5*z + 6*z^3 + 6*z^4 + 6*z^5 + O(z^6) sage: L([-5,2,0,5], valuation=5) -5*z^5 + 2*z^6 + 5*z^8 sage: L({-2:9, 3:4}, constant=2, degree=5) 9*z^-2 + 4*z^3 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8)
>>> from sage.all import * >>> L([-Integer(5),Integer(2),Integer(0),Integer(5)]) -5 + 2*z + 5*z^3 >>> L([-Integer(5),Integer(2),Integer(0),Integer(5)], constant=Integer(6)) -5 + 2*z + 5*z^3 + 6*z^4 + 6*z^5 + 6*z^6 + O(z^7) >>> L([-Integer(5),Integer(2),Integer(0),Integer(5)], degree=Integer(6), constant=Integer(6)) -5 + 2*z + 5*z^3 + 6*z^6 + 6*z^7 + 6*z^8 + O(z^9) >>> L([-Integer(5),Integer(2),Integer(0),Integer(5)], valuation=-Integer(2), degree=Integer(3), constant=Integer(6)) -5*z^-2 + 2*z^-1 + 5*z + 6*z^3 + 6*z^4 + 6*z^5 + O(z^6) >>> L([-Integer(5),Integer(2),Integer(0),Integer(5)], valuation=Integer(5)) -5*z^5 + 2*z^6 + 5*z^8 >>> L({-Integer(2):Integer(9), Integer(3):Integer(4)}, constant=Integer(2), degree=Integer(5)) 9*z^-2 + 4*z^3 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8)
We can also perform arithmetic:
sage: f = 1 / (1 - z - z^2) sage: f 1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7) sage: f.coefficient(100) 573147844013817084101 sage: f = (z^-2 - 1 + 2*z) / (z^-1 - z + 3*z^2) sage: f z^-1 - z^2 - z^4 + 3*z^5 + O(z^6)
>>> from sage.all import * >>> f = Integer(1) / (Integer(1) - z - z**Integer(2)) >>> f 1 + z + 2*z^2 + 3*z^3 + 5*z^4 + 8*z^5 + 13*z^6 + O(z^7) >>> f.coefficient(Integer(100)) 573147844013817084101 >>> f = (z**-Integer(2) - Integer(1) + Integer(2)*z) / (z**-Integer(1) - z + Integer(3)*z**Integer(2)) >>> f z^-1 - z^2 - z^4 + 3*z^5 + O(z^6)
However, we may not always be able to know when a result is exactly a polynomial:
sage: f * (z^-1 - z + 3*z^2) z^-2 - 1 + 2*z + O(z^5)
>>> from sage.all import * >>> f * (z**-Integer(1) - z + Integer(3)*z**Integer(2)) z^-2 - 1 + 2*z + O(z^5)
- O(prec, name=None)[source]#
Return the Laurent series with absolute precision
prec
approximated from this series.INPUT:
prec
– an integername
– name of the variable; if it isNone
, the name of the variable of the series is used
OUTPUT: a Laurent series with absolute precision
prec
EXAMPLES:
sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: z = L.gen() sage: f = (z - 2*z^3)^5/(1 - 2*z) sage: f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) sage: g = f.approximate_series(10) sage: g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) sage: g.parent() Power Series Ring in z over Integer Ring sage: h = (f^-1).approximate_series(3) sage: h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) sage: h.parent() Laurent Series Ring in z over Integer Ring
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, 'z') >>> z = L.gen() >>> f = (z - Integer(2)*z**Integer(3))**Integer(5)/(Integer(1) - Integer(2)*z) >>> f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) >>> g = f.approximate_series(Integer(10)) >>> g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) >>> g.parent() Power Series Ring in z over Integer Ring >>> h = (f**-Integer(1)).approximate_series(Integer(3)) >>> h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) >>> h.parent() Laurent Series Ring in z over Integer Ring
- add_bigoh(prec, name=None)[source]#
Return the Laurent series with absolute precision
prec
approximated from this series.INPUT:
prec
– an integername
– name of the variable; if it isNone
, the name of the variable of the series is used
OUTPUT: a Laurent series with absolute precision
prec
EXAMPLES:
sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: z = L.gen() sage: f = (z - 2*z^3)^5/(1 - 2*z) sage: f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) sage: g = f.approximate_series(10) sage: g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) sage: g.parent() Power Series Ring in z over Integer Ring sage: h = (f^-1).approximate_series(3) sage: h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) sage: h.parent() Laurent Series Ring in z over Integer Ring
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, 'z') >>> z = L.gen() >>> f = (z - Integer(2)*z**Integer(3))**Integer(5)/(Integer(1) - Integer(2)*z) >>> f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) >>> g = f.approximate_series(Integer(10)) >>> g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) >>> g.parent() Power Series Ring in z over Integer Ring >>> h = (f**-Integer(1)).approximate_series(Integer(3)) >>> h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) >>> h.parent() Laurent Series Ring in z over Integer Ring
- approximate_series(prec, name=None)[source]#
Return the Laurent series with absolute precision
prec
approximated from this series.INPUT:
prec
– an integername
– name of the variable; if it isNone
, the name of the variable of the series is used
OUTPUT: a Laurent series with absolute precision
prec
EXAMPLES:
sage: L = LazyLaurentSeriesRing(ZZ, 'z') sage: z = L.gen() sage: f = (z - 2*z^3)^5/(1 - 2*z) sage: f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) sage: g = f.approximate_series(10) sage: g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) sage: g.parent() Power Series Ring in z over Integer Ring sage: h = (f^-1).approximate_series(3) sage: h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) sage: h.parent() Laurent Series Ring in z over Integer Ring
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, 'z') >>> z = L.gen() >>> f = (z - Integer(2)*z**Integer(3))**Integer(5)/(Integer(1) - Integer(2)*z) >>> f z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + 32*z^10 - 16*z^11 + O(z^12) >>> g = f.approximate_series(Integer(10)) >>> g z^5 + 2*z^6 - 6*z^7 - 12*z^8 + 16*z^9 + O(z^10) >>> g.parent() Power Series Ring in z over Integer Ring >>> h = (f**-Integer(1)).approximate_series(Integer(3)) >>> h z^-5 - 2*z^-4 + 10*z^-3 - 20*z^-2 + 60*z^-1 - 120 + 280*z - 560*z^2 + O(z^3) >>> h.parent() Laurent Series Ring in z over Integer Ring
- compose(g)[source]#
Return the composition of
self
withg
.Given two Laurent series \(f\) and \(g\) over the same base ring, the composition \((f \circ g)(z) = f(g(z))\) is defined if and only if:
\(g = 0\) and \(\mathrm{val}(f) \geq 0\),
\(g\) is non-zero and \(f\) has only finitely many non-zero coefficients,
\(g\) is non-zero and \(\mathrm{val}(g) > 0\).
INPUT:
g
– other series
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: f = z^2 + 1 + z sage: f(0) 1 sage: f(L(0)) 1 sage: f(f) 3 + 3*z + 4*z^2 + 2*z^3 + z^4 sage: g = z^-3/(1-2*z); g z^-3 + 2*z^-2 + 4*z^-1 + 8 + 16*z + 32*z^2 + 64*z^3 + O(z^4) sage: f(g) z^-6 + 4*z^-5 + 12*z^-4 + 33*z^-3 + 82*z^-2 + 196*z^-1 + 457 + O(z) sage: g^2 + 1 + g z^-6 + 4*z^-5 + 12*z^-4 + 33*z^-3 + 82*z^-2 + 196*z^-1 + 457 + O(z) sage: f(int(2)) 7 sage: f = z^-2 + z + 4*z^3 sage: f(f) 4*z^-6 + 12*z^-3 + z^-2 + 48*z^-1 + 12 + O(z) sage: f^-2 + f + 4*f^3 4*z^-6 + 12*z^-3 + z^-2 + 48*z^-1 + 12 + O(z) sage: f(g) 4*z^-9 + 24*z^-8 + 96*z^-7 + 320*z^-6 + 960*z^-5 + 2688*z^-4 + 7169*z^-3 + O(z^-2) sage: g^-2 + g + 4*g^3 4*z^-9 + 24*z^-8 + 96*z^-7 + 320*z^-6 + 960*z^-5 + 2688*z^-4 + 7169*z^-3 + O(z^-2) sage: f = z^-3 + z^-2 + 1 / (1 + z^2); f z^-3 + z^-2 + 1 - z^2 + O(z^4) sage: g = z^3 / (1 + z - z^3); g z^3 - z^4 + z^5 - z^7 + 2*z^8 - 2*z^9 + O(z^10) sage: f(g) z^-9 + 3*z^-8 + 3*z^-7 - z^-6 - 4*z^-5 - 2*z^-4 + z^-3 + O(z^-2) sage: g^-3 + g^-2 + 1 / (1 + g^2) z^-9 + 3*z^-8 + 3*z^-7 - z^-6 - 4*z^-5 - 2*z^-4 + z^-3 + O(z^-2) sage: f = z^-3 sage: g = z^-2 + z^-1 sage: g^(-3) z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13) sage: f(g) z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13) sage: f = z^2 + z^3 sage: g = z^-3 + z^-2 sage: f^-3 + f^-2 z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z) sage: g(f) z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z) sage: g^2 + g^3 z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4 sage: f(g) z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4 sage: f = L(lambda n: n, valuation=0); f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: f(z^2) z^2 + 2*z^4 + 3*z^6 + 4*z^8 + O(z^9) sage: f = L(lambda n: n, valuation=-2); f -2*z^-2 - z^-1 + z + 2*z^2 + 3*z^3 + 4*z^4 + O(z^5) sage: f3 = f(z^3); f3 -2*z^-6 - z^-3 + O(z) sage: [f3[i] for i in range(-6,13)] [-2, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4]
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> f = z**Integer(2) + Integer(1) + z >>> f(Integer(0)) 1 >>> f(L(Integer(0))) 1 >>> f(f) 3 + 3*z + 4*z^2 + 2*z^3 + z^4 >>> g = z**-Integer(3)/(Integer(1)-Integer(2)*z); g z^-3 + 2*z^-2 + 4*z^-1 + 8 + 16*z + 32*z^2 + 64*z^3 + O(z^4) >>> f(g) z^-6 + 4*z^-5 + 12*z^-4 + 33*z^-3 + 82*z^-2 + 196*z^-1 + 457 + O(z) >>> g**Integer(2) + Integer(1) + g z^-6 + 4*z^-5 + 12*z^-4 + 33*z^-3 + 82*z^-2 + 196*z^-1 + 457 + O(z) >>> f(int(Integer(2))) 7 >>> f = z**-Integer(2) + z + Integer(4)*z**Integer(3) >>> f(f) 4*z^-6 + 12*z^-3 + z^-2 + 48*z^-1 + 12 + O(z) >>> f**-Integer(2) + f + Integer(4)*f**Integer(3) 4*z^-6 + 12*z^-3 + z^-2 + 48*z^-1 + 12 + O(z) >>> f(g) 4*z^-9 + 24*z^-8 + 96*z^-7 + 320*z^-6 + 960*z^-5 + 2688*z^-4 + 7169*z^-3 + O(z^-2) >>> g**-Integer(2) + g + Integer(4)*g**Integer(3) 4*z^-9 + 24*z^-8 + 96*z^-7 + 320*z^-6 + 960*z^-5 + 2688*z^-4 + 7169*z^-3 + O(z^-2) >>> f = z**-Integer(3) + z**-Integer(2) + Integer(1) / (Integer(1) + z**Integer(2)); f z^-3 + z^-2 + 1 - z^2 + O(z^4) >>> g = z**Integer(3) / (Integer(1) + z - z**Integer(3)); g z^3 - z^4 + z^5 - z^7 + 2*z^8 - 2*z^9 + O(z^10) >>> f(g) z^-9 + 3*z^-8 + 3*z^-7 - z^-6 - 4*z^-5 - 2*z^-4 + z^-3 + O(z^-2) >>> g**-Integer(3) + g**-Integer(2) + Integer(1) / (Integer(1) + g**Integer(2)) z^-9 + 3*z^-8 + 3*z^-7 - z^-6 - 4*z^-5 - 2*z^-4 + z^-3 + O(z^-2) >>> f = z**-Integer(3) >>> g = z**-Integer(2) + z**-Integer(1) >>> g**(-Integer(3)) z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13) >>> f(g) z^6 - 3*z^7 + 6*z^8 - 10*z^9 + 15*z^10 - 21*z^11 + 28*z^12 + O(z^13) >>> f = z**Integer(2) + z**Integer(3) >>> g = z**-Integer(3) + z**-Integer(2) >>> f**-Integer(3) + f**-Integer(2) z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z) >>> g(f) z^-6 - 3*z^-5 + 7*z^-4 - 12*z^-3 + 18*z^-2 - 25*z^-1 + 33 + O(z) >>> g**Integer(2) + g**Integer(3) z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4 >>> f(g) z^-9 + 3*z^-8 + 3*z^-7 + 2*z^-6 + 2*z^-5 + z^-4 >>> f = L(lambda n: n, valuation=Integer(0)); f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> f(z**Integer(2)) z^2 + 2*z^4 + 3*z^6 + 4*z^8 + O(z^9) >>> f = L(lambda n: n, valuation=-Integer(2)); f -2*z^-2 - z^-1 + z + 2*z^2 + 3*z^3 + 4*z^4 + O(z^5) >>> f3 = f(z**Integer(3)); f3 -2*z^-6 - z^-3 + O(z) >>> [f3[i] for i in range(-Integer(6),Integer(13))] [-2, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4]
We compose a Laurent polynomial with a generic element:
sage: R.<x> = QQ[] sage: f = z^2 + 1 + z^-1 sage: g = x^2 + x + 3 sage: f(g) (x^6 + 3*x^5 + 12*x^4 + 19*x^3 + 37*x^2 + 28*x + 31)/(x^2 + x + 3) sage: f(g) == g^2 + 1 + g^-1 True
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> f = z**Integer(2) + Integer(1) + z**-Integer(1) >>> g = x**Integer(2) + x + Integer(3) >>> f(g) (x^6 + 3*x^5 + 12*x^4 + 19*x^3 + 37*x^2 + 28*x + 31)/(x^2 + x + 3) >>> f(g) == g**Integer(2) + Integer(1) + g**-Integer(1) True
We compose with another lazy Laurent series:
sage: LS.<y> = LazyLaurentSeriesRing(QQ) sage: f = z^2 + 1 + z^-1 sage: fy = f(y); fy y^-1 + 1 + y^2 sage: fy.parent() is LS True sage: g = y - y sage: f(g) Traceback (most recent call last): ... ZeroDivisionError: the valuation of the series must be nonnegative sage: g = 1 - y sage: f(g) 3 - y + 2*y^2 + y^3 + y^4 + y^5 + O(y^6) sage: g^2 + 1 + g^-1 3 - y + 2*y^2 + y^3 + y^4 + y^5 + O(y^6) sage: f = L(lambda n: n, valuation=0); f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: f(0) 0 sage: f(y) y + 2*y^2 + 3*y^3 + 4*y^4 + 5*y^5 + 6*y^6 + 7*y^7 + O(y^8) sage: fp = f(y - y) sage: fp == 0 True sage: fp.parent() is LS True sage: f = z^2 + 3 + z sage: f(y - y) 3
>>> from sage.all import * >>> LS = LazyLaurentSeriesRing(QQ, names=('y',)); (y,) = LS._first_ngens(1) >>> f = z**Integer(2) + Integer(1) + z**-Integer(1) >>> fy = f(y); fy y^-1 + 1 + y^2 >>> fy.parent() is LS True >>> g = y - y >>> f(g) Traceback (most recent call last): ... ZeroDivisionError: the valuation of the series must be nonnegative >>> g = Integer(1) - y >>> f(g) 3 - y + 2*y^2 + y^3 + y^4 + y^5 + O(y^6) >>> g**Integer(2) + Integer(1) + g**-Integer(1) 3 - y + 2*y^2 + y^3 + y^4 + y^5 + O(y^6) >>> f = L(lambda n: n, valuation=Integer(0)); f z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> f(Integer(0)) 0 >>> f(y) y + 2*y^2 + 3*y^3 + 4*y^4 + 5*y^5 + 6*y^6 + 7*y^7 + O(y^8) >>> fp = f(y - y) >>> fp == Integer(0) True >>> fp.parent() is LS True >>> f = z**Integer(2) + Integer(3) + z >>> f(y - y) 3
With both of them sparse:
sage: L.<z> = LazyLaurentSeriesRing(QQ, sparse=True) sage: LS.<y> = LazyLaurentSeriesRing(QQ, sparse=True) sage: f = L(lambda n: 1, valuation=0); f 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) sage: f(y^2) 1 + y^2 + y^4 + y^6 + O(y^7) sage: fp = f - 1 + z^-2; fp z^-2 + z + z^2 + z^3 + z^4 + O(z^5) sage: fpy = fp(y^2); fpy y^-4 + y^2 + O(y^3) sage: fpy.parent() is LS True sage: [fpy[i] for i in range(-4,11)] [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] sage: g = LS(valuation=2, constant=1); g y^2 + y^3 + y^4 + O(y^5) sage: fg = f(g); fg 1 + y^2 + y^3 + 2*y^4 + 3*y^5 + 5*y^6 + O(y^7) sage: 1 + g + g^2 + g^3 + g^4 + g^5 + g^6 1 + y^2 + y^3 + 2*y^4 + 3*y^5 + 5*y^6 + O(y^7) sage: h = LS(lambda n: 1 if n % 2 else 0, valuation=2); h y^3 + y^5 + y^7 + O(y^9) sage: fgh = fg(h); fgh 1 + y^6 + O(y^7) sage: [fgh[i] for i in range(0, 15)] [1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 3, 3, 6, 6, 13] sage: t = 1 + h^2 + h^3 + 2*h^4 + 3*h^5 + 5*h^6 sage: [t[i] for i in range(0, 15)] [1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 3, 3, 6, 6, 13]
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, sparse=True, names=('z',)); (z,) = L._first_ngens(1) >>> LS = LazyLaurentSeriesRing(QQ, sparse=True, names=('y',)); (y,) = LS._first_ngens(1) >>> f = L(lambda n: Integer(1), valuation=Integer(0)); f 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) >>> f(y**Integer(2)) 1 + y^2 + y^4 + y^6 + O(y^7) >>> fp = f - Integer(1) + z**-Integer(2); fp z^-2 + z + z^2 + z^3 + z^4 + O(z^5) >>> fpy = fp(y**Integer(2)); fpy y^-4 + y^2 + O(y^3) >>> fpy.parent() is LS True >>> [fpy[i] for i in range(-Integer(4),Integer(11))] [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1] >>> g = LS(valuation=Integer(2), constant=Integer(1)); g y^2 + y^3 + y^4 + O(y^5) >>> fg = f(g); fg 1 + y^2 + y^3 + 2*y^4 + 3*y^5 + 5*y^6 + O(y^7) >>> Integer(1) + g + g**Integer(2) + g**Integer(3) + g**Integer(4) + g**Integer(5) + g**Integer(6) 1 + y^2 + y^3 + 2*y^4 + 3*y^5 + 5*y^6 + O(y^7) >>> h = LS(lambda n: Integer(1) if n % Integer(2) else Integer(0), valuation=Integer(2)); h y^3 + y^5 + y^7 + O(y^9) >>> fgh = fg(h); fgh 1 + y^6 + O(y^7) >>> [fgh[i] for i in range(Integer(0), Integer(15))] [1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 3, 3, 6, 6, 13] >>> t = Integer(1) + h**Integer(2) + h**Integer(3) + Integer(2)*h**Integer(4) + Integer(3)*h**Integer(5) + Integer(5)*h**Integer(6) >>> [t[i] for i in range(Integer(0), Integer(15))] [1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 3, 3, 6, 6, 13]
We look at mixing the sparse and the dense:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: f = L(lambda n: 1, valuation=0); f 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) sage: g = LS(lambda n: 1, valuation=1); g y + y^2 + y^3 + y^4 + y^5 + y^6 + y^7 + O(y^8) sage: f(g) 1 + y + 2*y^2 + 4*y^3 + 8*y^4 + 16*y^5 + 32*y^6 + O(y^7) sage: f = z^-2 + 1 + z sage: g = 1/(y*(1-y)); g y^-1 + 1 + y + O(y^2) sage: f(g) y^-1 + 2 + y + 2*y^2 - y^3 + 2*y^4 + y^5 + y^6 + y^7 + O(y^8) sage: g^-2 + 1 + g == f(g) True sage: f = z^-3 + z^-2 + 1 sage: g = 1/(y^2*(1-y)); g y^-2 + y^-1 + 1 + O(y) sage: f(g) 1 + y^4 - 2*y^5 + 2*y^6 - 3*y^7 + 3*y^8 - y^9 sage: g^-3 + g^-2 + 1 == f(g) True sage: z(y) y
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> f = L(lambda n: Integer(1), valuation=Integer(0)); f 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) >>> g = LS(lambda n: Integer(1), valuation=Integer(1)); g y + y^2 + y^3 + y^4 + y^5 + y^6 + y^7 + O(y^8) >>> f(g) 1 + y + 2*y^2 + 4*y^3 + 8*y^4 + 16*y^5 + 32*y^6 + O(y^7) >>> f = z**-Integer(2) + Integer(1) + z >>> g = Integer(1)/(y*(Integer(1)-y)); g y^-1 + 1 + y + O(y^2) >>> f(g) y^-1 + 2 + y + 2*y^2 - y^3 + 2*y^4 + y^5 + y^6 + y^7 + O(y^8) >>> g**-Integer(2) + Integer(1) + g == f(g) True >>> f = z**-Integer(3) + z**-Integer(2) + Integer(1) >>> g = Integer(1)/(y**Integer(2)*(Integer(1)-y)); g y^-2 + y^-1 + 1 + O(y) >>> f(g) 1 + y^4 - 2*y^5 + 2*y^6 - 3*y^7 + 3*y^8 - y^9 >>> g**-Integer(3) + g**-Integer(2) + Integer(1) == f(g) True >>> z(y) y
We look at cases where the composition does not exist. \(g = 0\) and \(\mathrm{val}(f) < 0\):
sage: g = L(0) sage: f = z^-1 + z^-2 sage: f.valuation() < 0 True sage: f(g) Traceback (most recent call last): ... ZeroDivisionError: the valuation of the series must be nonnegative
>>> from sage.all import * >>> g = L(Integer(0)) >>> f = z**-Integer(1) + z**-Integer(2) >>> f.valuation() < Integer(0) True >>> f(g) Traceback (most recent call last): ... ZeroDivisionError: the valuation of the series must be nonnegative
\(g \neq 0\) and \(\mathrm{val}(g) \leq 0\) and \(f\) has infinitely many non-zero coefficients:
sage: g = z^-1 + z^-2 sage: g.valuation() <= 0 True sage: f = L(lambda n: n, valuation=0) sage: f(g) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series sage: f = L(lambda n: n, valuation=1) sage: f(1 + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series
>>> from sage.all import * >>> g = z**-Integer(1) + z**-Integer(2) >>> g.valuation() <= Integer(0) True >>> f = L(lambda n: n, valuation=Integer(0)) >>> f(g) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series >>> f = L(lambda n: n, valuation=Integer(1)) >>> f(Integer(1) + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series
We compose the exponential with a Dirichlet series:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: e = L(lambda n: 1/factorial(n), 0) sage: D = LazyDirichletSeriesRing(QQ, "s") sage: g = D(constant=1)-1 sage: g # needs sage.symbolic 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) sage: e(g)[0:10] [0, 1, 1, 1, 3/2, 1, 2, 1, 13/6, 3/2] sage: sum(g^k/factorial(k) for k in range(10))[0:10] [0, 1, 1, 1, 3/2, 1, 2, 1, 13/6, 3/2] sage: g = D([0,1,0,1,1,2]) sage: g # needs sage.symbolic 1/(2^s) + 1/(4^s) + 1/(5^s) + 2/6^s sage: e(g)[0:10] [0, 1, 1, 0, 3/2, 1, 2, 0, 7/6, 0] sage: sum(g^k/factorial(k) for k in range(10))[0:10] [0, 1, 1, 0, 3/2, 1, 2, 0, 7/6, 0] sage: e(D([1,0,1])) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series sage: e5 = L(e, degree=5) sage: e5 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 sage: e5(g) # needs sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s)) sage: sum(e5[k] * g^k for k in range(5)) # needs sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s))
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> e = L(lambda n: Integer(1)/factorial(n), Integer(0)) >>> D = LazyDirichletSeriesRing(QQ, "s") >>> g = D(constant=Integer(1))-Integer(1) >>> g # needs sage.symbolic 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) >>> e(g)[Integer(0):Integer(10)] [0, 1, 1, 1, 3/2, 1, 2, 1, 13/6, 3/2] >>> sum(g**k/factorial(k) for k in range(Integer(10)))[Integer(0):Integer(10)] [0, 1, 1, 1, 3/2, 1, 2, 1, 13/6, 3/2] >>> g = D([Integer(0),Integer(1),Integer(0),Integer(1),Integer(1),Integer(2)]) >>> g # needs sage.symbolic 1/(2^s) + 1/(4^s) + 1/(5^s) + 2/6^s >>> e(g)[Integer(0):Integer(10)] [0, 1, 1, 0, 3/2, 1, 2, 0, 7/6, 0] >>> sum(g**k/factorial(k) for k in range(Integer(10)))[Integer(0):Integer(10)] [0, 1, 1, 0, 3/2, 1, 2, 0, 7/6, 0] >>> e(D([Integer(1),Integer(0),Integer(1)])) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series >>> e5 = L(e, degree=Integer(5)) >>> e5 1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4 >>> e5(g) # needs sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s)) >>> sum(e5[k] * g**k for k in range(Integer(5))) # needs sage.symbolic 1 + 1/(2^s) + 3/2/4^s + 1/(5^s) + 2/6^s + O(1/(8^s))
The output parent is always the common parent between the base ring of \(f\) and the parent of \(g\) or extended to the corresponding lazy series:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: R.<x> = ZZ[] sage: parent(z(x)) Univariate Polynomial Ring in x over Rational Field sage: parent(z(R.zero())) Univariate Polynomial Ring in x over Rational Field sage: parent(z(0)) Rational Field sage: f = 1 / (1 - z) sage: f(x) 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + O(x^7) sage: three = L(3)(x^2); three 3 sage: parent(three) Univariate Polynomial Ring in x over Rational Field
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> R = ZZ['x']; (x,) = R._first_ngens(1) >>> parent(z(x)) Univariate Polynomial Ring in x over Rational Field >>> parent(z(R.zero())) Univariate Polynomial Ring in x over Rational Field >>> parent(z(Integer(0))) Rational Field >>> f = Integer(1) / (Integer(1) - z) >>> f(x) 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + O(x^7) >>> three = L(Integer(3))(x**Integer(2)); three 3 >>> parent(three) Univariate Polynomial Ring in x over Rational Field
Consistency check when \(g\) is an uninitialized series between a polynomial \(f\) as both a polynomial and a lazy series:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: f = 1 + z sage: g = L.undefined(valuation=0) sage: f(g) == f.polynomial()(g) True
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> f = Integer(1) + z >>> g = L.undefined(valuation=Integer(0)) >>> f(g) == f.polynomial()(g) True
- compositional_inverse()[source]#
Return the compositional inverse of
self
.Given a Laurent series \(f\), the compositional inverse is a Laurent series \(g\) over the same base ring, such that \((f \circ g)(z) = f(g(z)) = z\).
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b z\) with \(a, b \neq 0\), or
\(f = a/z\) with \(a \neq 0\).
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: (2*z).revert() 1/2*z sage: (2/z).revert() 2*z^-1 sage: (z-z^2).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) sage: s = L(degree=1, constant=-1) sage: s.revert() -z - z^2 - z^3 + O(z^4) sage: s = L(degree=1, constant=1) sage: s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).revert() 1/2*z >>> (Integer(2)/z).revert() 2*z^-1 >>> (z-z**Integer(2)).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) >>> s = L(degree=Integer(1), constant=-Integer(1)) >>> s.revert() -z - z^2 - z^3 + O(z^4) >>> s = L(degree=Integer(1), constant=Integer(1)) >>> s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
Warning
For series not known to be eventually constant (e.g., being defined by a function) with approximate valuation \(\leq 1\) (but not necessarily its true valuation), this assumes that this is the actual valuation:
sage: f = L(lambda n: n if n > 2 else 0, valuation=1) sage: f.revert() <repr(... failed: ValueError: inverse does not exist>
>>> from sage.all import * >>> f = L(lambda n: n if n > Integer(2) else Integer(0), valuation=Integer(1)) >>> f.revert() <repr(... failed: ValueError: inverse does not exist>
- derivative(*args)[source]#
Return the derivative of the Laurent series.
Multiple variables and iteration counts may be supplied; see the documentation of
sage.calculus.functional.derivative()
function for details.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: z.derivative() 1 sage: (1+z+z^2).derivative(3) 0 sage: (1/z).derivative() -z^-2 sage: (1/(1-z)).derivative(z) 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> z.derivative() 1 >>> (Integer(1)+z+z**Integer(2)).derivative(Integer(3)) 0 >>> (Integer(1)/z).derivative() -z^-2 >>> (Integer(1)/(Integer(1)-z)).derivative(z) 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)
- integral(variable, constants=None)[source]#
Return the integral of
self
with respect tovariable
.INPUT:
variable
– (optional) the variable to integrateconstants
– (optional; keyword-only) list of integration constants for the integrals ofself
(the last constant corresponds to the first integral)
If the first argument is a list, then this method iterprets it as integration constants. If it is a positive integer, the method interprets it as the number of times to integrate the function. If
variable
is not the variable of the Laurent series, then the coefficients are integrated with respect tovariable
.If the integration constants are not specified, they are considered to be \(0\).
EXAMPLES:
sage: L.<t> = LazyLaurentSeriesRing(QQ) sage: f = t^-3 + 2 + 3*t + t^5 sage: f.integral() -1/2*t^-2 + 2*t + 3/2*t^2 + 1/6*t^6 sage: f.integral([-2, -2]) 1/2*t^-1 - 2 - 2*t + t^2 + 1/2*t^3 + 1/42*t^7 sage: f.integral(t) -1/2*t^-2 + 2*t + 3/2*t^2 + 1/6*t^6 sage: f.integral(2) 1/2*t^-1 + t^2 + 1/2*t^3 + 1/42*t^7 sage: L.zero().integral() 0 sage: L.zero().integral([0, 1, 2, 3]) t + t^2 + 1/2*t^3
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('t',)); (t,) = L._first_ngens(1) >>> f = t**-Integer(3) + Integer(2) + Integer(3)*t + t**Integer(5) >>> f.integral() -1/2*t^-2 + 2*t + 3/2*t^2 + 1/6*t^6 >>> f.integral([-Integer(2), -Integer(2)]) 1/2*t^-1 - 2 - 2*t + t^2 + 1/2*t^3 + 1/42*t^7 >>> f.integral(t) -1/2*t^-2 + 2*t + 3/2*t^2 + 1/6*t^6 >>> f.integral(Integer(2)) 1/2*t^-1 + t^2 + 1/2*t^3 + 1/42*t^7 >>> L.zero().integral() 0 >>> L.zero().integral([Integer(0), Integer(1), Integer(2), Integer(3)]) t + t^2 + 1/2*t^3
We solve the ODE \(f' = a f\) by integrating both sides and the recursive definition:
sage: R.<a, C> = QQ[] sage: L.<x> = LazyLaurentSeriesRing(R) sage: f = L.undefined(0) sage: f.define((a*f).integral(constants=[C])) sage: f C + a*C*x + 1/2*a^2*C*x^2 + 1/6*a^3*C*x^3 + 1/24*a^4*C*x^4 + 1/120*a^5*C*x^5 + 1/720*a^6*C*x^6 + O(x^7) sage: C * exp(a*x) C + a*C*x + 1/2*a^2*C*x^2 + 1/6*a^3*C*x^3 + 1/24*a^4*C*x^4 + 1/120*a^5*C*x^5 + 1/720*a^6*C*x^6 + O(x^7)
>>> from sage.all import * >>> R = QQ['a, C']; (a, C,) = R._first_ngens(2) >>> L = LazyLaurentSeriesRing(R, names=('x',)); (x,) = L._first_ngens(1) >>> f = L.undefined(Integer(0)) >>> f.define((a*f).integral(constants=[C])) >>> f C + a*C*x + 1/2*a^2*C*x^2 + 1/6*a^3*C*x^3 + 1/24*a^4*C*x^4 + 1/120*a^5*C*x^5 + 1/720*a^6*C*x^6 + O(x^7) >>> C * exp(a*x) C + a*C*x + 1/2*a^2*C*x^2 + 1/6*a^3*C*x^3 + 1/24*a^4*C*x^4 + 1/120*a^5*C*x^5 + 1/720*a^6*C*x^6 + O(x^7)
We can integrate both the series and coefficients:
sage: R.<x,y,z> = QQ[] sage: L.<t> = LazyLaurentSeriesRing(R) sage: f = (x*t^2 + y*t^-2 + z)^2; f y^2*t^-4 + 2*y*z*t^-2 + (2*x*y + z^2) + 2*x*z*t^2 + x^2*t^4 sage: f.integral(x) x*y^2*t^-4 + 2*x*y*z*t^-2 + (x^2*y + x*z^2) + x^2*z*t^2 + 1/3*x^3*t^4 sage: f.integral(t) -1/3*y^2*t^-3 - 2*y*z*t^-1 + (2*x*y + z^2)*t + 2/3*x*z*t^3 + 1/5*x^2*t^5 sage: f.integral(y, constants=[x*y*z]) -1/9*y^3*t^-3 - y^2*z*t^-1 + x*y*z + (x*y^2 + y*z^2)*t + 2/3*x*y*z*t^3 + 1/5*x^2*y*t^5
>>> from sage.all import * >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3) >>> L = LazyLaurentSeriesRing(R, names=('t',)); (t,) = L._first_ngens(1) >>> f = (x*t**Integer(2) + y*t**-Integer(2) + z)**Integer(2); f y^2*t^-4 + 2*y*z*t^-2 + (2*x*y + z^2) + 2*x*z*t^2 + x^2*t^4 >>> f.integral(x) x*y^2*t^-4 + 2*x*y*z*t^-2 + (x^2*y + x*z^2) + x^2*z*t^2 + 1/3*x^3*t^4 >>> f.integral(t) -1/3*y^2*t^-3 - 2*y*z*t^-1 + (2*x*y + z^2)*t + 2/3*x*z*t^3 + 1/5*x^2*t^5 >>> f.integral(y, constants=[x*y*z]) -1/9*y^3*t^-3 - y^2*z*t^-1 + x*y*z + (x*y^2 + y*z^2)*t + 2/3*x*y*z*t^3 + 1/5*x^2*y*t^5
- is_unit()[source]#
Return whether this element is a unit in the ring.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: (2*z).is_unit() False sage: (1 + 2*z).is_unit() True sage: (1 + 2*z^-1).is_unit() False sage: (z^3 + 4 - z^-2).is_unit() True
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).is_unit() False >>> (Integer(1) + Integer(2)*z).is_unit() True >>> (Integer(1) + Integer(2)*z**-Integer(1)).is_unit() False >>> (z**Integer(3) + Integer(4) - z**-Integer(2)).is_unit() True
- polynomial(degree=None, name=None)[source]#
Return
self
as a Laurent polynomial ifself
is actually so.INPUT:
degree
–None
or an integername
– name of the variable; if it isNone
, the name of the variable of the series is used
OUTPUT:
A Laurent polynomial if the valuation of the series is negative or a polynomial otherwise.
If
degree
is notNone
, the terms of the series of degree greater thandegree
are first truncated. Ifdegree
isNone
and the series is not a polynomial or a Laurent polynomial, aValueError
is raised.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = L([1,0,0,2,0,0,0,3], valuation=5); f z^5 + 2*z^8 + 3*z^12 sage: f.polynomial() 3*z^12 + 2*z^8 + z^5
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = L([Integer(1),Integer(0),Integer(0),Integer(2),Integer(0),Integer(0),Integer(0),Integer(3)], valuation=Integer(5)); f z^5 + 2*z^8 + 3*z^12 >>> f.polynomial() 3*z^12 + 2*z^8 + z^5
- revert()[source]#
Return the compositional inverse of
self
.Given a Laurent series \(f\), the compositional inverse is a Laurent series \(g\) over the same base ring, such that \((f \circ g)(z) = f(g(z)) = z\).
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b z\) with \(a, b \neq 0\), or
\(f = a/z\) with \(a \neq 0\).
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: (2*z).revert() 1/2*z sage: (2/z).revert() 2*z^-1 sage: (z-z^2).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) sage: s = L(degree=1, constant=-1) sage: s.revert() -z - z^2 - z^3 + O(z^4) sage: s = L(degree=1, constant=1) sage: s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).revert() 1/2*z >>> (Integer(2)/z).revert() 2*z^-1 >>> (z-z**Integer(2)).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) >>> s = L(degree=Integer(1), constant=-Integer(1)) >>> s.revert() -z - z^2 - z^3 + O(z^4) >>> s = L(degree=Integer(1), constant=Integer(1)) >>> s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
Warning
For series not known to be eventually constant (e.g., being defined by a function) with approximate valuation \(\leq 1\) (but not necessarily its true valuation), this assumes that this is the actual valuation:
sage: f = L(lambda n: n if n > 2 else 0, valuation=1) sage: f.revert() <repr(... failed: ValueError: inverse does not exist>
>>> from sage.all import * >>> f = L(lambda n: n if n > Integer(2) else Integer(0), valuation=Integer(1)) >>> f.revert() <repr(... failed: ValueError: inverse does not exist>
- class sage.rings.lazy_series.LazyModuleElement(parent, coeff_stream)[source]#
Bases:
Element
A lazy sequence with a module structure given by term-wise addition and scalar multiplication.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: M = L(lambda n: n, valuation=0) sage: N = L(lambda n: 1, valuation=0) sage: M[0:10] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] sage: N[0:10] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> M = L(lambda n: n, valuation=Integer(0)) >>> N = L(lambda n: Integer(1), valuation=Integer(0)) >>> M[Integer(0):Integer(10)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> N[Integer(0):Integer(10)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Two sequences can be added:
sage: O = M + N sage: O[0:10] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> from sage.all import * >>> O = M + N >>> O[Integer(0):Integer(10)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Two sequences can be subtracted:
sage: P = M - N sage: P[0:10] [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> from sage.all import * >>> P = M - N >>> P[Integer(0):Integer(10)] [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8]
A sequence can be multiplied by a scalar:
sage: Q = 2 * M sage: Q[0:10] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> from sage.all import * >>> Q = Integer(2) * M >>> Q[Integer(0):Integer(10)] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
The negation of a sequence can also be found:
sage: R = -M sage: R[0:10] [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> from sage.all import * >>> R = -M >>> R[Integer(0):Integer(10)] [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
- arccos()[source]#
Return the arccosine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(RR) sage: arccos(z) # needs sage.symbolic 1.57079632679490 - 1.00000000000000*z + 0.000000000000000*z^2 - 0.166666666666667*z^3 + 0.000000000000000*z^4 - 0.0750000000000000*z^5 + O(1.00000000000000*z^7) sage: L.<z> = LazyLaurentSeriesRing(SR) # needs sage.symbolic sage: arccos(z/(1-z)) # needs sage.symbolic 1/2*pi - z - z^2 - 7/6*z^3 - 3/2*z^4 - 83/40*z^5 - 73/24*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(SR) # needs sage.symbolic sage: arccos(x/(1-y)) # needs sage.symbolic 1/2*pi + (-x) + (-x*y) + ((-1/6)*x^3-x*y^2) + ((-1/2)*x^3*y-x*y^3) + ((-3/40)*x^5-x^3*y^2-x*y^4) + ((-3/8)*x^5*y+(-5/3)*x^3*y^3-x*y^5) + O(x,y)^7
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(RR, names=('z',)); (z,) = L._first_ngens(1) >>> arccos(z) # needs sage.symbolic 1.57079632679490 - 1.00000000000000*z + 0.000000000000000*z^2 - 0.166666666666667*z^3 + 0.000000000000000*z^4 - 0.0750000000000000*z^5 + O(1.00000000000000*z^7) >>> L = LazyLaurentSeriesRing(SR, names=('z',)); (z,) = L._first_ngens(1)# needs sage.symbolic >>> arccos(z/(Integer(1)-z)) # needs sage.symbolic 1/2*pi - z - z^2 - 7/6*z^3 - 3/2*z^4 - 83/40*z^5 - 73/24*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(SR, names=('x', 'y',)); (x, y,) = L._first_ngens(2)# needs sage.symbolic >>> arccos(x/(Integer(1)-y)) # needs sage.symbolic 1/2*pi + (-x) + (-x*y) + ((-1/6)*x^3-x*y^2) + ((-1/2)*x^3*y-x*y^3) + ((-3/40)*x^5-x^3*y^2-x*y^4) + ((-3/8)*x^5*y+(-5/3)*x^3*y^3-x*y^5) + O(x,y)^7
- arccot()[source]#
Return the arctangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(RR) sage: arccot(z) # needs sage.symbolic 1.57079632679490 - 1.00000000000000*z + 0.000000000000000*z^2 + 0.333333333333333*z^3 + 0.000000000000000*z^4 - 0.200000000000000*z^5 + O(1.00000000000000*z^7) sage: L.<z> = LazyLaurentSeriesRing(SR) # needs sage.symbolic sage: arccot(z/(1-z)) # needs sage.symbolic 1/2*pi - z - z^2 - 2/3*z^3 + 4/5*z^5 + 4/3*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(SR) # needs sage.symbolic sage: acot(x/(1-y)) # needs sage.symbolic 1/2*pi + (-x) + (-x*y) + (1/3*x^3-x*y^2) + (x^3*y-x*y^3) + ((-1/5)*x^5+2*x^3*y^2-x*y^4) + (-x^5*y+10/3*x^3*y^3-x*y^5) + O(x,y)^7
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(RR, names=('z',)); (z,) = L._first_ngens(1) >>> arccot(z) # needs sage.symbolic 1.57079632679490 - 1.00000000000000*z + 0.000000000000000*z^2 + 0.333333333333333*z^3 + 0.000000000000000*z^4 - 0.200000000000000*z^5 + O(1.00000000000000*z^7) >>> L = LazyLaurentSeriesRing(SR, names=('z',)); (z,) = L._first_ngens(1)# needs sage.symbolic >>> arccot(z/(Integer(1)-z)) # needs sage.symbolic 1/2*pi - z - z^2 - 2/3*z^3 + 4/5*z^5 + 4/3*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(SR, names=('x', 'y',)); (x, y,) = L._first_ngens(2)# needs sage.symbolic >>> acot(x/(Integer(1)-y)) # needs sage.symbolic 1/2*pi + (-x) + (-x*y) + (1/3*x^3-x*y^2) + (x^3*y-x*y^3) + ((-1/5)*x^5+2*x^3*y^2-x*y^4) + (-x^5*y+10/3*x^3*y^3-x*y^5) + O(x,y)^7
- arcsin()[source]#
Return the arcsine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: arcsin(z) z + 1/6*z^3 + 3/40*z^5 + 5/112*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: asin(x/(1-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (3/40*x^5+x^3*y^2+x*y^4) + (3/8*x^5*y+5/3*x^3*y^3+x*y^5) + (5/112*x^7+9/8*x^5*y^2+5/2*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> arcsin(z) z + 1/6*z^3 + 3/40*z^5 + 5/112*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> asin(x/(Integer(1)-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (3/40*x^5+x^3*y^2+x*y^4) + (3/8*x^5*y+5/3*x^3*y^3+x*y^5) + (5/112*x^7+9/8*x^5*y^2+5/2*x^3*y^4+x*y^6) + O(x,y)^8
- arcsinh()[source]#
Return the inverse of the hyperbolic sine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: asinh(z) z - 1/6*z^3 + 3/40*z^5 - 5/112*z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> asinh(z) z - 1/6*z^3 + 3/40*z^5 - 5/112*z^7 + O(z^8)
arcsinh
is an alias:sage: arcsinh(z) z - 1/6*z^3 + 3/40*z^5 - 5/112*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: asinh(x/(1-y)) x + x*y + (-1/6*x^3+x*y^2) + (-1/2*x^3*y+x*y^3) + (3/40*x^5-x^3*y^2+x*y^4) + (3/8*x^5*y-5/3*x^3*y^3+x*y^5) + (-5/112*x^7+9/8*x^5*y^2-5/2*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> arcsinh(z) z - 1/6*z^3 + 3/40*z^5 - 5/112*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> asinh(x/(Integer(1)-y)) x + x*y + (-1/6*x^3+x*y^2) + (-1/2*x^3*y+x*y^3) + (3/40*x^5-x^3*y^2+x*y^4) + (3/8*x^5*y-5/3*x^3*y^3+x*y^5) + (-5/112*x^7+9/8*x^5*y^2-5/2*x^3*y^4+x*y^6) + O(x,y)^8
- arctan()[source]#
Return the arctangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: arctan(z) z - 1/3*z^3 + 1/5*z^5 - 1/7*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: atan(x/(1-y)) x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (1/5*x^5-2*x^3*y^2+x*y^4) + (x^5*y-10/3*x^3*y^3+x*y^5) + (-1/7*x^7+3*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> arctan(z) z - 1/3*z^3 + 1/5*z^5 - 1/7*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> atan(x/(Integer(1)-y)) x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (1/5*x^5-2*x^3*y^2+x*y^4) + (x^5*y-10/3*x^3*y^3+x*y^5) + (-1/7*x^7+3*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8
- arctanh()[source]#
Return the inverse of the hyperbolic tangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: atanh(z) z + 1/3*z^3 + 1/5*z^5 + 1/7*z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> atanh(z) z + 1/3*z^3 + 1/5*z^5 + 1/7*z^7 + O(z^8)
arctanh
is an alias:sage: arctanh(z) z + 1/3*z^3 + 1/5*z^5 + 1/7*z^7 + O(z^8) sage: L.<x, y> = LazyPowerSeriesRing(QQ) sage: atanh(x/(1-y)) x + x*y + (1/3*x^3+x*y^2) + (x^3*y+x*y^3) + (1/5*x^5+2*x^3*y^2+x*y^4) + (x^5*y+10/3*x^3*y^3+x*y^5) + (1/7*x^7+3*x^5*y^2+5*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> arctanh(z) z + 1/3*z^3 + 1/5*z^5 + 1/7*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> atanh(x/(Integer(1)-y)) x + x*y + (1/3*x^3+x*y^2) + (x^3*y+x*y^3) + (1/5*x^5+2*x^3*y^2+x*y^4) + (x^5*y+10/3*x^3*y^3+x*y^5) + (1/7*x^7+3*x^5*y^2+5*x^3*y^4+x*y^6) + O(x,y)^8
- change_ring(ring)[source]#
Return
self
with coefficients converted to elements ofring
.INPUT:
ring
– a ring
EXAMPLES:
Dense Implementation:
sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False) sage: s = 2 + z sage: t = s.change_ring(QQ) sage: t^-1 1/2 - 1/4*z + 1/8*z^2 - 1/16*z^3 + 1/32*z^4 - 1/64*z^5 + 1/128*z^6 + O(z^7) sage: M = L(lambda n: n, valuation=0); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: N = M.change_ring(QQ) sage: N.parent() Lazy Laurent Series Ring in z over Rational Field sage: M.parent() Lazy Laurent Series Ring in z over Integer Ring
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, sparse=False, names=('z',)); (z,) = L._first_ngens(1) >>> s = Integer(2) + z >>> t = s.change_ring(QQ) >>> t**-Integer(1) 1/2 - 1/4*z + 1/8*z^2 - 1/16*z^3 + 1/32*z^4 - 1/64*z^5 + 1/128*z^6 + O(z^7) >>> M = L(lambda n: n, valuation=Integer(0)); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> N = M.change_ring(QQ) >>> N.parent() Lazy Laurent Series Ring in z over Rational Field >>> M.parent() Lazy Laurent Series Ring in z over Integer Ring
Sparse Implementation:
sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=True) sage: M = L(lambda n: n, valuation=0); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: M.parent() Lazy Laurent Series Ring in z over Integer Ring sage: N = M.change_ring(QQ) sage: N.parent() Lazy Laurent Series Ring in z over Rational Field sage: M^-1 z^-1 - 2 + z + O(z^6)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, sparse=True, names=('z',)); (z,) = L._first_ngens(1) >>> M = L(lambda n: n, valuation=Integer(0)); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> M.parent() Lazy Laurent Series Ring in z over Integer Ring >>> N = M.change_ring(QQ) >>> N.parent() Lazy Laurent Series Ring in z over Rational Field >>> M**-Integer(1) z^-1 - 2 + z + O(z^6)
A Dirichlet series example:
sage: L = LazyDirichletSeriesRing(ZZ, 'z') sage: s = L(constant=2) sage: t = s.change_ring(QQ) sage: t.parent() Lazy Dirichlet Series Ring in z over Rational Field sage: it = t^-1 sage: it # needs sage.symbolic 1/2 - 1/2/2^z - 1/2/3^z - 1/2/5^z + 1/2/6^z - 1/2/7^z + O(1/(8^z))
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, 'z') >>> s = L(constant=Integer(2)) >>> t = s.change_ring(QQ) >>> t.parent() Lazy Dirichlet Series Ring in z over Rational Field >>> it = t**-Integer(1) >>> it # needs sage.symbolic 1/2 - 1/2/2^z - 1/2/3^z - 1/2/5^z + 1/2/6^z - 1/2/7^z + O(1/(8^z))
A Taylor series example:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: s = 2 + z sage: t = s.change_ring(QQ) sage: t^-1 1/2 - 1/4*z + 1/8*z^2 - 1/16*z^3 + 1/32*z^4 - 1/64*z^5 + 1/128*z^6 + O(z^7) sage: t.parent() Lazy Taylor Series Ring in z over Rational Field
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> s = Integer(2) + z >>> t = s.change_ring(QQ) >>> t**-Integer(1) 1/2 - 1/4*z + 1/8*z^2 - 1/16*z^3 + 1/32*z^4 - 1/64*z^5 + 1/128*z^6 + O(z^7) >>> t.parent() Lazy Taylor Series Ring in z over Rational Field
- coefficient(n)[source]#
Return the homogeneous degree
n
part of the series.INPUT:
n
– integer; the degree
For a series
f
, the slicef[start:stop]
produces the following:if
start
andstop
are integers, return the list of terms with given degreesif
start
isNone
, return the list of terms beginning with the valuationif
stop
isNone
, return alazy_list_generic
instead.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = z / (1 - 2*z^3) sage: [f[n] for n in range(20)] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] sage: f[0:20] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] sage: f[:20] [1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] sage: f[::3] lazy list [1, 2, 4, ...] sage: M = L(lambda n: n, valuation=0) sage: [M[n] for n in range(20)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=True) sage: M = L(lambda n: n, valuation=0) sage: [M[n] for n in range(20)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = z / (Integer(1) - Integer(2)*z**Integer(3)) >>> [f[n] for n in range(Integer(20))] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] >>> f[Integer(0):Integer(20)] [0, 1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] >>> f[:Integer(20)] [1, 0, 0, 2, 0, 0, 4, 0, 0, 8, 0, 0, 16, 0, 0, 32, 0, 0, 64] >>> f[::Integer(3)] lazy list [1, 2, 4, ...] >>> M = L(lambda n: n, valuation=Integer(0)) >>> [M[n] for n in range(Integer(20))] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] >>> L = LazyLaurentSeriesRing(ZZ, sparse=True, names=('z',)); (z,) = L._first_ngens(1) >>> M = L(lambda n: n, valuation=Integer(0)) >>> [M[n] for n in range(Integer(20))] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Similarly for multivariate series:
sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: sin(x*y)[:11] [x*y, 0, 0, 0, -1/6*x^3*y^3, 0, 0, 0, 1/120*x^5*y^5] sage: sin(x*y)[2::4] lazy list [x*y, -1/6*x^3*y^3, 1/120*x^5*y^5, ...]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sin(x*y)[:Integer(11)] [x*y, 0, 0, 0, -1/6*x^3*y^3, 0, 0, 0, 1/120*x^5*y^5] >>> sin(x*y)[Integer(2)::Integer(4)] lazy list [x*y, -1/6*x^3*y^3, 1/120*x^5*y^5, ...]
Similarly for Dirichlet series:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: L(lambda n: n)[1:11] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> L(lambda n: n)[Integer(1):Integer(11)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- coefficients(n=None)[source]#
Return the first \(n\) non-zero coefficients of
self
.INPUT:
n
– (optional) the number of non-zero coefficients to return
If the series has fewer than \(n\) non-zero coefficients, only these are returned.
If
n
isNone
, alazy_list_generic
with all non-zero coefficients is returned instead.Warning
If there are fewer than \(n\) non-zero coefficients, but this cannot be detected, this method will not return.
EXAMPLES:
sage: L.<x> = LazyPowerSeriesRing(QQ) sage: f = L([1,2,3]) sage: f.coefficients(5) doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. See https://github.com/sagemath/sage/issues/32367 for details. [1, 2, 3] sage: f = sin(x) sage: f.coefficients(5) [1, -1/6, 1/120, -1/5040, 1/362880] sage: L.<x, y> = LazyPowerSeriesRing(QQ) sage: f = sin(x^2+y^2) sage: f.coefficients(5) [1, 1, -1/6, -1/2, -1/2] sage: f.coefficients() lazy list [1, 1, -1/6, ...] sage: L.<x> = LazyPowerSeriesRing(GF(2)) sage: f = L(lambda n: n) sage: f.coefficients(5) [1, 1, 1, 1, 1]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> f = L([Integer(1),Integer(2),Integer(3)]) >>> f.coefficients(Integer(5)) doctest:...: DeprecationWarning: the method coefficients now only returns the non-zero coefficients. Use __getitem__ instead. See https://github.com/sagemath/sage/issues/32367 for details. [1, 2, 3] >>> f = sin(x) >>> f.coefficients(Integer(5)) [1, -1/6, 1/120, -1/5040, 1/362880] >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = sin(x**Integer(2)+y**Integer(2)) >>> f.coefficients(Integer(5)) [1, 1, -1/6, -1/2, -1/2] >>> f.coefficients() lazy list [1, 1, -1/6, ...] >>> L = LazyPowerSeriesRing(GF(Integer(2)), names=('x',)); (x,) = L._first_ngens(1) >>> f = L(lambda n: n) >>> f.coefficients(Integer(5)) [1, 1, 1, 1, 1]
- cos()[source]#
Return the cosine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: cos(z) 1 - 1/2*z^2 + 1/24*z^4 - 1/720*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: cos(x/(1-y)).polynomial(4) 1/24*x^4 - 3/2*x^2*y^2 - x^2*y - 1/2*x^2 + 1
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> cos(z) 1 - 1/2*z^2 + 1/24*z^4 - 1/720*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> cos(x/(Integer(1)-y)).polynomial(Integer(4)) 1/24*x^4 - 3/2*x^2*y^2 - x^2*y - 1/2*x^2 + 1
- cosh()[source]#
Return the hyperbolic cosine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: cosh(z) 1 + 1/2*z^2 + 1/24*z^4 + 1/720*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: cosh(x/(1-y)) 1 + 1/2*x^2 + x^2*y + (1/24*x^4+3/2*x^2*y^2) + (1/6*x^4*y+2*x^2*y^3) + (1/720*x^6+5/12*x^4*y^2+5/2*x^2*y^4) + O(x,y)^7
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> cosh(z) 1 + 1/2*z^2 + 1/24*z^4 + 1/720*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> cosh(x/(Integer(1)-y)) 1 + 1/2*x^2 + x^2*y + (1/24*x^4+3/2*x^2*y^2) + (1/6*x^4*y+2*x^2*y^3) + (1/720*x^6+5/12*x^4*y^2+5/2*x^2*y^4) + O(x,y)^7
- cot()[source]#
Return the cotangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: cot(z) z^-1 - 1/3*z - 1/45*z^3 - 2/945*z^5 + O(z^6) sage: L.<x> = LazyLaurentSeriesRing(QQ) sage: cot(x/(1-x)).polynomial(4) x^-1 - 1 - 1/3*x - 1/3*x^2 - 16/45*x^3 - 2/5*x^4
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> cot(z) z^-1 - 1/3*z - 1/45*z^3 - 2/945*z^5 + O(z^6) >>> L = LazyLaurentSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> cot(x/(Integer(1)-x)).polynomial(Integer(4)) x^-1 - 1 - 1/3*x - 1/3*x^2 - 16/45*x^3 - 2/5*x^4
- coth()[source]#
Return the hyperbolic cotangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: coth(z) # needs sage.libs.flint z^-1 + 1/3*z - 1/45*z^3 + 2/945*z^5 + O(z^6) sage: coth(z + z^2) # needs sage.libs.flint z^-1 - 1 + 4/3*z - 2/3*z^2 + 44/45*z^3 - 16/15*z^4 + 884/945*z^5 + O(z^6)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> coth(z) # needs sage.libs.flint z^-1 + 1/3*z - 1/45*z^3 + 2/945*z^5 + O(z^6) >>> coth(z + z**Integer(2)) # needs sage.libs.flint z^-1 - 1 + 4/3*z - 2/3*z^2 + 44/45*z^3 - 16/15*z^4 + 884/945*z^5 + O(z^6)
- csc()[source]#
Return the cosecant of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: csc(z) z^-1 + 1/6*z + 7/360*z^3 + 31/15120*z^5 + O(z^6) sage: L.<x> = LazyLaurentSeriesRing(QQ) sage: csc(x/(1-x)).polynomial(4) x^-1 - 1 + 1/6*x + 1/6*x^2 + 67/360*x^3 + 9/40*x^4
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> csc(z) z^-1 + 1/6*z + 7/360*z^3 + 31/15120*z^5 + O(z^6) >>> L = LazyLaurentSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> csc(x/(Integer(1)-x)).polynomial(Integer(4)) x^-1 - 1 + 1/6*x + 1/6*x^2 + 67/360*x^3 + 9/40*x^4
- csch()[source]#
Return the hyperbolic cosecant of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: csch(z) # needs sage.libs.flint z^-1 - 1/6*z + 7/360*z^3 - 31/15120*z^5 + O(z^6) sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: csch(z/(1-z)) # needs sage.libs.flint z^-1 - 1 - 1/6*z - 1/6*z^2 - 53/360*z^3 - 13/120*z^4 - 787/15120*z^5 + O(z^6)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> csch(z) # needs sage.libs.flint z^-1 - 1/6*z + 7/360*z^3 - 31/15120*z^5 + O(z^6) >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> csch(z/(Integer(1)-z)) # needs sage.libs.flint z^-1 - 1 - 1/6*z - 1/6*z^2 - 53/360*z^3 - 13/120*z^4 - 787/15120*z^5 + O(z^6)
- define(s)[source]#
Define an equation by
self = s
.INPUT:
s
– a lazy series
EXAMPLES:
We begin by constructing the Catalan numbers:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: C = L.undefined() sage: C.define(1 + z*C^2) sage: C 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) sage: binomial(2000, 1000) / C[1000] # needs sage.symbolic 1001
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> C = L.undefined() >>> C.define(Integer(1) + z*C**Integer(2)) >>> C 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) >>> binomial(Integer(2000), Integer(1000)) / C[Integer(1000)] # needs sage.symbolic 1001
The Catalan numbers but with a valuation \(1\):
sage: B = L.undefined(valuation=1) sage: B.define(z + B^2) sage: B z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8)
>>> from sage.all import * >>> B = L.undefined(valuation=Integer(1)) >>> B.define(z + B**Integer(2)) >>> B z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8)
We can define multiple series that are linked:
sage: s = L.undefined() sage: t = L.undefined() sage: s.define(1 + z*t^3) sage: t.define(1 + z*s^2) sage: s[0:9] [1, 1, 3, 9, 34, 132, 546, 2327, 10191] sage: t[0:9] [1, 1, 2, 7, 24, 95, 386, 1641, 7150]
>>> from sage.all import * >>> s = L.undefined() >>> t = L.undefined() >>> s.define(Integer(1) + z*t**Integer(3)) >>> t.define(Integer(1) + z*s**Integer(2)) >>> s[Integer(0):Integer(9)] [1, 1, 3, 9, 34, 132, 546, 2327, 10191] >>> t[Integer(0):Integer(9)] [1, 1, 2, 7, 24, 95, 386, 1641, 7150]
A bigger example:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: A = L.undefined(valuation=5) sage: B = L.undefined() sage: C = L.undefined(valuation=2) sage: A.define(z^5 + B^2) sage: B.define(z^5 + C^2) sage: C.define(z^2 + C^2 + A^2) sage: A[0:15] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] sage: B[0:15] [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] sage: C[0:15] [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> A = L.undefined(valuation=Integer(5)) >>> B = L.undefined() >>> C = L.undefined(valuation=Integer(2)) >>> A.define(z**Integer(5) + B**Integer(2)) >>> B.define(z**Integer(5) + C**Integer(2)) >>> C.define(z**Integer(2) + C**Integer(2) + A**Integer(2)) >>> A[Integer(0):Integer(15)] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] >>> B[Integer(0):Integer(15)] [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] >>> C[Integer(0):Integer(15)] [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142]
Counting binary trees:
sage: L.<z> = LazyPowerSeriesRing(QQ) sage: s = L.undefined(valuation=1) sage: s.define(z + (s^2+s(z^2))/2) sage: s[0:9] [0, 1, 1, 1, 2, 3, 6, 11, 23]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> s = L.undefined(valuation=Integer(1)) >>> s.define(z + (s**Integer(2)+s(z**Integer(2)))/Integer(2)) >>> s[Integer(0):Integer(9)] [0, 1, 1, 1, 2, 3, 6, 11, 23]
The \(q\)-Catalan numbers:
sage: R.<q> = ZZ[] sage: L.<z> = LazyLaurentSeriesRing(R) sage: s = L.undefined(valuation=0) sage: s.define(1+z*s*s(q*z)) sage: s 1 + z + (q + 1)*z^2 + (q^3 + q^2 + 2*q + 1)*z^3 + (q^6 + q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 3*q + 1)*z^4 + (q^10 + q^9 + 2*q^8 + 3*q^7 + 5*q^6 + 5*q^5 + 7*q^4 + 7*q^3 + 6*q^2 + 4*q + 1)*z^5 + (q^15 + q^14 + 2*q^13 + 3*q^12 + 5*q^11 + 7*q^10 + 9*q^9 + 11*q^8 + 14*q^7 + 16*q^6 + 16*q^5 + 17*q^4 + 14*q^3 + 10*q^2 + 5*q + 1)*z^6 + O(z^7)
>>> from sage.all import * >>> R = ZZ['q']; (q,) = R._first_ngens(1) >>> L = LazyLaurentSeriesRing(R, names=('z',)); (z,) = L._first_ngens(1) >>> s = L.undefined(valuation=Integer(0)) >>> s.define(Integer(1)+z*s*s(q*z)) >>> s 1 + z + (q + 1)*z^2 + (q^3 + q^2 + 2*q + 1)*z^3 + (q^6 + q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 3*q + 1)*z^4 + (q^10 + q^9 + 2*q^8 + 3*q^7 + 5*q^6 + 5*q^5 + 7*q^4 + 7*q^3 + 6*q^2 + 4*q + 1)*z^5 + (q^15 + q^14 + 2*q^13 + 3*q^12 + 5*q^11 + 7*q^10 + 9*q^9 + 11*q^8 + 14*q^7 + 16*q^6 + 16*q^5 + 17*q^4 + 14*q^3 + 10*q^2 + 5*q + 1)*z^6 + O(z^7)
We count unlabeled ordered trees by total number of nodes and number of internal nodes:
sage: R.<q> = QQ[] sage: Q.<z> = LazyPowerSeriesRing(R) sage: leaf = z sage: internal_node = q * z sage: L = Q(constant=1, degree=1) sage: T = Q.undefined(valuation=1) sage: T.define(leaf + internal_node * L(T)) sage: T[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q]
>>> from sage.all import * >>> R = QQ['q']; (q,) = R._first_ngens(1) >>> Q = LazyPowerSeriesRing(R, names=('z',)); (z,) = Q._first_ngens(1) >>> leaf = z >>> internal_node = q * z >>> L = Q(constant=Integer(1), degree=Integer(1)) >>> T = Q.undefined(valuation=Integer(1)) >>> T.define(leaf + internal_node * L(T)) >>> T[Integer(0):Integer(6)] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q]
Similarly for Dirichlet series:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: g = L(constant=1, valuation=2) sage: F = L.undefined() sage: F.define(1 + g*F) sage: F[:16] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] sage: oeis(_) # optional - internet 0: A002033: Number of perfect partitions of n. 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... sage: F = L.undefined() sage: F.define(1 + g*F*F) sage: F[:16] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5]
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> g = L(constant=Integer(1), valuation=Integer(2)) >>> F = L.undefined() >>> F.define(Integer(1) + g*F) >>> F[:Integer(16)] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] >>> oeis(_) # optional - internet 0: A002033: Number of perfect partitions of n. 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... >>> F = L.undefined() >>> F.define(Integer(1) + g*F*F) >>> F[:Integer(16)] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5]
We can compute the Frobenius character of unlabeled trees:
sage: # needs sage.combinat sage: m = SymmetricFunctions(QQ).m() sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(m) sage: E = L(lambda n: s[n], valuation=0) sage: X = L(s[1]) sage: A = L.undefined() sage: A.define(X*E(A)) sage: A[:6] [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], 64*m[1, 1, 1, 1] + 34*m[2, 1, 1] + 18*m[2, 2] + 13*m[3, 1] + 4*m[4], 625*m[1, 1, 1, 1, 1] + 326*m[2, 1, 1, 1] + 171*m[2, 2, 1] + 119*m[3, 1, 1] + 63*m[3, 2] + 35*m[4, 1] + 9*m[5]]
>>> from sage.all import * >>> # needs sage.combinat >>> m = SymmetricFunctions(QQ).m() >>> s = SymmetricFunctions(QQ).s() >>> L = LazySymmetricFunctions(m) >>> E = L(lambda n: s[n], valuation=Integer(0)) >>> X = L(s[Integer(1)]) >>> A = L.undefined() >>> A.define(X*E(A)) >>> A[:Integer(6)] [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], 64*m[1, 1, 1, 1] + 34*m[2, 1, 1] + 18*m[2, 2] + 13*m[3, 1] + 4*m[4], 625*m[1, 1, 1, 1, 1] + 326*m[2, 1, 1, 1] + 171*m[2, 2, 1] + 119*m[3, 1, 1] + 63*m[3, 2] + 35*m[4, 1] + 9*m[5]]
- euler()[source]#
Return the Euler function evaluated at
self
.The Euler function is defined as
\[\phi(z) = (z; z)_{\infty} = \sum_{n=0}^{\infty} (-1)^n q^{(3n^2-n)/2}.\]EXAMPLES:
sage: L.<q> = LazyLaurentSeriesRing(ZZ) sage: phi = L.euler() sage: (q + q^2).euler() - phi(q + q^2) O(q^7)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('q',)); (q,) = L._first_ngens(1) >>> phi = L.euler() >>> (q + q**Integer(2)).euler() - phi(q + q**Integer(2)) O(q^7)
- exp()[source]#
Return the exponential series of
self
.EXAMPLES:
sage: L = LazyDirichletSeriesRing(QQ, "s") sage: Z = L(constant=1, valuation=2) sage: exp(Z) # needs sage.symbolic 1 + 1/(2^s) + 1/(3^s) + 3/2/4^s + 1/(5^s) + 2/6^s + 1/(7^s) + O(1/(8^s))
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(QQ, "s") >>> Z = L(constant=Integer(1), valuation=Integer(2)) >>> exp(Z) # needs sage.symbolic 1 + 1/(2^s) + 1/(3^s) + 3/2/4^s + 1/(5^s) + 2/6^s + 1/(7^s) + O(1/(8^s))
- hypergeometric(a, b)[source]#
Return the \({}_{p}F_{q}\)-hypergeometric function \(\,_pF_{q}\) where \((p,q)\) is the parameterization of
self
.INPUT:
a
– the first parameter of the hypergeometric functionb
– the second parameter of the hypergeometric function
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: z.hypergeometric([1, 1], [1]) 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) sage: z.hypergeometric([], []) - exp(z) O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: (x+y).hypergeometric([1, 1], [1]).polynomial(4) x^4 + 4*x^3*y + 6*x^2*y^2 + 4*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 + x^2 + 2*x*y + y^2 + x + y + 1
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> z.hypergeometric([Integer(1), Integer(1)], [Integer(1)]) 1 + z + z^2 + z^3 + z^4 + z^5 + z^6 + O(z^7) >>> z.hypergeometric([], []) - exp(z) O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> (x+y).hypergeometric([Integer(1), Integer(1)], [Integer(1)]).polynomial(Integer(4)) x^4 + 4*x^3*y + 6*x^2*y^2 + 4*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 + x^2 + 2*x*y + y^2 + x + y + 1
- is_nonzero(proof=False)[source]#
Return
True
ifself
is known to be nonzero.INPUT:
proof
– (default:False
) ifTrue
, this will also return an index such thatself
has a nonzero coefficient
Warning
If the stream is exactly zero, this will run forever.
EXAMPLES:
A series that it not known to be nonzero with no halting precision:
sage: L.<z> = LazyLaurentSeriesRing(GF(2)) sage: f = L(lambda n: 0, valuation=0) sage: f.is_nonzero() False sage: bool(f) True sage: g = L(lambda n: 0 if n < 50 else 1, valuation=2) sage: g.is_nonzero() False sage: g[60] 1 sage: g.is_nonzero() True
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(GF(Integer(2)), names=('z',)); (z,) = L._first_ngens(1) >>> f = L(lambda n: Integer(0), valuation=Integer(0)) >>> f.is_nonzero() False >>> bool(f) True >>> g = L(lambda n: Integer(0) if n < Integer(50) else Integer(1), valuation=Integer(2)) >>> g.is_nonzero() False >>> g[Integer(60)] 1 >>> g.is_nonzero() True
With finite halting precision, it can be considered to be indistinguishable from zero until possibly enough coefficients are computed:
sage: L.options.halting_precision = 20 sage: f = L(lambda n: 0, valuation=0) sage: f.is_zero() True sage: g = L(lambda n: 0 if n < 50 else 1, valuation=2) sage: g.is_nonzero() # checks up to degree 22 = 2 + 20 False sage: g.is_nonzero() # checks up to degree 42 = 22 + 20 False sage: g.is_nonzero() # checks up to degree 62 = 42 + 20 True sage: L.options._reset()
>>> from sage.all import * >>> L.options.halting_precision = Integer(20) >>> f = L(lambda n: Integer(0), valuation=Integer(0)) >>> f.is_zero() True >>> g = L(lambda n: Integer(0) if n < Integer(50) else Integer(1), valuation=Integer(2)) >>> g.is_nonzero() # checks up to degree 22 = 2 + 20 False >>> g.is_nonzero() # checks up to degree 42 = 22 + 20 False >>> g.is_nonzero() # checks up to degree 62 = 42 + 20 True >>> L.options._reset()
With a proof:
sage: L.<z> = LazyLaurentSeriesRing(GF(5)) sage: g = L(lambda n: 5 if n < 50 else 1, valuation=2) sage: g.is_nonzero(proof=True) (True, 50) sage: L.zero().is_nonzero(proof=True) (False, None)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(GF(Integer(5)), names=('z',)); (z,) = L._first_ngens(1) >>> g = L(lambda n: Integer(5) if n < Integer(50) else Integer(1), valuation=Integer(2)) >>> g.is_nonzero(proof=True) (True, 50) >>> L.zero().is_nonzero(proof=True) (False, None)
- is_trivial_zero()[source]#
Return whether
self
is known to be trivially zero.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = L(lambda n: 0, valuation=2) sage: f.is_trivial_zero() False sage: L.zero().is_trivial_zero() True
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = L(lambda n: Integer(0), valuation=Integer(2)) >>> f.is_trivial_zero() False >>> L.zero().is_trivial_zero() True
- lift_to_precision(absprec=None)[source]#
Return another element of the same parent with absolute precision at least
absprec
, congruent to this element modulo the precision of this element.Since the precision of a lazy series is infinity, this method returns the series itself, and the argument is ignored.
EXAMPLES:
sage: P.<t> = PowerSeriesRing(QQ, default_prec=2) sage: R.<z> = LazyPowerSeriesRing(P) sage: f = R(lambda n: 1/(1-t)^n) sage: f 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + ((1+3*t+O(t^2))*z^3) + ((1+4*t+O(t^2))*z^4) + ((1+5*t+O(t^2))*z^5) + ((1+6*t+O(t^2))*z^6) + O(z^7) sage: f.lift_to_precision() 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + ((1+3*t+O(t^2))*z^3) + ((1+4*t+O(t^2))*z^4) + ((1+5*t+O(t^2))*z^5) + ((1+6*t+O(t^2))*z^6) + O(z^7)
>>> from sage.all import * >>> P = PowerSeriesRing(QQ, default_prec=Integer(2), names=('t',)); (t,) = P._first_ngens(1) >>> R = LazyPowerSeriesRing(P, names=('z',)); (z,) = R._first_ngens(1) >>> f = R(lambda n: Integer(1)/(Integer(1)-t)**n) >>> f 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + ((1+3*t+O(t^2))*z^3) + ((1+4*t+O(t^2))*z^4) + ((1+5*t+O(t^2))*z^5) + ((1+6*t+O(t^2))*z^6) + O(z^7) >>> f.lift_to_precision() 1 + ((1+t+O(t^2))*z) + ((1+2*t+O(t^2))*z^2) + ((1+3*t+O(t^2))*z^3) + ((1+4*t+O(t^2))*z^4) + ((1+5*t+O(t^2))*z^5) + ((1+6*t+O(t^2))*z^6) + O(z^7)
- log()[source]#
Return the series for the natural logarithm of
self
.EXAMPLES:
sage: L = LazyDirichletSeriesRing(QQ, "s") sage: Z = L(constant=1) sage: log(Z) # needs sage.symbolic 1/(2^s) + 1/(3^s) + 1/2/4^s + 1/(5^s) + 1/(7^s) + O(1/(8^s))
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(QQ, "s") >>> Z = L(constant=Integer(1)) >>> log(Z) # needs sage.symbolic 1/(2^s) + 1/(3^s) + 1/2/4^s + 1/(5^s) + 1/(7^s) + O(1/(8^s))
- map_coefficients(f)[source]#
Return the series with
f
applied to each nonzero coefficient ofself
.INPUT:
func
– function that takes in a coefficient and returns a new coefficient
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: m = L(lambda n: n, valuation=0); m z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: m.map_coefficients(lambda c: c + 1) 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + 8*z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> m = L(lambda n: n, valuation=Integer(0)); m z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> m.map_coefficients(lambda c: c + Integer(1)) 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + 8*z^7 + O(z^8)
Similarly for Dirichlet series:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: s = L(lambda n: n-1) sage: s # needs sage.symbolic 1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z)) sage: ms = s.map_coefficients(lambda c: c + 1) # needs sage.symbolic sage: ms # needs sage.symbolic 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + 8/8^z + O(1/(9^z))
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> s = L(lambda n: n-Integer(1)) >>> s # needs sage.symbolic 1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z)) >>> ms = s.map_coefficients(lambda c: c + Integer(1)) # needs sage.symbolic >>> ms # needs sage.symbolic 2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + 8/8^z + O(1/(9^z))
Similarly for multivariate power series:
sage: L.<x, y> = LazyPowerSeriesRing(QQ) sage: f = 1/(1-(x+y)); f 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 sage: f.map_coefficients(lambda c: c^2) 1 + (x+y) + (x^2+4*x*y+y^2) + (x^3+9*x^2*y+9*x*y^2+y^3) + (x^4+16*x^3*y+36*x^2*y^2+16*x*y^3+y^4) + (x^5+25*x^4*y+100*x^3*y^2+100*x^2*y^3+25*x*y^4+y^5) + (x^6+36*x^5*y+225*x^4*y^2+400*x^3*y^3+225*x^2*y^4+36*x*y^5+y^6) + O(x,y)^7
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = Integer(1)/(Integer(1)-(x+y)); f 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 >>> f.map_coefficients(lambda c: c**Integer(2)) 1 + (x+y) + (x^2+4*x*y+y^2) + (x^3+9*x^2*y+9*x*y^2+y^3) + (x^4+16*x^3*y+36*x^2*y^2+16*x*y^3+y^4) + (x^5+25*x^4*y+100*x^3*y^2+100*x^2*y^3+25*x*y^4+y^5) + (x^6+36*x^5*y+225*x^4*y^2+400*x^3*y^3+225*x^2*y^4+36*x*y^5+y^6) + O(x,y)^7
Similarly for lazy symmetric functions:
sage: # needs sage.combinat sage: p = SymmetricFunctions(QQ).p() sage: L = LazySymmetricFunctions(p) sage: f = 1/(1-2*L(p[1])); f p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 sage: f.map_coefficients(lambda c: log(c, 2)) p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7
>>> from sage.all import * >>> # needs sage.combinat >>> p = SymmetricFunctions(QQ).p() >>> L = LazySymmetricFunctions(p) >>> f = Integer(1)/(Integer(1)-Integer(2)*L(p[Integer(1)])); f p[] + 2*p[1] + (4*p[1,1]) + (8*p[1,1,1]) + (16*p[1,1,1,1]) + (32*p[1,1,1,1,1]) + (64*p[1,1,1,1,1,1]) + O^7 >>> f.map_coefficients(lambda c: log(c, Integer(2))) p[1] + (2*p[1,1]) + (3*p[1,1,1]) + (4*p[1,1,1,1]) + (5*p[1,1,1,1,1]) + (6*p[1,1,1,1,1,1]) + O^7
- prec()[source]#
Return the precision of the series, which is infinity.
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = 1/(1 - z) sage: f.prec() +Infinity
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = Integer(1)/(Integer(1) - z) >>> f.prec() +Infinity
- q_pochhammer(q=None)[source]#
Return the infinite
q
-Pochhammer symbol \((a; q)_{\infty}\), where \(a\) isself
.This is also one version of the quantum dilogarithm or the \(q\)-Exponential function.
INPUT:
q
– (default: \(q \in \QQ(q)\)) the parameter \(q\)
EXAMPLES:
sage: q = ZZ['q'].fraction_field().gen() sage: L.<z> = LazyLaurentSeriesRing(q.parent()) sage: qp = L.q_pochhammer(q) sage: (z + z^2).q_pochhammer(q) - qp(z + z^2) O(z^7)
>>> from sage.all import * >>> q = ZZ['q'].fraction_field().gen() >>> L = LazyLaurentSeriesRing(q.parent(), names=('z',)); (z,) = L._first_ngens(1) >>> qp = L.q_pochhammer(q) >>> (z + z**Integer(2)).q_pochhammer(q) - qp(z + z**Integer(2)) O(z^7)
- sec()[source]#
Return the secant of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: sec(z) 1 + 1/2*z^2 + 5/24*z^4 + 61/720*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: sec(x/(1-y)).polynomial(4) 5/24*x^4 + 3/2*x^2*y^2 + x^2*y + 1/2*x^2 + 1
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> sec(z) 1 + 1/2*z^2 + 5/24*z^4 + 61/720*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sec(x/(Integer(1)-y)).polynomial(Integer(4)) 5/24*x^4 + 3/2*x^2*y^2 + x^2*y + 1/2*x^2 + 1
- sech()[source]#
Return the hyperbolic secant of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: sech(z) # needs sage.libs.flint 1 - 1/2*z^2 + 5/24*z^4 - 61/720*z^6 + O(z^7) sage: L.<x, y> = LazyPowerSeriesRing(QQ) sage: sech(x/(1-y)) # needs sage.libs.flint 1 + (-1/2*x^2) + (-x^2*y) + (5/24*x^4-3/2*x^2*y^2) + (5/6*x^4*y-2*x^2*y^3) + (-61/720*x^6+25/12*x^4*y^2-5/2*x^2*y^4) + O(x,y)^7
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> sech(z) # needs sage.libs.flint 1 - 1/2*z^2 + 5/24*z^4 - 61/720*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sech(x/(Integer(1)-y)) # needs sage.libs.flint 1 + (-1/2*x^2) + (-x^2*y) + (5/24*x^4-3/2*x^2*y^2) + (5/6*x^4*y-2*x^2*y^3) + (-61/720*x^6+25/12*x^4*y^2-5/2*x^2*y^4) + O(x,y)^7
- set(s)[source]#
Define an equation by
self = s
.INPUT:
s
– a lazy series
EXAMPLES:
We begin by constructing the Catalan numbers:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: C = L.undefined() sage: C.define(1 + z*C^2) sage: C 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) sage: binomial(2000, 1000) / C[1000] # needs sage.symbolic 1001
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> C = L.undefined() >>> C.define(Integer(1) + z*C**Integer(2)) >>> C 1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7) >>> binomial(Integer(2000), Integer(1000)) / C[Integer(1000)] # needs sage.symbolic 1001
The Catalan numbers but with a valuation \(1\):
sage: B = L.undefined(valuation=1) sage: B.define(z + B^2) sage: B z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8)
>>> from sage.all import * >>> B = L.undefined(valuation=Integer(1)) >>> B.define(z + B**Integer(2)) >>> B z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8)
We can define multiple series that are linked:
sage: s = L.undefined() sage: t = L.undefined() sage: s.define(1 + z*t^3) sage: t.define(1 + z*s^2) sage: s[0:9] [1, 1, 3, 9, 34, 132, 546, 2327, 10191] sage: t[0:9] [1, 1, 2, 7, 24, 95, 386, 1641, 7150]
>>> from sage.all import * >>> s = L.undefined() >>> t = L.undefined() >>> s.define(Integer(1) + z*t**Integer(3)) >>> t.define(Integer(1) + z*s**Integer(2)) >>> s[Integer(0):Integer(9)] [1, 1, 3, 9, 34, 132, 546, 2327, 10191] >>> t[Integer(0):Integer(9)] [1, 1, 2, 7, 24, 95, 386, 1641, 7150]
A bigger example:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: A = L.undefined(valuation=5) sage: B = L.undefined() sage: C = L.undefined(valuation=2) sage: A.define(z^5 + B^2) sage: B.define(z^5 + C^2) sage: C.define(z^2 + C^2 + A^2) sage: A[0:15] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] sage: B[0:15] [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] sage: C[0:15] [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> A = L.undefined(valuation=Integer(5)) >>> B = L.undefined() >>> C = L.undefined(valuation=Integer(2)) >>> A.define(z**Integer(5) + B**Integer(2)) >>> B.define(z**Integer(5) + C**Integer(2)) >>> C.define(z**Integer(2) + C**Integer(2) + A**Integer(2)) >>> A[Integer(0):Integer(15)] [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] >>> B[Integer(0):Integer(15)] [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] >>> C[Integer(0):Integer(15)] [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142]
Counting binary trees:
sage: L.<z> = LazyPowerSeriesRing(QQ) sage: s = L.undefined(valuation=1) sage: s.define(z + (s^2+s(z^2))/2) sage: s[0:9] [0, 1, 1, 1, 2, 3, 6, 11, 23]
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> s = L.undefined(valuation=Integer(1)) >>> s.define(z + (s**Integer(2)+s(z**Integer(2)))/Integer(2)) >>> s[Integer(0):Integer(9)] [0, 1, 1, 1, 2, 3, 6, 11, 23]
The \(q\)-Catalan numbers:
sage: R.<q> = ZZ[] sage: L.<z> = LazyLaurentSeriesRing(R) sage: s = L.undefined(valuation=0) sage: s.define(1+z*s*s(q*z)) sage: s 1 + z + (q + 1)*z^2 + (q^3 + q^2 + 2*q + 1)*z^3 + (q^6 + q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 3*q + 1)*z^4 + (q^10 + q^9 + 2*q^8 + 3*q^7 + 5*q^6 + 5*q^5 + 7*q^4 + 7*q^3 + 6*q^2 + 4*q + 1)*z^5 + (q^15 + q^14 + 2*q^13 + 3*q^12 + 5*q^11 + 7*q^10 + 9*q^9 + 11*q^8 + 14*q^7 + 16*q^6 + 16*q^5 + 17*q^4 + 14*q^3 + 10*q^2 + 5*q + 1)*z^6 + O(z^7)
>>> from sage.all import * >>> R = ZZ['q']; (q,) = R._first_ngens(1) >>> L = LazyLaurentSeriesRing(R, names=('z',)); (z,) = L._first_ngens(1) >>> s = L.undefined(valuation=Integer(0)) >>> s.define(Integer(1)+z*s*s(q*z)) >>> s 1 + z + (q + 1)*z^2 + (q^3 + q^2 + 2*q + 1)*z^3 + (q^6 + q^5 + 2*q^4 + 3*q^3 + 3*q^2 + 3*q + 1)*z^4 + (q^10 + q^9 + 2*q^8 + 3*q^7 + 5*q^6 + 5*q^5 + 7*q^4 + 7*q^3 + 6*q^2 + 4*q + 1)*z^5 + (q^15 + q^14 + 2*q^13 + 3*q^12 + 5*q^11 + 7*q^10 + 9*q^9 + 11*q^8 + 14*q^7 + 16*q^6 + 16*q^5 + 17*q^4 + 14*q^3 + 10*q^2 + 5*q + 1)*z^6 + O(z^7)
We count unlabeled ordered trees by total number of nodes and number of internal nodes:
sage: R.<q> = QQ[] sage: Q.<z> = LazyPowerSeriesRing(R) sage: leaf = z sage: internal_node = q * z sage: L = Q(constant=1, degree=1) sage: T = Q.undefined(valuation=1) sage: T.define(leaf + internal_node * L(T)) sage: T[0:6] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q]
>>> from sage.all import * >>> R = QQ['q']; (q,) = R._first_ngens(1) >>> Q = LazyPowerSeriesRing(R, names=('z',)); (z,) = Q._first_ngens(1) >>> leaf = z >>> internal_node = q * z >>> L = Q(constant=Integer(1), degree=Integer(1)) >>> T = Q.undefined(valuation=Integer(1)) >>> T.define(leaf + internal_node * L(T)) >>> T[Integer(0):Integer(6)] [0, 1, q, q^2 + q, q^3 + 3*q^2 + q, q^4 + 6*q^3 + 6*q^2 + q]
Similarly for Dirichlet series:
sage: L = LazyDirichletSeriesRing(ZZ, "z") sage: g = L(constant=1, valuation=2) sage: F = L.undefined() sage: F.define(1 + g*F) sage: F[:16] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] sage: oeis(_) # optional - internet 0: A002033: Number of perfect partitions of n. 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... sage: F = L.undefined() sage: F.define(1 + g*F*F) sage: F[:16] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5]
>>> from sage.all import * >>> L = LazyDirichletSeriesRing(ZZ, "z") >>> g = L(constant=Integer(1), valuation=Integer(2)) >>> F = L.undefined() >>> F.define(Integer(1) + g*F) >>> F[:Integer(16)] [1, 1, 1, 2, 1, 3, 1, 4, 2, 3, 1, 8, 1, 3, 3] >>> oeis(_) # optional - internet 0: A002033: Number of perfect partitions of n. 1: A074206: Kalmár's [Kalmar's] problem: number of ordered factorizations of n. ... >>> F = L.undefined() >>> F.define(Integer(1) + g*F*F) >>> F[:Integer(16)] [1, 1, 1, 3, 1, 5, 1, 10, 3, 5, 1, 24, 1, 5, 5]
We can compute the Frobenius character of unlabeled trees:
sage: # needs sage.combinat sage: m = SymmetricFunctions(QQ).m() sage: s = SymmetricFunctions(QQ).s() sage: L = LazySymmetricFunctions(m) sage: E = L(lambda n: s[n], valuation=0) sage: X = L(s[1]) sage: A = L.undefined() sage: A.define(X*E(A)) sage: A[:6] [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], 64*m[1, 1, 1, 1] + 34*m[2, 1, 1] + 18*m[2, 2] + 13*m[3, 1] + 4*m[4], 625*m[1, 1, 1, 1, 1] + 326*m[2, 1, 1, 1] + 171*m[2, 2, 1] + 119*m[3, 1, 1] + 63*m[3, 2] + 35*m[4, 1] + 9*m[5]]
>>> from sage.all import * >>> # needs sage.combinat >>> m = SymmetricFunctions(QQ).m() >>> s = SymmetricFunctions(QQ).s() >>> L = LazySymmetricFunctions(m) >>> E = L(lambda n: s[n], valuation=Integer(0)) >>> X = L(s[Integer(1)]) >>> A = L.undefined() >>> A.define(X*E(A)) >>> A[:Integer(6)] [m[1], 2*m[1, 1] + m[2], 9*m[1, 1, 1] + 5*m[2, 1] + 2*m[3], 64*m[1, 1, 1, 1] + 34*m[2, 1, 1] + 18*m[2, 2] + 13*m[3, 1] + 4*m[4], 625*m[1, 1, 1, 1, 1] + 326*m[2, 1, 1, 1] + 171*m[2, 2, 1] + 119*m[3, 1, 1] + 63*m[3, 2] + 35*m[4, 1] + 9*m[5]]
- shift(n)[source]#
Return
self
with the indices shifted byn
.For example, a Laurent series is multiplied by the power \(z^n\), where \(z\) is the variable of
self
. For series with a fixed minimal valuation (e.g., power series), this removes any terms that are less than the minimal valuation.INPUT:
n
– the amount to shift
EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(ZZ) sage: f = 1 / (1 + 2*z) sage: f 1 - 2*z + 4*z^2 - 8*z^3 + 16*z^4 - 32*z^5 + 64*z^6 + O(z^7) sage: f.shift(3) z^3 - 2*z^4 + 4*z^5 - 8*z^6 + 16*z^7 - 32*z^8 + 64*z^9 + O(z^10) sage: f << -3 # shorthand z^-3 - 2*z^-2 + 4*z^-1 - 8 + 16*z - 32*z^2 + 64*z^3 + O(z^4) sage: g = z^-3 + 3 + z^2 sage: g.shift(5) z^2 + 3*z^5 + z^7 sage: L([2,0,3], valuation=2, degree=7, constant=1) << -2 2 + 3*z^2 + z^5 + z^6 + z^7 + O(z^8) sage: D = LazyDirichletSeriesRing(QQ, 't') sage: f = D([0,1,2]) sage: f # needs sage.symbolic 1/(2^t) + 2/3^t sage: sf = f.shift(3) sage: sf # needs sage.symbolic 1/(5^t) + 2/6^t
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) + Integer(2)*z) >>> f 1 - 2*z + 4*z^2 - 8*z^3 + 16*z^4 - 32*z^5 + 64*z^6 + O(z^7) >>> f.shift(Integer(3)) z^3 - 2*z^4 + 4*z^5 - 8*z^6 + 16*z^7 - 32*z^8 + 64*z^9 + O(z^10) >>> f << -Integer(3) # shorthand z^-3 - 2*z^-2 + 4*z^-1 - 8 + 16*z - 32*z^2 + 64*z^3 + O(z^4) >>> g = z**-Integer(3) + Integer(3) + z**Integer(2) >>> g.shift(Integer(5)) z^2 + 3*z^5 + z^7 >>> L([Integer(2),Integer(0),Integer(3)], valuation=Integer(2), degree=Integer(7), constant=Integer(1)) << -Integer(2) 2 + 3*z^2 + z^5 + z^6 + z^7 + O(z^8) >>> D = LazyDirichletSeriesRing(QQ, 't') >>> f = D([Integer(0),Integer(1),Integer(2)]) >>> f # needs sage.symbolic 1/(2^t) + 2/3^t >>> sf = f.shift(Integer(3)) >>> sf # needs sage.symbolic 1/(5^t) + 2/6^t
Examples with power series (where the minimal valuation is \(0\)):
sage: L.<x> = LazyPowerSeriesRing(QQ) sage: f = 1 / (1 - x) sage: f.shift(2) x^2 + x^3 + x^4 + O(x^5) sage: g = f.shift(-1); g 1 + x + x^2 + O(x^3) sage: f == g True sage: g[-1] 0 sage: h = L(lambda n: 1) sage: LazyPowerSeriesRing.options.halting_precision(20) # verify up to degree 20 sage: f == h True sage: h == f True sage: h.shift(-1) == h True sage: LazyPowerSeriesRing.options._reset() sage: fp = L([3,3,3], constant=1) sage: fp.shift(2) 3*x^2 + 3*x^3 + 3*x^4 + x^5 + x^6 + x^7 + O(x^8) sage: fp.shift(-2) 3 + x + x^2 + x^3 + O(x^4) sage: fp.shift(-7) 1 + x + x^2 + O(x^3) sage: fp.shift(-5) == g True
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) - x) >>> f.shift(Integer(2)) x^2 + x^3 + x^4 + O(x^5) >>> g = f.shift(-Integer(1)); g 1 + x + x^2 + O(x^3) >>> f == g True >>> g[-Integer(1)] 0 >>> h = L(lambda n: Integer(1)) >>> LazyPowerSeriesRing.options.halting_precision(Integer(20)) # verify up to degree 20 >>> f == h True >>> h == f True >>> h.shift(-Integer(1)) == h True >>> LazyPowerSeriesRing.options._reset() >>> fp = L([Integer(3),Integer(3),Integer(3)], constant=Integer(1)) >>> fp.shift(Integer(2)) 3*x^2 + 3*x^3 + 3*x^4 + x^5 + x^6 + x^7 + O(x^8) >>> fp.shift(-Integer(2)) 3 + x + x^2 + x^3 + O(x^4) >>> fp.shift(-Integer(7)) 1 + x + x^2 + O(x^3) >>> fp.shift(-Integer(5)) == g True
We compare the shifting with converting to the fraction field (see also Issue #35293):
sage: M = L.fraction_field() sage: f = L([1,2,3,4]); f 1 + 2*x + 3*x^2 + 4*x^3 sage: f.shift(-3) 4 sage: M(f).shift(-3) x^-3 + 2*x^-2 + 3*x^-1 + 4
>>> from sage.all import * >>> M = L.fraction_field() >>> f = L([Integer(1),Integer(2),Integer(3),Integer(4)]); f 1 + 2*x + 3*x^2 + 4*x^3 >>> f.shift(-Integer(3)) 4 >>> M(f).shift(-Integer(3)) x^-3 + 2*x^-2 + 3*x^-1 + 4
An example with a more general function:
sage: fun = lambda n: 1 if ZZ(n).is_power_of(2) else 0 sage: f = L(fun); f x + x^2 + x^4 + O(x^7) sage: fs = f.shift(-4) sage: fs 1 + x^4 + O(x^7) sage: fs.shift(4) x^4 + x^8 + O(x^11) sage: M(f).shift(-4) x^-3 + x^-2 + 1 + O(x^4)
>>> from sage.all import * >>> fun = lambda n: Integer(1) if ZZ(n).is_power_of(Integer(2)) else Integer(0) >>> f = L(fun); f x + x^2 + x^4 + O(x^7) >>> fs = f.shift(-Integer(4)) >>> fs 1 + x^4 + O(x^7) >>> fs.shift(Integer(4)) x^4 + x^8 + O(x^11) >>> M(f).shift(-Integer(4)) x^-3 + x^-2 + 1 + O(x^4)
- sin()[source]#
Return the sine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: sin(z) z - 1/6*z^3 + 1/120*z^5 - 1/5040*z^7 + O(z^8) sage: sin(1 + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: sin(x/(1-y)).polynomial(3) -1/6*x^3 + x*y^2 + x*y + x
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> sin(z) z - 1/6*z^3 + 1/120*z^5 - 1/5040*z^7 + O(z^8) >>> sin(Integer(1) + z) Traceback (most recent call last): ... ValueError: can only compose with a positive valuation series >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sin(x/(Integer(1)-y)).polynomial(Integer(3)) -1/6*x^3 + x*y^2 + x*y + x
- sinh()[source]#
Return the hyperbolic sine of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: sinh(z) z + 1/6*z^3 + 1/120*z^5 + 1/5040*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: sinh(x/(1-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (1/120*x^5+x^3*y^2+x*y^4) + (1/24*x^5*y+5/3*x^3*y^3+x*y^5) + (1/5040*x^7+1/8*x^5*y^2+5/2*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> sinh(z) z + 1/6*z^3 + 1/120*z^5 + 1/5040*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sinh(x/(Integer(1)-y)) x + x*y + (1/6*x^3+x*y^2) + (1/2*x^3*y+x*y^3) + (1/120*x^5+x^3*y^2+x*y^4) + (1/24*x^5*y+5/3*x^3*y^3+x*y^5) + (1/5040*x^7+1/8*x^5*y^2+5/2*x^3*y^4+x*y^6) + O(x,y)^8
- sqrt()[source]#
Return
self^(1/2)
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: sqrt(1+z) 1 + 1/2*z - 1/8*z^2 + 1/16*z^3 - 5/128*z^4 + 7/256*z^5 - 21/1024*z^6 + O(z^7) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: sqrt(1+x/(1-y)) 1 + 1/2*x + (-1/8*x^2+1/2*x*y) + (1/16*x^3-1/4*x^2*y+1/2*x*y^2) + (-5/128*x^4+3/16*x^3*y-3/8*x^2*y^2+1/2*x*y^3) + (7/256*x^5-5/32*x^4*y+3/8*x^3*y^2-1/2*x^2*y^3+1/2*x*y^4) + (-21/1024*x^6+35/256*x^5*y-25/64*x^4*y^2+5/8*x^3*y^3-5/8*x^2*y^4+1/2*x*y^5) + O(x,y)^7
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> sqrt(Integer(1)+z) 1 + 1/2*z - 1/8*z^2 + 1/16*z^3 - 5/128*z^4 + 7/256*z^5 - 21/1024*z^6 + O(z^7) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> sqrt(Integer(1)+x/(Integer(1)-y)) 1 + 1/2*x + (-1/8*x^2+1/2*x*y) + (1/16*x^3-1/4*x^2*y+1/2*x*y^2) + (-5/128*x^4+3/16*x^3*y-3/8*x^2*y^2+1/2*x*y^3) + (7/256*x^5-5/32*x^4*y+3/8*x^3*y^2-1/2*x^2*y^3+1/2*x*y^4) + (-21/1024*x^6+35/256*x^5*y-25/64*x^4*y^2+5/8*x^3*y^3-5/8*x^2*y^4+1/2*x*y^5) + O(x,y)^7
This also works for Dirichlet series:
sage: # needs sage.symbolic sage: D = LazyDirichletSeriesRing(SR, "s") sage: Z = D(constant=1) sage: f = sqrt(Z); f 1 + 1/2/2^s + 1/2/3^s + 3/8/4^s + 1/2/5^s + 1/4/6^s + 1/2/7^s + O(1/(8^s)) sage: f*f - Z O(1/(8^s))
>>> from sage.all import * >>> # needs sage.symbolic >>> D = LazyDirichletSeriesRing(SR, "s") >>> Z = D(constant=Integer(1)) >>> f = sqrt(Z); f 1 + 1/2/2^s + 1/2/3^s + 3/8/4^s + 1/2/5^s + 1/4/6^s + 1/2/7^s + O(1/(8^s)) >>> f*f - Z O(1/(8^s))
- tan()[source]#
Return the tangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: tan(z) z + 1/3*z^3 + 2/15*z^5 + 17/315*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: tan(x/(1-y)).polynomial(5) 2/15*x^5 + 2*x^3*y^2 + x*y^4 + x^3*y + x*y^3 + 1/3*x^3 + x*y^2 + x*y + x
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> tan(z) z + 1/3*z^3 + 2/15*z^5 + 17/315*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> tan(x/(Integer(1)-y)).polynomial(Integer(5)) 2/15*x^5 + 2*x^3*y^2 + x*y^4 + x^3*y + x*y^3 + 1/3*x^3 + x*y^2 + x*y + x
- tanh()[source]#
Return the hyperbolic tangent of
self
.EXAMPLES:
sage: L.<z> = LazyLaurentSeriesRing(QQ) sage: tanh(z) # needs sage.libs.flint z - 1/3*z^3 + 2/15*z^5 - 17/315*z^7 + O(z^8) sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: tanh(x/(1-y)) # needs sage.libs.flint x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (2/15*x^5-2*x^3*y^2+x*y^4) + (2/3*x^5*y-10/3*x^3*y^3+x*y^5) + (-17/315*x^7+2*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> tanh(z) # needs sage.libs.flint z - 1/3*z^3 + 2/15*z^5 - 17/315*z^7 + O(z^8) >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> tanh(x/(Integer(1)-y)) # needs sage.libs.flint x + x*y + (-1/3*x^3+x*y^2) + (-x^3*y+x*y^3) + (2/15*x^5-2*x^3*y^2+x*y^4) + (2/3*x^5*y-10/3*x^3*y^3+x*y^5) + (-17/315*x^7+2*x^5*y^2-5*x^3*y^4+x*y^6) + O(x,y)^8
- truncate(d)[source]#
Return the series obtained by removing all terms of degree at least
d
.INPUT:
d
– integer; the degree from which the series is truncated
EXAMPLES:
Dense implementation:
sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False) sage: alpha = 1/(1-z) sage: alpha 1 + z + z^2 + O(z^3) sage: beta = alpha.truncate(5) sage: beta 1 + z + z^2 + z^3 + z^4 sage: alpha - beta z^5 + z^6 + z^7 + O(z^8) sage: M = L(lambda n: n, valuation=0); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: M.truncate(4) z + 2*z^2 + 3*z^3
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, sparse=False, names=('z',)); (z,) = L._first_ngens(1) >>> alpha = Integer(1)/(Integer(1)-z) >>> alpha 1 + z + z^2 + O(z^3) >>> beta = alpha.truncate(Integer(5)) >>> beta 1 + z + z^2 + z^3 + z^4 >>> alpha - beta z^5 + z^6 + z^7 + O(z^8) >>> M = L(lambda n: n, valuation=Integer(0)); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> M.truncate(Integer(4)) z + 2*z^2 + 3*z^3
Sparse Implementation:
sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=True) sage: M = L(lambda n: n, valuation=0); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) sage: M.truncate(4) z + 2*z^2 + 3*z^3
>>> from sage.all import * >>> L = LazyLaurentSeriesRing(ZZ, sparse=True, names=('z',)); (z,) = L._first_ngens(1) >>> M = L(lambda n: n, valuation=Integer(0)); M z + 2*z^2 + 3*z^3 + 4*z^4 + 5*z^5 + 6*z^6 + O(z^7) >>> M.truncate(Integer(4)) z + 2*z^2 + 3*z^3
Series which are known to be exact can also be truncated:
sage: M = z + z^2 + z^3 + z^4 sage: M.truncate(4) z + z^2 + z^3
>>> from sage.all import * >>> M = z + z**Integer(2) + z**Integer(3) + z**Integer(4) >>> M.truncate(Integer(4)) z + z^2 + z^3
- class sage.rings.lazy_series.LazyPowerSeries(parent, coeff_stream)[source]#
Bases:
LazyCauchyProductSeries
A Taylor series where the coefficients are computed lazily.
EXAMPLES:
sage: L.<x, y> = LazyPowerSeriesRing(ZZ) sage: f = 1 / (1 - x^2 + y^3); f 1 + x^2 + (-y^3) + x^4 + (-2*x^2*y^3) + (x^6+y^6) + O(x,y)^7 sage: P.<x, y> = PowerSeriesRing(ZZ, default_prec=101) sage: g = 1 / (1 - x^2 + y^3); f[100] - g[100] 0
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = Integer(1) / (Integer(1) - x**Integer(2) + y**Integer(3)); f 1 + x^2 + (-y^3) + x^4 + (-2*x^2*y^3) + (x^6+y^6) + O(x,y)^7 >>> P = PowerSeriesRing(ZZ, default_prec=Integer(101), names=('x', 'y',)); (x, y,) = P._first_ngens(2) >>> g = Integer(1) / (Integer(1) - x**Integer(2) + y**Integer(3)); f[Integer(100)] - g[Integer(100)] 0
Lazy Taylor series is picklable:
sage: g = loads(dumps(f)) sage: g 1 + x^2 + (-y^3) + x^4 + (-2*x^2*y^3) + (x^6+y^6) + O(x,y)^7 sage: g == f True
>>> from sage.all import * >>> g = loads(dumps(f)) >>> g 1 + x^2 + (-y^3) + x^4 + (-2*x^2*y^3) + (x^6+y^6) + O(x,y)^7 >>> g == f True
- O(prec)[source]#
Return the power series of precision at most
prec
obtained by adding \(O(q^\text{prec})\) to \(f\), where \(q\) is the (tuple of) variable(s).EXAMPLES:
sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: f = 1 / (1 - x + y) sage: f 1 + (x-y) + (x^2-2*x*y+y^2) + (x^3-3*x^2*y+3*x*y^2-y^3) + (x^4-4*x^3*y+6*x^2*y^2-4*x*y^3+y^4) + (x^5-5*x^4*y+10*x^3*y^2-10*x^2*y^3+5*x*y^4-y^5) + (x^6-6*x^5*y+15*x^4*y^2-20*x^3*y^3+15*x^2*y^4-6*x*y^5+y^6) + O(x,y)^7 sage: f3 = f.add_bigoh(3); f3 1 + x - y + x^2 - 2*x*y + y^2 + O(x, y)^3 sage: f3.parent() Multivariate Power Series Ring in x, y over Rational Field sage: R.<t> = QQ[] sage: L.<x> = LazyPowerSeriesRing(R) sage: f = 1 / (1 - t^3*x) sage: f 1 + t^3*x + t^6*x^2 + t^9*x^3 + t^12*x^4 + t^15*x^5 + t^18*x^6 + O(x^7) sage: f3 = f.add_bigoh(3); f3 1 + t^3*x + t^6*x^2 + O(x^3) sage: f3.parent() Power Series Ring in x over Univariate Polynomial Ring in t over Rational Field
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = Integer(1) / (Integer(1) - x + y) >>> f 1 + (x-y) + (x^2-2*x*y+y^2) + (x^3-3*x^2*y+3*x*y^2-y^3) + (x^4-4*x^3*y+6*x^2*y^2-4*x*y^3+y^4) + (x^5-5*x^4*y+10*x^3*y^2-10*x^2*y^3+5*x*y^4-y^5) + (x^6-6*x^5*y+15*x^4*y^2-20*x^3*y^3+15*x^2*y^4-6*x*y^5+y^6) + O(x,y)^7 >>> f3 = f.add_bigoh(Integer(3)); f3 1 + x - y + x^2 - 2*x*y + y^2 + O(x, y)^3 >>> f3.parent() Multivariate Power Series Ring in x, y over Rational Field >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> L = LazyPowerSeriesRing(R, names=('x',)); (x,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) - t**Integer(3)*x) >>> f 1 + t^3*x + t^6*x^2 + t^9*x^3 + t^12*x^4 + t^15*x^5 + t^18*x^6 + O(x^7) >>> f3 = f.add_bigoh(Integer(3)); f3 1 + t^3*x + t^6*x^2 + O(x^3) >>> f3.parent() Power Series Ring in x over Univariate Polynomial Ring in t over Rational Field
- adams_operator(p)[source]#
Return the image of
self
under the Adams operator of indexp
.This raises all variables to the power
p
, both the power series variables and the variables inside the coefficient ring.INPUT:
p
– a positive integer
EXAMPLES:
With no variables in the base ring:
sage: A = LazyPowerSeriesRing(QQ,'t') sage: f = A([1,2,3,4]); f 1 + 2*t + 3*t^2 + 4*t^3 sage: f.adams_operator(2) 1 + 2*t^2 + 3*t^4 + 4*t^6
>>> from sage.all import * >>> A = LazyPowerSeriesRing(QQ,'t') >>> f = A([Integer(1),Integer(2),Integer(3),Integer(4)]); f 1 + 2*t + 3*t^2 + 4*t^3 >>> f.adams_operator(Integer(2)) 1 + 2*t^2 + 3*t^4 + 4*t^6
With variables in the base ring:
sage: q = polygen(QQ,'q') sage: A = LazyPowerSeriesRing(q.parent(),'t') sage: f = A([0,1+q,2,3+q**2]); f ((q+1)*t) + 2*t^2 + ((q^2+3)*t^3) sage: f.adams_operator(2) ((q^2+1)*t^2) + 2*t^4 + ((q^4+3)*t^6)
>>> from sage.all import * >>> q = polygen(QQ,'q') >>> A = LazyPowerSeriesRing(q.parent(),'t') >>> f = A([Integer(0),Integer(1)+q,Integer(2),Integer(3)+q**Integer(2)]); f ((q+1)*t) + 2*t^2 + ((q^2+3)*t^3) >>> f.adams_operator(Integer(2)) ((q^2+1)*t^2) + 2*t^4 + ((q^4+3)*t^6)
In the multivariate case:
sage: A = LazyPowerSeriesRing(ZZ,'t,u') sage: f = A({(1,2):4,(2,3):6}); f 4*t*u^2 + 6*t^2*u^3 sage: f.adams_operator(3) 4*t^3*u^6 + 6*t^6*u^9
>>> from sage.all import * >>> A = LazyPowerSeriesRing(ZZ,'t,u') >>> f = A({(Integer(1),Integer(2)):Integer(4),(Integer(2),Integer(3)):Integer(6)}); f 4*t*u^2 + 6*t^2*u^3 >>> f.adams_operator(Integer(3)) 4*t^3*u^6 + 6*t^6*u^9
- add_bigoh(prec)[source]#
Return the power series of precision at most
prec
obtained by adding \(O(q^\text{prec})\) to \(f\), where \(q\) is the (tuple of) variable(s).EXAMPLES:
sage: L.<x,y> = LazyPowerSeriesRing(QQ) sage: f = 1 / (1 - x + y) sage: f 1 + (x-y) + (x^2-2*x*y+y^2) + (x^3-3*x^2*y+3*x*y^2-y^3) + (x^4-4*x^3*y+6*x^2*y^2-4*x*y^3+y^4) + (x^5-5*x^4*y+10*x^3*y^2-10*x^2*y^3+5*x*y^4-y^5) + (x^6-6*x^5*y+15*x^4*y^2-20*x^3*y^3+15*x^2*y^4-6*x*y^5+y^6) + O(x,y)^7 sage: f3 = f.add_bigoh(3); f3 1 + x - y + x^2 - 2*x*y + y^2 + O(x, y)^3 sage: f3.parent() Multivariate Power Series Ring in x, y over Rational Field sage: R.<t> = QQ[] sage: L.<x> = LazyPowerSeriesRing(R) sage: f = 1 / (1 - t^3*x) sage: f 1 + t^3*x + t^6*x^2 + t^9*x^3 + t^12*x^4 + t^15*x^5 + t^18*x^6 + O(x^7) sage: f3 = f.add_bigoh(3); f3 1 + t^3*x + t^6*x^2 + O(x^3) sage: f3.parent() Power Series Ring in x over Univariate Polynomial Ring in t over Rational Field
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = Integer(1) / (Integer(1) - x + y) >>> f 1 + (x-y) + (x^2-2*x*y+y^2) + (x^3-3*x^2*y+3*x*y^2-y^3) + (x^4-4*x^3*y+6*x^2*y^2-4*x*y^3+y^4) + (x^5-5*x^4*y+10*x^3*y^2-10*x^2*y^3+5*x*y^4-y^5) + (x^6-6*x^5*y+15*x^4*y^2-20*x^3*y^3+15*x^2*y^4-6*x*y^5+y^6) + O(x,y)^7 >>> f3 = f.add_bigoh(Integer(3)); f3 1 + x - y + x^2 - 2*x*y + y^2 + O(x, y)^3 >>> f3.parent() Multivariate Power Series Ring in x, y over Rational Field >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> L = LazyPowerSeriesRing(R, names=('x',)); (x,) = L._first_ngens(1) >>> f = Integer(1) / (Integer(1) - t**Integer(3)*x) >>> f 1 + t^3*x + t^6*x^2 + t^9*x^3 + t^12*x^4 + t^15*x^5 + t^18*x^6 + O(x^7) >>> f3 = f.add_bigoh(Integer(3)); f3 1 + t^3*x + t^6*x^2 + O(x^3) >>> f3.parent() Power Series Ring in x over Univariate Polynomial Ring in t over Rational Field
- compose(*g)[source]#
Return the composition of
self
withg
.The arity of
self
must be equal to the number of arguments provided.Given a Taylor series \(f\) of arity \(n\) and a tuple of Taylor series \(g = (g_1,\dots, g_n)\) over the same base ring, the composition \(f \circ g\) is defined if and only if for each \(1\leq i\leq n\):
\(g_i\) is zero, or
setting all variables except the \(i\)-th in \(f\) to zero yields a polynomial, or
\(\mathrm{val}(g_i) > 0\).
If \(f\) is a univariate ‘exact’ series, we can check whether \(f\) is a actually a polynomial. However, if \(f\) is a multivariate series, we have no way to test whether setting all but one variable of \(f\) to zero yields a polynomial, except if \(f\) itself is ‘exact’ and therefore a polynomial.
INPUT:
g
– other series, all can be coerced into the same parent
EXAMPLES:
sage: L.<x, y, z> = LazyPowerSeriesRing(QQ) sage: M.<a, b> = LazyPowerSeriesRing(ZZ) sage: g1 = 1 / (1 - x) sage: g2 = x + y^2 sage: p = a^2 + b + 1 sage: p(g1, g2) - g1^2 - g2 - 1 O(x,y,z)^7
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3) >>> M = LazyPowerSeriesRing(ZZ, names=('a', 'b',)); (a, b,) = M._first_ngens(2) >>> g1 = Integer(1) / (Integer(1) - x) >>> g2 = x + y**Integer(2) >>> p = a**Integer(2) + b + Integer(1) >>> p(g1, g2) - g1**Integer(2) - g2 - Integer(1) O(x,y,z)^7
The number of mappings from a set with \(m\) elements to a set with \(n\) elements:
sage: M.<a> = LazyPowerSeriesRing(QQ) sage: Ea = M(lambda n: 1/factorial(n)) sage: Ex = L(lambda n: 1/factorial(n)*x^n) sage: Ea(Ex*y)[5] 1/24*x^4*y + 2/3*x^3*y^2 + 3/4*x^2*y^3 + 1/6*x*y^4 + 1/120*y^5
>>> from sage.all import * >>> M = LazyPowerSeriesRing(QQ, names=('a',)); (a,) = M._first_ngens(1) >>> Ea = M(lambda n: Integer(1)/factorial(n)) >>> Ex = L(lambda n: Integer(1)/factorial(n)*x**n) >>> Ea(Ex*y)[Integer(5)] 1/24*x^4*y + 2/3*x^3*y^2 + 3/4*x^2*y^3 + 1/6*x*y^4 + 1/120*y^5
So, there are \(3! 2! 2/3 = 8\) mappings from a three element set to a two element set.
We perform the composition with a lazy Laurent series:
sage: N.<w> = LazyLaurentSeriesRing(QQ) sage: f1 = 1 / (1 - w) sage: f2 = cot(w / (1 - w)) sage: p(f1, f2) w^-1 + 1 + 5/3*w + 8/3*w^2 + 164/45*w^3 + 23/5*w^4 + 5227/945*w^5 + O(w^6)
>>> from sage.all import * >>> N = LazyLaurentSeriesRing(QQ, names=('w',)); (w,) = N._first_ngens(1) >>> f1 = Integer(1) / (Integer(1) - w) >>> f2 = cot(w / (Integer(1) - w)) >>> p(f1, f2) w^-1 + 1 + 5/3*w + 8/3*w^2 + 164/45*w^3 + 23/5*w^4 + 5227/945*w^5 + O(w^6)
We perform the composition with a lazy Dirichlet series:
sage: # needs sage.symbolic sage: D = LazyDirichletSeriesRing(QQ, "s") sage: g = D(constant=1)-1 sage: g 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) sage: f = 1 / (1 - x - y*z); f 1 + x + (x^2+y*z) + (x^3+2*x*y*z) + (x^4+3*x^2*y*z+y^2*z^2) + (x^5+4*x^3*y*z+3*x*y^2*z^2) + (x^6+5*x^4*y*z+6*x^2*y^2*z^2+y^3*z^3) + O(x,y,z)^7 sage: fog = f(g, g, g) sage: fog 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + O(1/(7^s)) sage: fg = 1 / (1 - g - g*g) sage: fg 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + 1/(7^s) + O(1/(8^s)) sage: fog - fg O(1/(8^s)) sage: f = 1 / (1 - 2*a) sage: f(g) # needs sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s)) sage: 1 / (1 - 2*g) # needs sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s))
>>> from sage.all import * >>> # needs sage.symbolic >>> D = LazyDirichletSeriesRing(QQ, "s") >>> g = D(constant=Integer(1))-Integer(1) >>> g 1/(2^s) + 1/(3^s) + 1/(4^s) + O(1/(5^s)) >>> f = Integer(1) / (Integer(1) - x - y*z); f 1 + x + (x^2+y*z) + (x^3+2*x*y*z) + (x^4+3*x^2*y*z+y^2*z^2) + (x^5+4*x^3*y*z+3*x*y^2*z^2) + (x^6+5*x^4*y*z+6*x^2*y^2*z^2+y^3*z^3) + O(x,y,z)^7 >>> fog = f(g, g, g) >>> fog 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + O(1/(7^s)) >>> fg = Integer(1) / (Integer(1) - g - g*g) >>> fg 1 + 1/(2^s) + 1/(3^s) + 3/4^s + 1/(5^s) + 5/6^s + 1/(7^s) + O(1/(8^s)) >>> fog - fg O(1/(8^s)) >>> f = Integer(1) / (Integer(1) - Integer(2)*a) >>> f(g) # needs sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s)) >>> Integer(1) / (Integer(1) - Integer(2)*g) # needs sage.symbolic 1 + 2/2^s + 2/3^s + 6/4^s + 2/5^s + 10/6^s + 2/7^s + O(1/(8^s))
The output parent is always the common parent between the base ring of \(f\) and the parent of \(g\) or extended to the corresponding lazy series:
sage: T.<x,y> = LazyPowerSeriesRing(QQ) sage: R.<a,b,c> = ZZ[] sage: S.<v> = R[] sage: L.<z> = LaurentPolynomialRing(ZZ) sage: parent(x(a, b)) Multivariate Polynomial Ring in a, b, c over Rational Field sage: parent(x(CC(2), a)) Multivariate Polynomial Ring in a, b, c over Complex Field with 53 bits of precision sage: parent(x(0, 0)) Rational Field sage: f = 1 / (1 - x - y); f 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 sage: f(a^2, b*c) 1 + (a^2+b*c) + (a^4+2*a^2*b*c+b^2*c^2) + (a^6+3*a^4*b*c+3*a^2*b^2*c^2+b^3*c^3) + O(a,b,c)^7 sage: f(v, v^2) 1 + v + 2*v^2 + 3*v^3 + 5*v^4 + 8*v^5 + 13*v^6 + O(v^7) sage: f(z, z^2 + z) 1 + 2*z + 5*z^2 + 12*z^3 + 29*z^4 + 70*z^5 + 169*z^6 + O(z^7) sage: three = T(3)(a^2, b); three 3 sage: parent(three) Multivariate Polynomial Ring in a, b, c over Rational Field
>>> from sage.all import * >>> T = LazyPowerSeriesRing(QQ, names=('x', 'y',)); (x, y,) = T._first_ngens(2) >>> R = ZZ['a, b, c']; (a, b, c,) = R._first_ngens(3) >>> S = R['v']; (v,) = S._first_ngens(1) >>> L = LaurentPolynomialRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> parent(x(a, b)) Multivariate Polynomial Ring in a, b, c over Rational Field >>> parent(x(CC(Integer(2)), a)) Multivariate Polynomial Ring in a, b, c over Complex Field with 53 bits of precision >>> parent(x(Integer(0), Integer(0))) Rational Field >>> f = Integer(1) / (Integer(1) - x - y); f 1 + (x+y) + (x^2+2*x*y+y^2) + (x^3+3*x^2*y+3*x*y^2+y^3) + (x^4+4*x^3*y+6*x^2*y^2+4*x*y^3+y^4) + (x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5) + (x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6) + O(x,y)^7 >>> f(a**Integer(2), b*c) 1 + (a^2+b*c) + (a^4+2*a^2*b*c+b^2*c^2) + (a^6+3*a^4*b*c+3*a^2*b^2*c^2+b^3*c^3) + O(a,b,c)^7 >>> f(v, v**Integer(2)) 1 + v + 2*v^2 + 3*v^3 + 5*v^4 + 8*v^5 + 13*v^6 + O(v^7) >>> f(z, z**Integer(2) + z) 1 + 2*z + 5*z^2 + 12*z^3 + 29*z^4 + 70*z^5 + 169*z^6 + O(z^7) >>> three = T(Integer(3))(a**Integer(2), b); three 3 >>> parent(three) Multivariate Polynomial Ring in a, b, c over Rational Field
- compositional_inverse()[source]#
Return the compositional inverse of
self
.Given a Taylor series \(f\) in one variable, the compositional inverse is a power series \(g\) over the same base ring, such that \((f \circ g)(z) = f(g(z)) = z\).
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b z\) with \(a, b \neq 0\).
EXAMPLES:
sage: L.<z> = LazyPowerSeriesRing(QQ) sage: (2*z).revert() 1/2*z sage: (z-z^2).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) sage: s = L(degree=1, constant=-1) sage: s.revert() -z - z^2 - z^3 + O(z^4) sage: s = L(degree=1, constant=1) sage: s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).revert() 1/2*z >>> (z-z**Integer(2)).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) >>> s = L(degree=Integer(1), constant=-Integer(1)) >>> s.revert() -z - z^2 - z^3 + O(z^4) >>> s = L(degree=Integer(1), constant=Integer(1)) >>> s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
Warning
For series not known to be eventually constant (e.g., being defined by a function) with approximate valuation \(\leq 1\) (but not necessarily its true valuation), this assumes that this is the actual valuation:
sage: f = L(lambda n: n if n > 2 else 0) sage: f.revert() <repr(... failed: ValueError: generator already executing>
>>> from sage.all import * >>> f = L(lambda n: n if n > Integer(2) else Integer(0)) >>> f.revert() <repr(... failed: ValueError: generator already executing>
- compute_coefficients(i)[source]#
Computes all the coefficients of
self
up toi
.This method is deprecated, it has no effect anymore.
- derivative(*args)[source]#
Return the derivative of the Taylor series.
Multiple variables and iteration counts may be supplied; see the documentation of
sage.calculus.functional.derivative()
function for details.EXAMPLES:
sage: T.<z> = LazyPowerSeriesRing(ZZ) sage: z.derivative() 1 sage: (1 + z + z^2).derivative(3) 0 sage: (z^2 + z^4 + z^10).derivative(3) 24*z + 720*z^7 sage: (1 / (1-z)).derivative() 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) sage: T([1, 1, 1], constant=4).derivative() 1 + 2*z + 12*z^2 + 16*z^3 + 20*z^4 + 24*z^5 + 28*z^6 + O(z^7) sage: R.<q> = QQ[] sage: L.<x, y> = LazyPowerSeriesRing(R) sage: f = 1 / (1-q*x+y); f 1 + (q*x-y) + (q^2*x^2+(-2*q)*x*y+y^2) + (q^3*x^3+(-3*q^2)*x^2*y+3*q*x*y^2-y^3) + (q^4*x^4+(-4*q^3)*x^3*y+6*q^2*x^2*y^2+(-4*q)*x*y^3+y^4) + (q^5*x^5+(-5*q^4)*x^4*y+10*q^3*x^3*y^2+(-10*q^2)*x^2*y^3+5*q*x*y^4-y^5) + (q^6*x^6+(-6*q^5)*x^5*y+15*q^4*x^4*y^2+(-20*q^3)*x^3*y^3+15*q^2*x^2*y^4+(-6*q)*x*y^5+y^6) + O(x,y)^7 sage: f.derivative(q) x + (2*q*x^2+(-2)*x*y) + (3*q^2*x^3+(-6*q)*x^2*y+3*x*y^2) + (4*q^3*x^4+(-12*q^2)*x^3*y+12*q*x^2*y^2+(-4)*x*y^3) + (5*q^4*x^5+(-20*q^3)*x^4*y+30*q^2*x^3*y^2+(-20*q)*x^2*y^3+5*x*y^4) + (6*q^5*x^6+(-30*q^4)*x^5*y+60*q^3*x^4*y^2+(-60*q^2)*x^3*y^3+30*q*x^2*y^4+(-6)*x*y^5) + O(x,y)^7
>>> from sage.all import * >>> T = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = T._first_ngens(1) >>> z.derivative() 1 >>> (Integer(1) + z + z**Integer(2)).derivative(Integer(3)) 0 >>> (z**Integer(2) + z**Integer(4) + z**Integer(10)).derivative(Integer(3)) 24*z + 720*z^7 >>> (Integer(1) / (Integer(1)-z)).derivative() 1 + 2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7) >>> T([Integer(1), Integer(1), Integer(1)], constant=Integer(4)).derivative() 1 + 2*z + 12*z^2 + 16*z^3 + 20*z^4 + 24*z^5 + 28*z^6 + O(z^7) >>> R = QQ['q']; (q,) = R._first_ngens(1) >>> L = LazyPowerSeriesRing(R, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = Integer(1) / (Integer(1)-q*x+y); f 1 + (q*x-y) + (q^2*x^2+(-2*q)*x*y+y^2) + (q^3*x^3+(-3*q^2)*x^2*y+3*q*x*y^2-y^3) + (q^4*x^4+(-4*q^3)*x^3*y+6*q^2*x^2*y^2+(-4*q)*x*y^3+y^4) + (q^5*x^5+(-5*q^4)*x^4*y+10*q^3*x^3*y^2+(-10*q^2)*x^2*y^3+5*q*x*y^4-y^5) + (q^6*x^6+(-6*q^5)*x^5*y+15*q^4*x^4*y^2+(-20*q^3)*x^3*y^3+15*q^2*x^2*y^4+(-6*q)*x*y^5+y^6) + O(x,y)^7 >>> f.derivative(q) x + (2*q*x^2+(-2)*x*y) + (3*q^2*x^3+(-6*q)*x^2*y+3*x*y^2) + (4*q^3*x^4+(-12*q^2)*x^3*y+12*q*x^2*y^2+(-4)*x*y^3) + (5*q^4*x^5+(-20*q^3)*x^4*y+30*q^2*x^3*y^2+(-20*q)*x^2*y^3+5*x*y^4) + (6*q^5*x^6+(-30*q^4)*x^5*y+60*q^3*x^4*y^2+(-60*q^2)*x^3*y^3+30*q*x^2*y^4+(-6)*x*y^5) + O(x,y)^7
Multivariate:
sage: L.<x,y,z> = LazyPowerSeriesRing(QQ) sage: f = (x + y^2 + z)^3; f (x^3+3*x^2*z+3*x*z^2+z^3) + (3*x^2*y^2+6*x*y^2*z+3*y^2*z^2) + (3*x*y^4+3*y^4*z) + y^6 sage: f.derivative(x) (3*x^2+6*x*z+3*z^2) + (6*x*y^2+6*y^2*z) + 3*y^4 sage: f.derivative(y, 5) 720*y sage: f.derivative(z, 5) 0 sage: f.derivative(x, y, z) 12*y sage: f = (1 + x + y^2 + z)^-1 sage: f.derivative(x) -1 + (2*x+2*z) + (-3*x^2+2*y^2-6*x*z-3*z^2) + ... + O(x,y,z)^6 sage: f.derivative(y, 2) -2 + (4*x+4*z) + (-6*x^2+12*y^2-12*x*z-6*z^2) + ... + O(x,y,z)^5 sage: f.derivative(x, y) 4*y + (-12*x*y-12*y*z) + (24*x^2*y-12*y^3+48*x*y*z+24*y*z^2) + (-40*x^3*y+48*x*y^3-120*x^2*y*z+48*y^3*z-120*x*y*z^2-40*y*z^3) + O(x,y,z)^5 sage: f.derivative(x, y, z) (-12*y) + (48*x*y+48*y*z) + (-120*x^2*y+48*y^3-240*x*y*z-120*y*z^2) + O(x,y,z)^4 sage: R.<t> = QQ[] sage: L.<x,y,z> = LazyPowerSeriesRing(R) sage: f = ((t^2-3)*x + t*y^2 - t*z)^2 sage: f.derivative(t,x,t,y) 24*t*y sage: f.derivative(t, 2) ((12*t^2-12)*x^2+(-12*t)*x*z+2*z^2) + (12*t*x*y^2+(-4)*y^2*z) + 2*y^4 sage: f.derivative(z, t) ((-6*t^2+6)*x+4*t*z) + ((-4*t)*y^2) sage: f.derivative(t, 10) 0 sage: f = (1 + t*(x + y + z))^-1 sage: f.derivative(x, t, y) 4*t + ((-18*t^2)*x+(-18*t^2)*y+(-18*t^2)*z) + (48*t^3*x^2+96*t^3*x*y+48*t^3*y^2+96*t^3*x*z+96*t^3*y*z+48*t^3*z^2) + ... + O(x,y,z)^5 sage: f.derivative(t, 2) (2*x^2+4*x*y+2*y^2+4*x*z+4*y*z+2*z^2) + ... + O(x,y,z)^7 sage: f.derivative(x, y, z, t) (-18*t^2) + (96*t^3*x+96*t^3*y+96*t^3*z) + ... + O(x,y,z)^4
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3) >>> f = (x + y**Integer(2) + z)**Integer(3); f (x^3+3*x^2*z+3*x*z^2+z^3) + (3*x^2*y^2+6*x*y^2*z+3*y^2*z^2) + (3*x*y^4+3*y^4*z) + y^6 >>> f.derivative(x) (3*x^2+6*x*z+3*z^2) + (6*x*y^2+6*y^2*z) + 3*y^4 >>> f.derivative(y, Integer(5)) 720*y >>> f.derivative(z, Integer(5)) 0 >>> f.derivative(x, y, z) 12*y >>> f = (Integer(1) + x + y**Integer(2) + z)**-Integer(1) >>> f.derivative(x) -1 + (2*x+2*z) + (-3*x^2+2*y^2-6*x*z-3*z^2) + ... + O(x,y,z)^6 >>> f.derivative(y, Integer(2)) -2 + (4*x+4*z) + (-6*x^2+12*y^2-12*x*z-6*z^2) + ... + O(x,y,z)^5 >>> f.derivative(x, y) 4*y + (-12*x*y-12*y*z) + (24*x^2*y-12*y^3+48*x*y*z+24*y*z^2) + (-40*x^3*y+48*x*y^3-120*x^2*y*z+48*y^3*z-120*x*y*z^2-40*y*z^3) + O(x,y,z)^5 >>> f.derivative(x, y, z) (-12*y) + (48*x*y+48*y*z) + (-120*x^2*y+48*y^3-240*x*y*z-120*y*z^2) + O(x,y,z)^4 >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> L = LazyPowerSeriesRing(R, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3) >>> f = ((t**Integer(2)-Integer(3))*x + t*y**Integer(2) - t*z)**Integer(2) >>> f.derivative(t,x,t,y) 24*t*y >>> f.derivative(t, Integer(2)) ((12*t^2-12)*x^2+(-12*t)*x*z+2*z^2) + (12*t*x*y^2+(-4)*y^2*z) + 2*y^4 >>> f.derivative(z, t) ((-6*t^2+6)*x+4*t*z) + ((-4*t)*y^2) >>> f.derivative(t, Integer(10)) 0 >>> f = (Integer(1) + t*(x + y + z))**-Integer(1) >>> f.derivative(x, t, y) 4*t + ((-18*t^2)*x+(-18*t^2)*y+(-18*t^2)*z) + (48*t^3*x^2+96*t^3*x*y+48*t^3*y^2+96*t^3*x*z+96*t^3*y*z+48*t^3*z^2) + ... + O(x,y,z)^5 >>> f.derivative(t, Integer(2)) (2*x^2+4*x*y+2*y^2+4*x*z+4*y*z+2*z^2) + ... + O(x,y,z)^7 >>> f.derivative(x, y, z, t) (-18*t^2) + (96*t^3*x+96*t^3*y+96*t^3*z) + ... + O(x,y,z)^4
- exponential()[source]#
Return the exponential series of
self
.This method is deprecated, use
exp()
instead.
- integral(variable, constants=None)[source]#
Return the integral of
self
with respect tovariable
.INPUT:
variable
– (optional) the variable to integrateconstants
– (optional; keyword-only) list of integration constants for the integrals ofself
(the last constant corresponds to the first integral)
For multivariable series, only
variable
should be specified; the integration constant is taken to be \(0\).Now we assume the series is univariate. If the first argument is a list, then this method iterprets it as integration constants. If it is a positive integer, the method interprets it as the number of times to integrate the function. If
variable
is not the variable of the power series, then the coefficients are integrated with respect tovariable
. If the integration constants are not specified, they are considered to be \(0\).EXAMPLES:
sage: L.<t> = LazyPowerSeriesRing(QQ) sage: f = 2 + 3*t + t^5 sage: f.integral() 2*t + 3/2*t^2 + 1/6*t^6 sage: f.integral([-2, -2]) -2 - 2*t + t^2 + 1/2*t^3 + 1/42*t^7 sage: f.integral(t) 2*t + 3/2*t^2 + 1/6*t^6 sage: f.integral(2) t^2 + 1/2*t^3 + 1/42*t^7 sage: (t^3 + t^5).integral() 1/4*t^4 + 1/6*t^6 sage: L.zero().integral() 0 sage: L.zero().integral([0, 1, 2, 3]) t + t^2 + 1/2*t^3 sage: L([1, 2 ,3], constant=4).integral() t + t^2 + t^3 + t^4 + 4/5*t^5 + 2/3*t^6 + O(t^7)
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('t',)); (t,) = L._first_ngens(1) >>> f = Integer(2) + Integer(3)*t + t**Integer(5) >>> f.integral() 2*t + 3/2*t^2 + 1/6*t^6 >>> f.integral([-Integer(2), -Integer(2)]) -2 - 2*t + t^2 + 1/2*t^3 + 1/42*t^7 >>> f.integral(t) 2*t + 3/2*t^2 + 1/6*t^6 >>> f.integral(Integer(2)) t^2 + 1/2*t^3 + 1/42*t^7 >>> (t**Integer(3) + t**Integer(5)).integral() 1/4*t^4 + 1/6*t^6 >>> L.zero().integral() 0 >>> L.zero().integral([Integer(0), Integer(1), Integer(2), Integer(3)]) t + t^2 + 1/2*t^3 >>> L([Integer(1), Integer(2) ,Integer(3)], constant=Integer(4)).integral() t + t^2 + t^3 + t^4 + 4/5*t^5 + 2/3*t^6 + O(t^7)
We solve the ODE \(f'' - f' - 2 f = 0\) by solving for \(f''\), then integrating and applying a recursive definition:
sage: R.<C, D> = QQ[] sage: L.<x> = LazyPowerSeriesRing(R) sage: f = L.undefined() sage: f.define((f.derivative() + 2*f).integral(constants=[C, D])) sage: f C + D*x + ((C+1/2*D)*x^2) + ((1/3*C+1/2*D)*x^3) + ((1/4*C+5/24*D)*x^4) + ((1/12*C+11/120*D)*x^5) + ((11/360*C+7/240*D)*x^6) + O(x^7) sage: f.derivative(2) - f.derivative() - 2*f O(x^7)
>>> from sage.all import * >>> R = QQ['C, D']; (C, D,) = R._first_ngens(2) >>> L = LazyPowerSeriesRing(R, names=('x',)); (x,) = L._first_ngens(1) >>> f = L.undefined() >>> f.define((f.derivative() + Integer(2)*f).integral(constants=[C, D])) >>> f C + D*x + ((C+1/2*D)*x^2) + ((1/3*C+1/2*D)*x^3) + ((1/4*C+5/24*D)*x^4) + ((1/12*C+11/120*D)*x^5) + ((11/360*C+7/240*D)*x^6) + O(x^7) >>> f.derivative(Integer(2)) - f.derivative() - Integer(2)*f O(x^7)
We compare this with the answer we get from the characteristic polynomial:
sage: g = C * exp(-x) + D * exp(2*x); g (C+D) + ((-C+2*D)*x) + ((1/2*C+2*D)*x^2) + ((-1/6*C+4/3*D)*x^3) + ((1/24*C+2/3*D)*x^4) + ((-1/120*C+4/15*D)*x^5) + ((1/720*C+4/45*D)*x^6) + O(x^7) sage: g.derivative(2) - g.derivative() - 2*g O(x^7)
>>> from sage.all import * >>> g = C * exp(-x) + D * exp(Integer(2)*x); g (C+D) + ((-C+2*D)*x) + ((1/2*C+2*D)*x^2) + ((-1/6*C+4/3*D)*x^3) + ((1/24*C+2/3*D)*x^4) + ((-1/120*C+4/15*D)*x^5) + ((1/720*C+4/45*D)*x^6) + O(x^7) >>> g.derivative(Integer(2)) - g.derivative() - Integer(2)*g O(x^7)
Note that
C
andD
are playing different roles, so we need to perform a substitution to the coefficients off
to recover the solutiong
:sage: fp = f.map_coefficients(lambda c: c(C=C+D, D=2*D-C)); fp (C+D) + ((-C+2*D)*x) + ((1/2*C+2*D)*x^2) + ((-1/6*C+4/3*D)*x^3) + ((1/24*C+2/3*D)*x^4) + ((-1/120*C+4/15*D)*x^5) + ((1/720*C+4/45*D)*x^6) + O(x^7) sage: fp - g O(x^7)
>>> from sage.all import * >>> fp = f.map_coefficients(lambda c: c(C=C+D, D=Integer(2)*D-C)); fp (C+D) + ((-C+2*D)*x) + ((1/2*C+2*D)*x^2) + ((-1/6*C+4/3*D)*x^3) + ((1/24*C+2/3*D)*x^4) + ((-1/120*C+4/15*D)*x^5) + ((1/720*C+4/45*D)*x^6) + O(x^7) >>> fp - g O(x^7)
We can integrate both the series and coefficients:
sage: R.<x,y,z> = QQ[] sage: L.<t> = LazyPowerSeriesRing(R) sage: f = (x*t^2 + y*t + z)^2; f z^2 + 2*y*z*t + ((y^2+2*x*z)*t^2) + 2*x*y*t^3 + x^2*t^4 sage: f.integral(x) x*z^2 + 2*x*y*z*t + ((x*y^2+x^2*z)*t^2) + x^2*y*t^3 + 1/3*x^3*t^4 sage: f.integral(t) z^2*t + y*z*t^2 + ((1/3*y^2+2/3*x*z)*t^3) + 1/2*x*y*t^4 + 1/5*x^2*t^5 sage: f.integral(y, constants=[x*y*z]) x*y*z + y*z^2*t + 1/2*y^2*z*t^2 + ((1/9*y^3+2/3*x*y*z)*t^3) + 1/4*x*y^2*t^4 + 1/5*x^2*y*t^5
>>> from sage.all import * >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3) >>> L = LazyPowerSeriesRing(R, names=('t',)); (t,) = L._first_ngens(1) >>> f = (x*t**Integer(2) + y*t + z)**Integer(2); f z^2 + 2*y*z*t + ((y^2+2*x*z)*t^2) + 2*x*y*t^3 + x^2*t^4 >>> f.integral(x) x*z^2 + 2*x*y*z*t + ((x*y^2+x^2*z)*t^2) + x^2*y*t^3 + 1/3*x^3*t^4 >>> f.integral(t) z^2*t + y*z*t^2 + ((1/3*y^2+2/3*x*z)*t^3) + 1/2*x*y*t^4 + 1/5*x^2*t^5 >>> f.integral(y, constants=[x*y*z]) x*y*z + y*z^2*t + 1/2*y^2*z*t^2 + ((1/9*y^3+2/3*x*y*z)*t^3) + 1/4*x*y^2*t^4 + 1/5*x^2*y*t^5
We can integrate multivariate power series:
sage: R.<t> = QQ[] sage: L.<x,y,z> = LazyPowerSeriesRing(R) sage: f = ((t^2 + t) - t * y^2 + t^2 * (y + z))^2; f (t^4+2*t^3+t^2) + ((2*t^4+2*t^3)*y+(2*t^4+2*t^3)*z) + ((t^4-2*t^3-2*t^2)*y^2+2*t^4*y*z+t^4*z^2) + ((-2*t^3)*y^3+(-2*t^3)*y^2*z) + t^2*y^4 sage: g = f.integral(x); g ((t^4+2*t^3+t^2)*x) + ((2*t^4+2*t^3)*x*y+(2*t^4+2*t^3)*x*z) + ((t^4-2*t^3-2*t^2)*x*y^2+2*t^4*x*y*z+t^4*x*z^2) + ((-2*t^3)*x*y^3+(-2*t^3)*x*y^2*z) + t^2*x*y^4 sage: g[0] 0 sage: g[1] (t^4 + 2*t^3 + t^2)*x sage: g[2] (2*t^4 + 2*t^3)*x*y + (2*t^4 + 2*t^3)*x*z sage: f.integral(z) ((t^4+2*t^3+t^2)*z) + ((2*t^4+2*t^3)*y*z+(t^4+t^3)*z^2) + ((t^4-2*t^3-2*t^2)*y^2*z+t^4*y*z^2+1/3*t^4*z^3) + ((-2*t^3)*y^3*z+(-t^3)*y^2*z^2) + t^2*y^4*z sage: f.integral(t) (1/5*t^5+1/2*t^4+1/3*t^3) + ((2/5*t^5+1/2*t^4)*y+(2/5*t^5+1/2*t^4)*z) + ((1/5*t^5-1/2*t^4-2/3*t^3)*y^2+2/5*t^5*y*z+1/5*t^5*z^2) + ((-1/2*t^4)*y^3+(-1/2*t^4)*y^2*z) + 1/3*t^3*y^4 sage: L.<x,y,z> = LazyPowerSeriesRing(QQ) sage: (x + y - z^2).integral(z) (x*z+y*z) + (-1/3*z^3)
>>> from sage.all import * >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> L = LazyPowerSeriesRing(R, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3) >>> f = ((t**Integer(2) + t) - t * y**Integer(2) + t**Integer(2) * (y + z))**Integer(2); f (t^4+2*t^3+t^2) + ((2*t^4+2*t^3)*y+(2*t^4+2*t^3)*z) + ((t^4-2*t^3-2*t^2)*y^2+2*t^4*y*z+t^4*z^2) + ((-2*t^3)*y^3+(-2*t^3)*y^2*z) + t^2*y^4 >>> g = f.integral(x); g ((t^4+2*t^3+t^2)*x) + ((2*t^4+2*t^3)*x*y+(2*t^4+2*t^3)*x*z) + ((t^4-2*t^3-2*t^2)*x*y^2+2*t^4*x*y*z+t^4*x*z^2) + ((-2*t^3)*x*y^3+(-2*t^3)*x*y^2*z) + t^2*x*y^4 >>> g[Integer(0)] 0 >>> g[Integer(1)] (t^4 + 2*t^3 + t^2)*x >>> g[Integer(2)] (2*t^4 + 2*t^3)*x*y + (2*t^4 + 2*t^3)*x*z >>> f.integral(z) ((t^4+2*t^3+t^2)*z) + ((2*t^4+2*t^3)*y*z+(t^4+t^3)*z^2) + ((t^4-2*t^3-2*t^2)*y^2*z+t^4*y*z^2+1/3*t^4*z^3) + ((-2*t^3)*y^3*z+(-t^3)*y^2*z^2) + t^2*y^4*z >>> f.integral(t) (1/5*t^5+1/2*t^4+1/3*t^3) + ((2/5*t^5+1/2*t^4)*y+(2/5*t^5+1/2*t^4)*z) + ((1/5*t^5-1/2*t^4-2/3*t^3)*y^2+2/5*t^5*y*z+1/5*t^5*z^2) + ((-1/2*t^4)*y^3+(-1/2*t^4)*y^2*z) + 1/3*t^3*y^4 >>> L = LazyPowerSeriesRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = L._first_ngens(3) >>> (x + y - z**Integer(2)).integral(z) (x*z+y*z) + (-1/3*z^3)
- is_unit()[source]#
Return whether this element is a unit in the ring.
EXAMPLES:
sage: L.<z> = LazyPowerSeriesRing(ZZ) sage: (2*z).is_unit() False sage: (1 + 2*z).is_unit() True sage: (3 + 2*z).is_unit() False sage: L.<x,y> = LazyPowerSeriesRing(ZZ) sage: (-1 + 2*x + 3*x*y).is_unit() True
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).is_unit() False >>> (Integer(1) + Integer(2)*z).is_unit() True >>> (Integer(3) + Integer(2)*z).is_unit() False >>> L = LazyPowerSeriesRing(ZZ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> (-Integer(1) + Integer(2)*x + Integer(3)*x*y).is_unit() True
- polynomial(degree=None, names=None)[source]#
Return
self
as a polynomial ifself
is actually so.INPUT:
degree
–None
or an integernames
– names of the variables; if it isNone
, the name of the variables of the series is used
OUTPUT:
If
degree
is notNone
, the terms of the series of degree greater thandegree
are first truncated. Ifdegree
isNone
and the series is not a polynomial polynomial, aValueError
is raised.EXAMPLES:
sage: L.<x,y> = LazyPowerSeriesRing(ZZ) sage: f = x^2 + y*x - x + 2; f 2 + (-x) + (x^2+x*y) sage: f.polynomial() x^2 + x*y - x + 2
>>> from sage.all import * >>> L = LazyPowerSeriesRing(ZZ, names=('x', 'y',)); (x, y,) = L._first_ngens(2) >>> f = x**Integer(2) + y*x - x + Integer(2); f 2 + (-x) + (x^2+x*y) >>> f.polynomial() x^2 + x*y - x + 2
- revert()[source]#
Return the compositional inverse of
self
.Given a Taylor series \(f\) in one variable, the compositional inverse is a power series \(g\) over the same base ring, such that \((f \circ g)(z) = f(g(z)) = z\).
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b z\) with \(a, b \neq 0\).
EXAMPLES:
sage: L.<z> = LazyPowerSeriesRing(QQ) sage: (2*z).revert() 1/2*z sage: (z-z^2).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) sage: s = L(degree=1, constant=-1) sage: s.revert() -z - z^2 - z^3 + O(z^4) sage: s = L(degree=1, constant=1) sage: s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('z',)); (z,) = L._first_ngens(1) >>> (Integer(2)*z).revert() 1/2*z >>> (z-z**Integer(2)).revert() z + z^2 + 2*z^3 + 5*z^4 + 14*z^5 + 42*z^6 + 132*z^7 + O(z^8) >>> s = L(degree=Integer(1), constant=-Integer(1)) >>> s.revert() -z - z^2 - z^3 + O(z^4) >>> s = L(degree=Integer(1), constant=Integer(1)) >>> s.revert() z - z^2 + z^3 - z^4 + z^5 - z^6 + z^7 + O(z^8)
Warning
For series not known to be eventually constant (e.g., being defined by a function) with approximate valuation \(\leq 1\) (but not necessarily its true valuation), this assumes that this is the actual valuation:
sage: f = L(lambda n: n if n > 2 else 0) sage: f.revert() <repr(... failed: ValueError: generator already executing>
>>> from sage.all import * >>> f = L(lambda n: n if n > Integer(2) else Integer(0)) >>> f.revert() <repr(... failed: ValueError: generator already executing>
- class sage.rings.lazy_series.LazyPowerSeries_gcd_mixin[source]#
Bases:
object
A lazy power series that also implements the GCD algorithm.
- gcd(other)[source]#
Return the greatest common divisor of
self
andother
.EXAMPLES:
sage: L.<x> = LazyPowerSeriesRing(QQ) sage: a = 16*x^5 / (1 - 5*x) sage: b = (22*x^2 + x^8) / (1 - 4*x^2) sage: a.gcd(b) x^2
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> a = Integer(16)*x**Integer(5) / (Integer(1) - Integer(5)*x) >>> b = (Integer(22)*x**Integer(2) + x**Integer(8)) / (Integer(1) - Integer(4)*x**Integer(2)) >>> a.gcd(b) x^2
- xgcd(f)[source]#
Return the extended gcd of
self
andf
.OUTPUT:
A triple
(g, s, t)
such thatg
is the gcd ofself
andf
, ands
andt
are cofactors satisfying the Bezout identity\[g = s \cdot \mathrm{self} + t \cdot f.\]EXAMPLES:
sage: L.<x> = LazyPowerSeriesRing(QQ) sage: a = 16*x^5 / (1 - 2*x) sage: b = (22*x^3 + x^8) / (1 - 3*x^2) sage: g, s, t = a.xgcd(b) sage: g x^3 sage: s 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) sage: t 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) sage: LazyPowerSeriesRing.options.halting_precision(20) # verify up to degree 20 sage: g == s * a + t * b True sage: a = 16*x^5 / (1 - 2*x) sage: b = (-16*x^5 + x^8) / (1 - 3*x^2) sage: g, s, t = a.xgcd(b) sage: g x^5 sage: s 1/16 - 1/16*x - 3/16*x^2 + 1/8*x^3 - 17/256*x^4 + 9/128*x^5 + 1/128*x^6 + O(x^7) sage: t 1/16*x - 1/16*x^2 - 3/16*x^3 + 1/8*x^4 - 17/256*x^5 + 9/128*x^6 + 1/128*x^7 + O(x^8) sage: g == s * a + t * b True sage: # needs sage.rings.finite_rings sage: L.<x> = LazyPowerSeriesRing(GF(2)) sage: a = L(lambda n: n % 2, valuation=3); a x^3 + x^5 + x^7 + x^9 + O(x^10) sage: b = L(lambda n: binomial(n,2) % 2, valuation=3); b x^3 + x^6 + x^7 + O(x^10) sage: g, s, t = a.xgcd(b) sage: g x^3 sage: s 1 + x + x^3 + x^4 + x^5 + O(x^7) sage: t x + x^2 + x^4 + x^5 + x^6 + O(x^8) sage: g == s * a + t * b True sage: LazyPowerSeriesRing.options._reset() # reset the options
>>> from sage.all import * >>> L = LazyPowerSeriesRing(QQ, names=('x',)); (x,) = L._first_ngens(1) >>> a = Integer(16)*x**Integer(5) / (Integer(1) - Integer(2)*x) >>> b = (Integer(22)*x**Integer(3) + x**Integer(8)) / (Integer(1) - Integer(3)*x**Integer(2)) >>> g, s, t = a.xgcd(b) >>> g x^3 >>> s 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) >>> t 1/22 - 41/242*x^2 - 8/121*x^3 + 120/1331*x^4 + 1205/5324*x^5 + 316/14641*x^6 + O(x^7) >>> LazyPowerSeriesRing.options.halting_precision(Integer(20)) # verify up to degree 20 >>> g == s * a + t * b True >>> a = Integer(16)*x**Integer(5) / (Integer(1) - Integer(2)*x) >>> b = (-Integer(16)*x**Integer(5) + x**Integer(8)) / (Integer(1) - Integer(3)*x**Integer(2)) >>> g, s, t = a.xgcd(b) >>> g x^5 >>> s 1/16 - 1/16*x - 3/16*x^2 + 1/8*x^3 - 17/256*x^4 + 9/128*x^5 + 1/128*x^6 + O(x^7) >>> t 1/16*x - 1/16*x^2 - 3/16*x^3 + 1/8*x^4 - 17/256*x^5 + 9/128*x^6 + 1/128*x^7 + O(x^8) >>> g == s * a + t * b True >>> # needs sage.rings.finite_rings >>> L = LazyPowerSeriesRing(GF(Integer(2)), names=('x',)); (x,) = L._first_ngens(1) >>> a = L(lambda n: n % Integer(2), valuation=Integer(3)); a x^3 + x^5 + x^7 + x^9 + O(x^10) >>> b = L(lambda n: binomial(n,Integer(2)) % Integer(2), valuation=Integer(3)); b x^3 + x^6 + x^7 + O(x^10) >>> g, s, t = a.xgcd(b) >>> g x^3 >>> s 1 + x + x^3 + x^4 + x^5 + O(x^7) >>> t x + x^2 + x^4 + x^5 + x^6 + O(x^8) >>> g == s * a + t * b True >>> LazyPowerSeriesRing.options._reset() # reset the options
- class sage.rings.lazy_series.LazySymmetricFunction(parent, coeff_stream)[source]#
Bases:
LazyCompletionGradedAlgebraElement
A symmetric function where each degree is computed lazily.
EXAMPLES:
sage: s = SymmetricFunctions(ZZ).s() # needs sage.modules sage: L = LazySymmetricFunctions(s) # needs sage.modules
>>> from sage.all import * >>> s = SymmetricFunctions(ZZ).s() # needs sage.modules >>> L = LazySymmetricFunctions(s) # needs sage.modules
- arithmetic_product(*args)[source]#
Return the arithmetic product of
self
withg
.The arithmetic product is a binary operation \(\boxdot\) on the ring of symmetric functions which is bilinear in its two arguments and satisfies
\[p_{\lambda} \boxdot p_{\mu} = \prod\limits_{i \geq 1, j \geq 1} p_{\mathrm{lcm}(\lambda_i, \mu_j)}^{\mathrm{gcd}(\lambda_i, \mu_j)}\]for any two partitions \(\lambda = (\lambda_1, \lambda_2, \lambda_3, \dots )\) and \(\mu = (\mu_1, \mu_2, \mu_3, \dots )\) (where \(p_{\nu}\) denotes the power-sum symmetric function indexed by the partition \(\nu\), and \(p_i\) denotes the \(i\)-th power-sum symmetric function). This is enough to define the arithmetic product if the base ring is torsion-free as a \(\ZZ\)-module; for all other cases the arithmetic product is uniquely determined by requiring it to be functorial in the base ring. See http://mathoverflow.net/questions/138148/ for a discussion of this arithmetic product.
Warning
The operation \(f \boxdot g\) was originally defined only for symmetric functions \(f\) and \(g\) without constant term. We extend this definition using the convention that the least common multiple of any integer with \(0\) is \(0\).
If \(f\) and \(g\) are two symmetric functions which are homogeneous of degrees \(a\) and \(b\), respectively, then \(f \boxdot g\) is homogeneous of degree \(ab\).
The arithmetic product is commutative and associative and has unity \(e_1 = p_1 = h_1\).
For species \(M\) and \(N\) such that \(M[\varnothing] = N[\varnothing] = \varnothing\), their arithmetic product is the species \(M \boxdot N\) of “\(M\)-assemblies of cloned \(N\)-structures”. This operation is defined and several examples are given in [MM2008].
INPUT:
g
– a cycle index series having the same parent asself
OUTPUT:
The arithmetic product of
self
withg
.EXAMPLES:
For \(C\) the species of (oriented) cycles and \(L_{+}\) the species of nonempty linear orders, \(C \boxdot L_{+}\) corresponds to the species of “regular octopuses”; a \((C \boxdot L_{+})\)-structure is a cycle of some length, each of whose elements is an ordered list of a length which is consistent for all the lists in the structure.
sage: R.<q> = QQ[] sage: p = SymmetricFunctions(R).p() # needs sage.modules sage: m = SymmetricFunctions(R).m() # needs sage.modules sage: L = LazySymmetricFunctions(m) # needs sage.modules sage: # needs sage.modules sage: C = species.CycleSpecies().cycle_index_series() sage: c = L(lambda n: C[n]) sage: Lplus = L(lambda n: p([1]*n), valuation=1) sage: r = c.arithmetic_product(Lplus); r # needs sage.libs.pari m[1] + (3*m[1,1]+2*m[2]) + (8*m[1,1,1]+4*m[2,1]+2*m[3]) + (42*m[1,1,1,1]+21*m[2,1,1]+12*m[2,2]+7*m[3,1]+3*m[4]) + (144*m[1,1,1,1,1]+72*m[2,1,1,1]+36*m[2,2,1]+24*m[3,1,1]+12*m[3,2]+6*m[4,1]+2*m[5]) + ... + O^7
>>> from sage.all import * >>> R = QQ['q']; (q,) = R._first_ngens(1) >>> p = SymmetricFunctions(R).p() # needs sage.modules >>> m = SymmetricFunctions(R).m() # needs sage.modules >>> L = LazySymmetricFunctions(m) # needs sage.modules >>> # needs sage.modules >>> C = species.CycleSpecies().cycle_index_series() >>> c = L(lambda n: C[n]) >>> Lplus = L(lambda n: p([Integer(1)]*n), valuation=Integer(1)) >>> r = c.arithmetic_product(Lplus); r # needs sage.libs.pari m[1] + (3*m[1,1]+2*m[2]) + (8*m[1,1,1]+4*m[2,1]+2*m[3]) + (42*m[1,1,1,1]+21*m[2,1,1]+12*m[2,2]+7*m[3,1]+3*m[4]) + (144*m[1,1,1,1,1]+72*m[2,1,1,1]+36*m[2,2,1]+24*m[3,1,1]+12*m[3,2]+6*m[4,1]+2*m[5]) + ... + O^7
In particular, the number of regular octopuses is:
sage: [r[n].coefficient([1]*n) for n in range(8)] # needs sage.libs.pari sage.modules [0, 1, 3, 8, 42, 144, 1440, 5760]
>>> from sage.all import * >>> [r[n].coefficient([Integer(1)]*n) for n in range(Integer(8))] # needs sage.libs.pari sage.modules [0, 1, 3, 8, 42, 144, 1440, 5760]
It is shown in [MM2008] that the exponential generating function for regular octopuses satisfies \((C \boxdot L_{+}) (x) = \sum_{n \geq 1} \sigma (n) (n - 1)! \frac{x^{n}}{n!}\) (where \(\sigma (n)\) is the sum of the divisors of \(n\)).
sage: [sum(divisors(i))*factorial(i-1) for i in range(1,8)] # needs sage.modules [1, 3, 8, 42, 144, 1440, 5760]
>>> from sage.all import * >>> [sum(divisors(i))*factorial(i-Integer(1)) for i in range(Integer(1),Integer(8))] # needs sage.modules [1, 3, 8, 42, 144, 1440, 5760]
AUTHORS:
Andrew Gainer-Dewar (2013)
REFERENCES:
- compositional_inverse()[source]#
Return the compositional inverse of
self
.Given a symmetric function \(f\), the compositional inverse is a symmetric function \(g\) over the same base ring, such that \(f \circ g = p_1\). Thus, it is the inverse with respect to plethystic substitution.
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b p_1\) with \(a, b \neq 0\).
See also
EXAMPLES:
sage: # needs sage.modules sage: h = SymmetricFunctions(QQ).h() sage: L = LazySymmetricFunctions(h) sage: f = L(lambda n: h[n]) - 1 sage: f(f.revert()) h[1] + O^8
>>> from sage.all import * >>> # needs sage.modules >>> h = SymmetricFunctions(QQ).h() >>> L = LazySymmetricFunctions(h) >>> f = L(lambda n: h[n]) - Integer(1) >>> f(f.revert()) h[1] + O^8
ALGORITHM:
Let \(F\) be a symmetric function with valuation \(1\), i.e., whose constant term vanishes and whose degree one term equals \(b p_1\). Then
\[(F - b p_1) \circ G = F \circ G - b p_1 \circ G = p_1 - b G,\]and therefore \(G = (p_1 - (F - b p_1) \circ G) / b\), which allows recursive computation of \(G\).
See also
The compositional inverse \(\Omega\) of the symmetric function \(h_1 + h_2 + \dots\) can be handled much more efficiently using specialized methods. See
LogarithmCycleIndexSeries()
AUTHORS:
Andrew Gainer-Dewar
Martin Rubey
- derivative_with_respect_to_p1(n=1)[source]#
Return the symmetric function obtained by taking the derivative of
self
with respect to the power-sum symmetric function \(p_1\) when the expansion ofself
in the power-sum basis is considered as a polynomial in \(p_k\)’s (with \(k \geq 1\)).This is the same as skewing
self
by the first power-sum symmetric function \(p_1\).INPUT:
n
– (default: 1) nonnegative integer which determines which power of the derivative is taken
EXAMPLES:
The species \(E\) of sets satisfies the relationship \(E' = E\):
sage: # needs sage.modules sage: h = SymmetricFunctions(QQ).h() sage: T = LazySymmetricFunctions(h) sage: E = T(lambda n: h[n]) sage: E - E.derivative_with_respect_to_p1() O^6
>>> from sage.all import * >>> # needs sage.modules >>> h = SymmetricFunctions(QQ).h() >>> T = LazySymmetricFunctions(h) >>> E = T(lambda n: h[n]) >>> E - E.derivative_with_respect_to_p1() O^6
The species \(C\) of cyclic orderings and the species \(L\) of linear orderings satisfy the relationship \(C' = L\):
sage: # needs sage.modules sage: p = SymmetricFunctions(QQ).p() sage: C = T(lambda n: (sum(euler_phi(k)*p([k])**(n//k) ....: for k in divisors(n))/n if n > 0 else 0)) sage: L = T(lambda n: p([1]*n)) sage: L - C.derivative_with_respect_to_p1() # needs sage.libs.pari O^6
>>> from sage.all import * >>> # needs sage.modules >>> p = SymmetricFunctions(QQ).p() >>> C = T(lambda n: (sum(euler_phi(k)*p([k])**(n//k) ... for k in divisors(n))/n if n > Integer(0) else Integer(0))) >>> L = T(lambda n: p([Integer(1)]*n)) >>> L - C.derivative_with_respect_to_p1() # needs sage.libs.pari O^6
- functorial_composition(*args)[source]#
Return the functorial composition of
self
andg
.Let \(X\) be a finite set of cardinality \(m\). For a group action of the symmetric group \(g: S_n \to S_X\) and a (possibly virtual) representation of the symmetric group on \(X\), \(f: S_X \to GL(V)\), the functorial composition is the (virtual) representation of the symmetric group \(f \Box g: S_n \to GL(V)\) given by \(\sigma \mapsto f(g(\sigma))\).
This is more naturally phrased in the language of combinatorial species. Let \(F\) and \(G\) be species, then their functorial composition is the species \(F \Box G\) with \((F \Box G) [A] = F[ G[A] ]\). In other words, an \((F \Box G)\)-structure on a set \(A\) of labels is an \(F\)-structure whose labels are the set of all \(G\)-structures on \(A\).
The Frobenius character (or cycle index series) of \(F \Box G\) can be computed as follows, see section 2.2 of [BLL1998]):
\[\sum_{n \geq 0} \frac{1}{n!} \sum_{\sigma \in \mathfrak{S}_{n}} \operatorname{fix} F[ (G[\sigma])_{1}, (G[\sigma])_{2}, \ldots ] \, p_{1}^{\sigma_{1}} p_{2}^{\sigma_{2}} \cdots.\]Warning
The operation \(f \Box g\) only makes sense when \(g\) corresponds to a permutation representation, i.e., a group action.
EXAMPLES:
The species \(G\) of simple graphs can be expressed in terms of a functorial composition: \(G = \mathfrak{p} \Box \mathfrak{p}_{2}\), where \(\mathfrak{p}\) is the
SubsetSpecies
.:sage: # needs sage.modules sage: R.<q> = QQ[] sage: h = SymmetricFunctions(R).h() sage: m = SymmetricFunctions(R).m() sage: L = LazySymmetricFunctions(m) sage: P = L(lambda n: sum(q^k*h[n-k]*h[k] for k in range(n+1))) sage: P2 = L(lambda n: h[2]*h[n-2], valuation=2) sage: P.functorial_composition(P2)[:4] # needs sage.libs.pari [m[], m[1], (q+1)*m[1, 1] + (q+1)*m[2], (q^3+3*q^2+3*q+1)*m[1, 1, 1] + (q^3+2*q^2+2*q+1)*m[2, 1] + (q^3+q^2+q+1)*m[3]]
>>> from sage.all import * >>> # needs sage.modules >>> R = QQ['q']; (q,) = R._first_ngens(1) >>> h = SymmetricFunctions(R).h() >>> m = SymmetricFunctions(R).m() >>> L = LazySymmetricFunctions(m) >>> P = L(lambda n: sum(q**k*h[n-k]*h[k] for k in range(n+Integer(1)))) >>> P2 = L(lambda n: h[Integer(2)]*h[n-Integer(2)], valuation=Integer(2)) >>> P.functorial_composition(P2)[:Integer(4)] # needs sage.libs.pari [m[], m[1], (q+1)*m[1, 1] + (q+1)*m[2], (q^3+3*q^2+3*q+1)*m[1, 1, 1] + (q^3+2*q^2+2*q+1)*m[2, 1] + (q^3+q^2+q+1)*m[3]]
For example, there are:
sage: P.functorial_composition(P2)[4].coefficient([4])[3] # needs sage.libs.pari sage.modules 3
>>> from sage.all import * >>> P.functorial_composition(P2)[Integer(4)].coefficient([Integer(4)])[Integer(3)] # needs sage.libs.pari sage.modules 3
unlabelled graphs on 4 vertices and 3 edges, and:
sage: P.functorial_composition(P2)[4].coefficient([2,2])[3] # needs sage.libs.pari sage.modules 8
>>> from sage.all import * >>> P.functorial_composition(P2)[Integer(4)].coefficient([Integer(2),Integer(2)])[Integer(3)] # needs sage.libs.pari sage.modules 8
labellings of their vertices with two 1’s and two 2’s.
The symmetric function \(h_1 \sum_n h_n\) is the neutral element with respect to functorial composition:
sage: # needs sage.modules sage: p = SymmetricFunctions(QQ).p() sage: h = SymmetricFunctions(QQ).h() sage: e = SymmetricFunctions(QQ).e() sage: L = LazySymmetricFunctions(h) sage: H = L(lambda n: h[n]) sage: Ep = p[1]*H.derivative_with_respect_to_p1(); Ep h[1] + (h[1,1]) + (h[2,1]) + (h[3,1]) + (h[4,1]) + (h[5,1]) + O^7 sage: f = L(lambda n: h[n-n//2, n//2]) sage: f - Ep.functorial_composition(f) # needs sage.libs.pari O^7
>>> from sage.all import * >>> # needs sage.modules >>> p = SymmetricFunctions(QQ).p() >>> h = SymmetricFunctions(QQ).h() >>> e = SymmetricFunctions(QQ).e() >>> L = LazySymmetricFunctions(h) >>> H = L(lambda n: h[n]) >>> Ep = p[Integer(1)]*H.derivative_with_respect_to_p1(); Ep h[1] + (h[1,1]) + (h[2,1]) + (h[3,1]) + (h[4,1]) + (h[5,1]) + O^7 >>> f = L(lambda n: h[n-n//Integer(2), n//Integer(2)]) >>> f - Ep.functorial_composition(f) # needs sage.libs.pari O^7
The symmetric function \(\sum_n h_n\) is a left absorbing element:
sage: # needs sage.modules sage: H.functorial_composition(f) - H O^7
>>> from sage.all import * >>> # needs sage.modules >>> H.functorial_composition(f) - H O^7
The functorial composition distributes over the sum:
sage: # needs sage.modules sage: F1 = L(lambda n: h[n]) sage: F2 = L(lambda n: e[n]) sage: f1 = F1.functorial_composition(f) sage: f2 = F2.functorial_composition(f) sage: (F1 + F2).functorial_composition(f) - f1 - f2 # long time O^7
>>> from sage.all import * >>> # needs sage.modules >>> F1 = L(lambda n: h[n]) >>> F2 = L(lambda n: e[n]) >>> f1 = F1.functorial_composition(f) >>> f2 = F2.functorial_composition(f) >>> (F1 + F2).functorial_composition(f) - f1 - f2 # long time O^7
- is_unit()[source]#
Return whether this element is a unit in the ring.
EXAMPLES:
sage: # needs sage.modules sage: m = SymmetricFunctions(ZZ).m() sage: L = LazySymmetricFunctions(m) sage: L(2*m[1]).is_unit() False sage: L(-1 + 2*m[1]).is_unit() True sage: L(2 + m[1]).is_unit() False sage: m = SymmetricFunctions(QQ).m() sage: L = LazySymmetricFunctions(m) sage: L(2 + 3*m[1]).is_unit() True
>>> from sage.all import * >>> # needs sage.modules >>> m = SymmetricFunctions(ZZ).m() >>> L = LazySymmetricFunctions(m) >>> L(Integer(2)*m[Integer(1)]).is_unit() False >>> L(-Integer(1) + Integer(2)*m[Integer(1)]).is_unit() True >>> L(Integer(2) + m[Integer(1)]).is_unit() False >>> m = SymmetricFunctions(QQ).m() >>> L = LazySymmetricFunctions(m) >>> L(Integer(2) + Integer(3)*m[Integer(1)]).is_unit() True
- legendre_transform()[source]#
Return the Legendre transform of
self
.Given a symmetric function \(f\) of valuation 2, the Legendre transform of \(f\) is the unique symmetric function \(g\) of valuation 2 over the same base ring, such that
\[g \circ \partial_{p_1} f + f = p_1 \partial_{p_1} f.\]This implies that the derivatives of \(f\) and \(g\) with respect to \(p_1\) are inverses of each other with respect to plethystic substitution.
The Legendre transform is an involution.
See also
EXAMPLES:
sage: p = SymmetricFunctions(QQ).p() sage: s = SymmetricFunctions(QQ).s() sage: lp = LazySymmetricFunctions(p) sage: A = lp(s([2])) sage: A.legendre_transform() (1/2*p[1,1]-1/2*p[2]) + O^9 sage: def asso(n): ....: return p.sum_of_terms((Partition([d] * (n // d)), ....: euler_phi(d) / n) for d in divisors(n)) sage: A = lp(asso, valuation=2) sage: A.legendre_transform()[:5] [1/2*p[1, 1] - 1/2*p[2], -1/3*p[1, 1, 1] - 2/3*p[3], 1/4*p[1, 1, 1, 1] + 1/4*p[2, 2] - 1/2*p[4]]
>>> from sage.all import * >>> p = SymmetricFunctions(QQ).p() >>> s = SymmetricFunctions(QQ).s() >>> lp = LazySymmetricFunctions(p) >>> A = lp(s([Integer(2)])) >>> A.legendre_transform() (1/2*p[1,1]-1/2*p[2]) + O^9 >>> def asso(n): ... return p.sum_of_terms((Partition([d] * (n // d)), ... euler_phi(d) / n) for d in divisors(n)) >>> A = lp(asso, valuation=Integer(2)) >>> A.legendre_transform()[:Integer(5)] [1/2*p[1, 1] - 1/2*p[2], -1/3*p[1, 1, 1] - 2/3*p[3], 1/4*p[1, 1, 1, 1] + 1/4*p[2, 2] - 1/2*p[4]]
- plethysm(*args)[source]#
Return the composition of
self
withg
.The arity of
self
must be equal to the number of arguments provided.Given a lazy symmetric function \(f\) of arity \(n\) and a tuple of lazy symmetric functions \(g = (g_1,\dots, g_n)\) over the same base ring, the composition (or plethysm) \((f \circ g)\) is defined if and only if for each \(1\leq i\leq n\):
\(g_i = 0\), or
setting all alphabets except the \(i\)-th in \(f\) to zero yields a symmetric function with only finitely many non-zero coefficients, or
\(\mathrm{val}(g) > 0\).
If \(f\) is a univariate ‘exact’ lazy symmetric function, we can check whether \(f\) has only finitely many non-zero coefficients. However, if \(f\) has larger arity, we have no way to test whether setting all but one alphabets of \(f\) to zero yields a polynomial, except if \(f\) itself is ‘exact’ and therefore a symmetric function with only finitely many non-zero coefficients.
INPUT:
g
– other (lazy) symmetric functions
Todo
Allow specification of degree one elements.
EXAMPLES:
sage: # needs sage.modules sage: P.<q> = QQ[] sage: s = SymmetricFunctions(P).s() sage: L = LazySymmetricFunctions(s) sage: f = s[2] sage: g = s[3] sage: L(f)(L(g)) - L(f(g)) 0 sage: f = s[2] + s[2,1] sage: g = s[1] + s[2,2] sage: L(f)(L(g)) - L(f(g)) 0 sage: L(f)(g) - L(f(g)) 0 sage: f = s[2] + s[2,1] sage: g = s[1] + s[2,2] sage: L(f)(L(q*g)) - L(f(q*g)) 0
>>> from sage.all import * >>> # needs sage.modules >>> P = QQ['q']; (q,) = P._first_ngens(1) >>> s = SymmetricFunctions(P).s() >>> L = LazySymmetricFunctions(s) >>> f = s[Integer(2)] >>> g = s[Integer(3)] >>> L(f)(L(g)) - L(f(g)) 0 >>> f = s[Integer(2)] + s[Integer(2),Integer(1)] >>> g = s[Integer(1)] + s[Integer(2),Integer(2)] >>> L(f)(L(g)) - L(f(g)) 0 >>> L(f)(g) - L(f(g)) 0 >>> f = s[Integer(2)] + s[Integer(2),Integer(1)] >>> g = s[Integer(1)] + s[Integer(2),Integer(2)] >>> L(f)(L(q*g)) - L(f(q*g)) 0
The Frobenius character of the permutation action on set partitions is a plethysm:
sage: # needs sage.modules sage: s = SymmetricFunctions(QQ).s() sage: S = LazySymmetricFunctions(s) sage: E1 = S(lambda n: s[n], valuation=1) sage: E = 1 + E1 sage: P = E(E1) sage: P[:5] [s[], s[1], 2*s[2], s[2, 1] + 3*s[3], 2*s[2, 2] + 2*s[3, 1] + 5*s[4]]
>>> from sage.all import * >>> # needs sage.modules >>> s = SymmetricFunctions(QQ).s() >>> S = LazySymmetricFunctions(s) >>> E1 = S(lambda n: s[n], valuation=Integer(1)) >>> E = Integer(1) + E1 >>> P = E(E1) >>> P[:Integer(5)] [s[], s[1], 2*s[2], s[2, 1] + 3*s[3], 2*s[2, 2] + 2*s[3, 1] + 5*s[4]]
The plethysm with a tensor product is also implemented:
sage: # needs sage.modules sage: s = SymmetricFunctions(QQ).s() sage: X = tensor([s[1],s[[]]]) sage: Y = tensor([s[[]],s[1]]) sage: S = LazySymmetricFunctions(s) sage: S2 = LazySymmetricFunctions(tensor([s, s])) sage: A = S(s[1,1,1]) sage: B = S2(X+Y) sage: A(B) # needs lrcalc_python (s[]#s[1,1,1]+s[1]#s[1,1]+s[1,1]#s[1]+s[1,1,1]#s[]) sage: H = S(lambda n: s[n]) # needs sage.modules sage: H(S2(X*Y)) # needs lrcalc_python sage.modules (s[]#s[]) + (s[1]#s[1]) + (s[1,1]#s[1,1]+s[2]#s[2]) + (s[1,1,1]#s[1,1,1]+s[2,1]#s[2,1]+s[3]#s[3]) + O^7 sage: H(S2(X+Y)) # needs sage.modules (s[]#s[]) + (s[]#s[1]+s[1]#s[]) + (s[]#s[2]+s[1]#s[1]+s[2]#s[]) + (s[]#s[3]+s[1]#s[2]+s[2]#s[1]+s[3]#s[]) + (s[]#s[4]+s[1]#s[3]+s[2]#s[2]+s[3]#s[1]+s[4]#s[]) + (s[]#s[5]+s[1]#s[4]+s[2]#s[3]+s[3]#s[2]+s[4]#s[1]+s[5]#s[]) + (s[]#s[6]+s[1]#s[5]+s[2]#s[4]+s[3]#s[3]+s[4]#s[2]+s[5]#s[1]+s[6]#s[]) + O^7
>>> from sage.all import * >>> # needs sage.modules >>> s = SymmetricFunctions(QQ).s() >>> X = tensor([s[Integer(1)],s[[]]]) >>> Y = tensor([s[[]],s[Integer(1)]]) >>> S = LazySymmetricFunctions(s) >>> S2 = LazySymmetricFunctions(tensor([s, s])) >>> A = S(s[Integer(1),Integer(1),Integer(1)]) >>> B = S2(X+Y) >>> A(B) # needs lrcalc_python (s[]#s[1,1,1]+s[1]#s[1,1]+s[1,1]#s[1]+s[1,1,1]#s[]) >>> H = S(lambda n: s[n]) # needs sage.modules >>> H(S2(X*Y)) # needs lrcalc_python sage.modules (s[]#s[]) + (s[1]#s[1]) + (s[1,1]#s[1,1]+s[2]#s[2]) + (s[1,1,1]#s[1,1,1]+s[2,1]#s[2,1]+s[3]#s[3]) + O^7 >>> H(S2(X+Y)) # needs sage.modules (s[]#s[]) + (s[]#s[1]+s[1]#s[]) + (s[]#s[2]+s[1]#s[1]+s[2]#s[]) + (s[]#s[3]+s[1]#s[2]+s[2]#s[1]+s[3]#s[]) + (s[]#s[4]+s[1]#s[3]+s[2]#s[2]+s[3]#s[1]+s[4]#s[]) + (s[]#s[5]+s[1]#s[4]+s[2]#s[3]+s[3]#s[2]+s[4]#s[1]+s[5]#s[]) + (s[]#s[6]+s[1]#s[5]+s[2]#s[4]+s[3]#s[3]+s[4]#s[2]+s[5]#s[1]+s[6]#s[]) + O^7
- plethystic_inverse()[source]#
Return the compositional inverse of
self
.Given a symmetric function \(f\), the compositional inverse is a symmetric function \(g\) over the same base ring, such that \(f \circ g = p_1\). Thus, it is the inverse with respect to plethystic substitution.
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b p_1\) with \(a, b \neq 0\).
See also
EXAMPLES:
sage: # needs sage.modules sage: h = SymmetricFunctions(QQ).h() sage: L = LazySymmetricFunctions(h) sage: f = L(lambda n: h[n]) - 1 sage: f(f.revert()) h[1] + O^8
>>> from sage.all import * >>> # needs sage.modules >>> h = SymmetricFunctions(QQ).h() >>> L = LazySymmetricFunctions(h) >>> f = L(lambda n: h[n]) - Integer(1) >>> f(f.revert()) h[1] + O^8
ALGORITHM:
Let \(F\) be a symmetric function with valuation \(1\), i.e., whose constant term vanishes and whose degree one term equals \(b p_1\). Then
\[(F - b p_1) \circ G = F \circ G - b p_1 \circ G = p_1 - b G,\]and therefore \(G = (p_1 - (F - b p_1) \circ G) / b\), which allows recursive computation of \(G\).
See also
The compositional inverse \(\Omega\) of the symmetric function \(h_1 + h_2 + \dots\) can be handled much more efficiently using specialized methods. See
LogarithmCycleIndexSeries()
AUTHORS:
Andrew Gainer-Dewar
Martin Rubey
- revert()[source]#
Return the compositional inverse of
self
.Given a symmetric function \(f\), the compositional inverse is a symmetric function \(g\) over the same base ring, such that \(f \circ g = p_1\). Thus, it is the inverse with respect to plethystic substitution.
The compositional inverse exists if and only if:
\(\mathrm{val}(f) = 1\), or
\(f = a + b p_1\) with \(a, b \neq 0\).
See also
EXAMPLES:
sage: # needs sage.modules sage: h = SymmetricFunctions(QQ).h() sage: L = LazySymmetricFunctions(h) sage: f = L(lambda n: h[n]) - 1 sage: f(f.revert()) h[1] + O^8
>>> from sage.all import * >>> # needs sage.modules >>> h = SymmetricFunctions(QQ).h() >>> L = LazySymmetricFunctions(h) >>> f = L(lambda n: h[n]) - Integer(1) >>> f(f.revert()) h[1] + O^8
ALGORITHM:
Let \(F\) be a symmetric function with valuation \(1\), i.e., whose constant term vanishes and whose degree one term equals \(b p_1\). Then
\[(F - b p_1) \circ G = F \circ G - b p_1 \circ G = p_1 - b G,\]and therefore \(G = (p_1 - (F - b p_1) \circ G) / b\), which allows recursive computation of \(G\).
See also
The compositional inverse \(\Omega\) of the symmetric function \(h_1 + h_2 + \dots\) can be handled much more efficiently using specialized methods. See
LogarithmCycleIndexSeries()
AUTHORS:
Andrew Gainer-Dewar
Martin Rubey
- suspension()[source]#
Return the suspension of \(self`\).
This is an involution, that maps the homogeneous component \(f_n\) of degree \(n\) to \((-1)^{n - 1} \omega(f_n)\), where \(omega\) is the usual involution of symmetric functions.
EXAMPLES:
sage: s = SymmetricFunctions(QQ).s() sage: ls = LazySymmetricFunctions(s) sage: f = ls(lambda n: s([n]), valuation=1) sage: g = f.revert().suspension(); g s[1] + (s[1,1]) + (s[2,1]) + (s[2,1,1]+s[3,1]) + ... sage: g.revert().suspension() s[1] + s[2] + s[3] + s[4] + s[5] + ...
>>> from sage.all import * >>> s = SymmetricFunctions(QQ).s() >>> ls = LazySymmetricFunctions(s) >>> f = ls(lambda n: s([n]), valuation=Integer(1)) >>> g = f.revert().suspension(); g s[1] + (s[1,1]) + (s[2,1]) + (s[2,1,1]+s[3,1]) + ... >>> g.revert().suspension() s[1] + s[2] + s[3] + s[4] + s[5] + ...
- symmetric_function(degree=None)[source]#
Return
self
as a symmetric function ifself
is actually so.INPUT:
degree
–None
or an integer
OUTPUT:
If
degree
is notNone
, the terms of the series of degree greater thandegree
are first truncated. Ifdegree
isNone
and the series is not a polynomial polynomial, aValueError
is raised.EXAMPLES:
sage: # needs sage.modules sage: s = SymmetricFunctions(QQ).s() sage: S = LazySymmetricFunctions(s) sage: elt = S(s[2]) sage: elt.symmetric_function() s[2]
>>> from sage.all import * >>> # needs sage.modules >>> s = SymmetricFunctions(QQ).s() >>> S = LazySymmetricFunctions(s) >>> elt = S(s[Integer(2)]) >>> elt.symmetric_function() s[2]