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)

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)

In principle, we can now compute any coefficient of \(f\):

sage: f.coefficient(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
{0: 0, 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
[0, 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)

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> = LazyTaylorSeriesRing(ZZ)
sage: f = 1 + 2*z^2 / (1 - z)
sage: f - 2 / (1 - z) + 1 + 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> = LazyTaylorSeriesRing(ZZ)
sage: 1 / (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()
sage: L = LazySymmetricFunctions(h)
sage: 1 / (1-L(h[1]))
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()
Lazy Laurent Series Ring in z over Rational Field
sage: h
4*z + 6*z^2 + 8*z^3 + 19*z^4 + 38*z^5 + 71*z^6 + O(z^7)
sage: hinv = h^-1; hinv
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()
-1
class sage.rings.lazy_series.LazyCauchyProductSeries(parent, coeff_stream)#

Bases: sage.rings.lazy_series.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)
valuation()#

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
class sage.rings.lazy_series.LazyCompletionGradedAlgebraElement(parent, coeff_stream)#

Bases: sage.rings.lazy_series.LazyCauchyProductSeries

An element of a completion of a graded algebra that is computed lazily.

class sage.rings.lazy_series.LazyDirichletSeries(parent, coeff_stream)#

Bases: sage.rings.lazy_series.LazyModuleElement

A Dirichlet series where the coefficients are computed lazily.

EXAMPLES:

sage: L = LazyDirichletSeriesRing(ZZ, "z")
sage: f = L(constant=1)^2; f
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)
True

Lazy Dirichlet series is picklable:

sage: g = loads(dumps(f))
sage: g
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
valuation()#

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()
0
sage: (mu - mu).valuation()
+Infinity
sage: g = L(constant=1, valuation=2)
sage: g.valuation()
log(2)
sage: (g*g).valuation()
2*log(2)
class sage.rings.lazy_series.LazyLaurentSeries(parent, coeff_stream)#

Bases: sage.rings.lazy_series.LazyCauchyProductSeries

A Laurent series where the coefficients are computed lazily.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)

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

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)

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)

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)
approximate_series(prec, name=None)#

Return the Laurent series with absolute precision prec approximated from this series.

INPUT:

  • prec – an integer

  • name – name of the variable; if it is None, 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
compose(g, check)#

Return the composition of self with g.

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 \(val(f) >= 0\),

  • \(g\) is non-zero and \(f\) has only finitely many non-zero coefficients,

  • \(g\) is non-zero and \(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 + O(z^7)

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]

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

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 + O(y^7)
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

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]

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

We look at cases where the composition does not exist. \(g = 0\) and \(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

\(g \neq 0\) and \(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

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; g
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]); g
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); e5
1 + z + 1/2*z^2 + 1/6*z^3 + 1/24*z^4
sage: e5(g)
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))
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
polynomial(degree=None, name=None)#

Return self as a Laurent polynomial if self is actually so.

INPUT:

  • degreeNone or an integer

  • name – name of the variable; if it is None, 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 not None, the terms of the series of degree greater than degree are truncated first. If degree is None and the series is not a polynomial or a Laurent polynomial, a ValueError 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
revert()#

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:

  • \(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(ZZ)
sage: z.revert()
z + O(z^8)
sage: (1/z).revert()
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)
class sage.rings.lazy_series.LazyModuleElement(parent, coeff_stream)#

Bases: sage.structure.element.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[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sage: N[: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]

Two sequences can be subtracted:

sage: P = M - N
sage: P[: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[: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[:10]
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
arccos()#

Return the arccos of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(RR)
sage: arccos(z)
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)
sage: arccos(z/(1-z))
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> = LazyTaylorSeriesRing(SR)
sage: arccos(x/(1-y))
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()#

Return the arctangent of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(RR)
sage: arccot(z)
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)
sage: arccot(z/(1-z))
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> = LazyTaylorSeriesRing(SR)
sage: acot(x/(1-y))
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()#

Return the arcsin 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> = LazyTaylorSeriesRing(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
arcsinh()#

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)

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> = LazyTaylorSeriesRing(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
arctan()#

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> = LazyTaylorSeriesRing(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
arctanh()#

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)

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> = LazyTaylorSeriesRing(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
change_ring(ring)#

Return self with coefficients converted to elements of ring.

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

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)

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: t^-1
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> = LazyTaylorSeriesRing(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
coefficient(n)#

Return the coefficient of the term with exponent n of the series.

INPUT:

  • n – integer; the exponent

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False)
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: 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]

Similarly for Dirichlet series:

sage: L = LazyDirichletSeriesRing(ZZ, "z")
sage: f = L(lambda n: n)
sage: [f[n] for n in range(1, 11)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sage: f[1:11]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

sage: M = L(lambda n: n)
sage: [M[n] for n in range(1, 11)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sage: L = LazyDirichletSeriesRing(ZZ, "z", sparse=True)
sage: M = L(lambda n: n)
sage: [M[n] for n in range(1, 11)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cos()#

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> = LazyTaylorSeriesRing(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
cosh()#

Return the cosh 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> = LazyTaylorSeriesRing(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
cot()#

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
coth()#

Return the hyperbolic cotangent of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: coth(z)
z^-1 + 1/3*z - 1/45*z^3 + 2/945*z^5 + O(z^6)

sage: coth(z + z^2)
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()#

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
csch()#

Return the hyperbolic cosecant of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: csch(z)
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))
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)#

Define an equation by self = s.

INPUT:

  • s – a Laurent polynomial

EXAMPLES:

We begin by constructing the Catalan numbers:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: C = L(None, valuation=0)
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)

The Catalan numbers but with a valuation 1:

sage: B = L(None, 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)

We can define multiple series that are linked:

sage: s = L(None, valuation=0)
sage: t = L(None, valuation=0)
sage: s.define(1 + z*t^3)
sage: t.define(1 + z*s^2)
sage: s[:9]
[1, 1, 3, 9, 34, 132, 546, 2327, 10191]
sage: t[:9]
[1, 1, 2, 7, 24, 95, 386, 1641, 7150]

A bigger example:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: A = L(None, valuation=5)
sage: B = L(None, valuation=0)
sage: C = L(None, 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]

Counting binary trees:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: s = L(None, valuation=1)
sage: s.define(z + (s^2+s(z^2))/2)
sage: [s[i] for i in range(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(None, 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)

We count unlabeled ordered trees by total number of nodes and number of internal nodes:

sage: R.<q> = QQ[]
sage: Q.<z> = LazyLaurentSeriesRing(R)
sage: leaf = z
sage: internal_node = q * z
sage: L = Q(constant=1, degree=1)
sage: T = Q(None, valuation=1)
sage: T.define(leaf + internal_node * L(T))
sage: [T[i] for i in range(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(None); F.define(1 + g*F)
sage: [F[i] for i in range(1, 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(None); F.define(1 + g*F*F)
sage: [F[i] for i in range(1, 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: 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(None); A.define(X*E(A, check=False))
sage: A[:6]
[0,
 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]]
exp()#

Return the exponential series of self.

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)
1
sage: exp(1 + z)
Traceback (most recent call last):
...
ValueError: can only compose with a positive valuation series

sage: L.<x,y> = LazyTaylorSeriesRing(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
hypergeometric(a, b)#

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 function

  • b – 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> = LazyTaylorSeriesRing(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
log()#

Return the series for the natural logarithm of self.

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> = LazyTaylorSeriesRing(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
map_coefficients(func, ring=None)#

Return the series with func applied to each nonzero coefficient of self.

INPUT:

  • func – function that takes in a coefficient and returns a new coefficient

EXAMPLES:

Dense Implementation:

sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False)
sage: s = z/(1 - 2*z^2)
sage: t = s.map_coefficients(lambda c: c + 1)
sage: s
z + 2*z^3 + 4*z^5 + 8*z^7 + O(z^8)
sage: t
2*z + 3*z^3 + 5*z^5 + 9*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.map_coefficients(lambda c: c + 1)
2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)

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.map_coefficients(lambda c: c + 1)
2*z + 3*z^2 + 4*z^3 + 5*z^4 + 6*z^5 + 7*z^6 + O(z^7)

An example where the series is known to be exact:

sage: f = z + z^2 + z^3
sage: f.map_coefficients(lambda c: c + 1)
2*z + 2*z^2 + 2*z^3

Similarly for Dirichlet series:

sage: L = LazyDirichletSeriesRing(ZZ, "z")
sage: s = L(lambda n: n-1); s
1/(2^z) + 2/3^z + 3/4^z + 4/5^z + 5/6^z + 6/7^z + O(1/(8^z))
sage: s.map_coefficients(lambda c: c + 1)
2/2^z + 3/3^z + 4/4^z + 5/5^z + 6/6^z + 7/7^z + O(1/(8^z))
prec()#

Return the precision of the series, which is infinity.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: f = 1/(1 - z)
sage: f.prec()
+Infinity
sec()#

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> = LazyTaylorSeriesRing(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
sech()#

Return the hyperbolic secant of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: sech(z)
1 - 1/2*z^2 + 5/24*z^4 - 61/720*z^6 + O(z^7)

sage: L.<x, y> = LazyTaylorSeriesRing(QQ)
sage: sech(x/(1-y))
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)#

Define an equation by self = s.

INPUT:

  • s – a Laurent polynomial

EXAMPLES:

We begin by constructing the Catalan numbers:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: C = L(None, valuation=0)
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)

The Catalan numbers but with a valuation 1:

sage: B = L(None, 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)

We can define multiple series that are linked:

sage: s = L(None, valuation=0)
sage: t = L(None, valuation=0)
sage: s.define(1 + z*t^3)
sage: t.define(1 + z*s^2)
sage: s[:9]
[1, 1, 3, 9, 34, 132, 546, 2327, 10191]
sage: t[:9]
[1, 1, 2, 7, 24, 95, 386, 1641, 7150]

A bigger example:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: A = L(None, valuation=5)
sage: B = L(None, valuation=0)
sage: C = L(None, 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]

Counting binary trees:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: s = L(None, valuation=1)
sage: s.define(z + (s^2+s(z^2))/2)
sage: [s[i] for i in range(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(None, 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)

We count unlabeled ordered trees by total number of nodes and number of internal nodes:

sage: R.<q> = QQ[]
sage: Q.<z> = LazyLaurentSeriesRing(R)
sage: leaf = z
sage: internal_node = q * z
sage: L = Q(constant=1, degree=1)
sage: T = Q(None, valuation=1)
sage: T.define(leaf + internal_node * L(T))
sage: [T[i] for i in range(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(None); F.define(1 + g*F)
sage: [F[i] for i in range(1, 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(None); F.define(1 + g*F*F)
sage: [F[i] for i in range(1, 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: 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(None); A.define(X*E(A, check=False))
sage: A[:6]
[0,
 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)#

Return self with the indices shifted by n.

For example, a Laurent series is multiplied by the power \(z^n\), where \(z\) is the variable of self.

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]); f
1/(2^t) + 2/3^t
sage: f.shift(3)
1/(5^t) + 2/6^t
sin()#

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> = LazyTaylorSeriesRing(QQ)
sage: sin(x/(1-y)).polynomial(3)
-1/6*x^3 + x*y^2 + x*y + x
sinh()#

Return the sinh 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> = LazyTaylorSeriesRing(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
sqrt()#

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> = LazyTaylorSeriesRing(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

This also works for Dirichlet series:

sage: D = LazyDirichletSeriesRing(SR, "s")
sage: Z = D(constant=1)
sage: f = sqrt(Z)
sage: 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))
tan()#

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> = LazyTaylorSeriesRing(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
tanh()#

Return the tanh of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: tanh(z)
z - 1/3*z^3 + 2/15*z^5 - 17/315*z^7 + O(z^8)

sage: L.<x,y> = LazyTaylorSeriesRing(QQ)
sage: tanh(x/(1-y))
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)#

Return this series with its terms of degree >= d truncated.

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

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

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
class sage.rings.lazy_series.LazySymmetricFunction(parent, coeff_stream)#

Bases: sage.rings.lazy_series.LazyCompletionGradedAlgebraElement

A symmetric function where each degree is computed lazily.

EXAMPLES:

sage: s = SymmetricFunctions(ZZ).s()
sage: L = LazySymmetricFunctions(s)
plethysm(check, *args)#

Return the composition of self with args.

The arity of self must be equal to the number of arguments provided.

Given two lazy symmetric functions \(f\) and \(g\) over the same base ring, the composition (or plethysm) \((f \circ g)\) is defined if and only if:

  • \(g = 0\),

  • \(g\) is non-zero and \(f\) has only finitely many non-zero coefficients,

  • \(g\) is non-zero and \(val(g) > 0\).

INPUT:

  • args – other (lazy) symmetric functions

EXAMPLES:

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

The Frobenius character of the permutation action on set partitions is a plethysm:

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: [s(x) for x in 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]]
symmetric_function(degree=None)#

Return self as a symmetric function if self is actually so.

INPUT:

  • degreeNone or an integer

OUTPUT:

If degree is not None, the terms of the series of degree greater than degree are truncated first. If degree is None and the series is not a polynomial polynomial, a ValueError is raised.

EXAMPLES:

sage: s = SymmetricFunctions(QQ).s()
sage: S = LazySymmetricFunctions(s)
sage: elt = S(s[2])
sage: elt.symmetric_function()
s[2]
class sage.rings.lazy_series.LazyTaylorSeries(parent, coeff_stream)#

Bases: sage.rings.lazy_series.LazyCauchyProductSeries

A Taylor series where the coefficients are computed lazily.

EXAMPLES:

sage: L.<x, y> = LazyTaylorSeriesRing(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

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
compose(check, *g)#

Return the composition of self with g.

The arity of self must be equal to the number of arguments provided.

Given two Taylor 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 \(val(f) >= 0\),

  • \(g\) is non-zero and \(f\) has only finitely many non-zero coefficients,

  • \(g\) is non-zero and \(val(g) > 0\).

INPUT:

  • g – other series, all can be coerced into the same parent

EXAMPLES:

sage: L.<x, y, z> = LazyTaylorSeriesRing(QQ)
sage: M.<a, b> = LazyTaylorSeriesRing(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

The number of mappings from a set with \(m\) elements to a set with \(n\) elements:

sage: M.<a> = LazyTaylorSeriesRing(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

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)

We perform the composition with a lazy Dirichlet series:

sage: D = LazyDirichletSeriesRing(QQ, "s")
sage: g = D(constant=1)-1; 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); 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); 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/(7^s))

sage: f = 1 / (1 - 2*a)
sage: f(g)
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)
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> = LazyTaylorSeriesRing(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
polynomial(degree=None, names=None)#

Return self as a polynomial if self is actually so.

INPUT:

  • degreeNone or an integer

  • names – names of the variables; if it is None, the name of the variables of the series is used

OUTPUT:

If degree is not None, the terms of the series of degree greater than degree are truncated first. If degree is None and the series is not a polynomial polynomial, a ValueError is raised.

EXAMPLES:

sage: L.<x,y> = LazyTaylorSeriesRing(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