# Lazy Series Rings#

We provide lazy implementations for various $$\NN$$-graded rings.

 LazyLaurentSeriesRing The ring of lazy Laurent series. LazyTaylorSeriesRing The ring of (possibly multivariate) lazy Taylor series. LazyCompletionGradedAlgebra The completion of a graded alebra consisting of formal series. LazySymmetricFunctions The ring of (possibly multivariate) lazy symmetric functions. LazyDirichletSeriesRing The ring of lazy Dirichlet series.

AUTHORS:

• Kwankyu Lee (2019-02-24): initial version

• Tejasvi Chebrolu, Martin Rubey, Travis Scrimshaw (2021-08): refactored and expanded functionality

The completion of a graded alebra consisting of formal series.

For a graded algebra $$A$$, we can form a completion of $$A$$ consisting of all formal series of $$A$$ such that each homogeneous component is a finite linear combination of basis elements of $$A$$.

INPUT:

• basis – a graded algebra

• names – name(s) of the alphabets

• sparse – (default: True) whether we use a sparse or a dense representation

EXAMPLES:

sage: NCSF = NonCommutativeSymmetricFunctions(QQ)
sage: S = NCSF.Complete()
sage: L = S.formal_series_ring()
sage: L
Lazy completion of Non-Commutative Symmetric Functions over the Rational Field in the Complete basis

sage: f = 1 / (1 - L(S[1]))
sage: f
S[] + S[1] + (S[1,1]) + (S[1,1,1]) + (S[1,1,1,1]) + (S[1,1,1,1,1]) + (S[1,1,1,1,1,1]) + O^7
sage: g = 1 / (1 - L(S[2]))
sage: g
S[] + S[2] + (S[2,2]) + (S[2,2,2]) + O^7
sage: f * g
S[] + S[1] + (S[1,1]+S[2]) + (S[1,1,1]+S[1,2])
+ (S[1,1,1,1]+S[1,1,2]+S[2,2]) + (S[1,1,1,1,1]+S[1,1,1,2]+S[1,2,2])
+ (S[1,1,1,1,1,1]+S[1,1,1,1,2]+S[1,1,2,2]+S[2,2,2]) + O^7
sage: g * f
S[] + S[1] + (S[1,1]+S[2]) + (S[1,1,1]+S[2,1])
+ (S[1,1,1,1]+S[2,1,1]+S[2,2]) + (S[1,1,1,1,1]+S[2,1,1,1]+S[2,2,1])
+ (S[1,1,1,1,1,1]+S[2,1,1,1,1]+S[2,2,1,1]+S[2,2,2]) + O^7
sage: f * g - g * f
(S[1,2]-S[2,1]) + (S[1,1,2]-S[2,1,1])
+ (S[1,1,1,2]+S[1,2,2]-S[2,1,1,1]-S[2,2,1])
+ (S[1,1,1,1,2]+S[1,1,2,2]-S[2,1,1,1,1]-S[2,2,1,1]) + O^7

Element#
class sage.rings.lazy_series_ring.LazyDirichletSeriesRing(base_ring, names, sparse=True, category=None)#

The ring of lazy Dirichlet series.

INPUT:

• base_ring – base ring of this Dirichlet series ring

• names – name of the generator of this Dirichlet series ring

• sparse – (default: True) whether this series is sparse or not

EXAMPLES:

sage: LazyDirichletSeriesRing(ZZ, 't')
Lazy Dirichlet Series Ring in t over Integer Ring

Element#
one()#

Return the constant series $$1$$.

EXAMPLES:

sage: L = LazyDirichletSeriesRing(ZZ, 'z')
sage: L.one()
1
sage: ~L.one()
1 + O(1/(8^z))

class sage.rings.lazy_series_ring.LazyLaurentSeriesRing(base_ring, names, sparse=True, category=None)#

The ring of lazy Laurent series.

The ring of Laurent series over a ring with the usual arithmetic where the coefficients are computed lazily.

INPUT:

• base_ring – base ring

• names – name of the generator

• sparse – (default: True) whether the implementation of the series is sparse or not

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(QQ)
sage: 1 / (1 - z)
1 + z + z^2 + O(z^3)
sage: 1 / (1 - z) == 1 / (1 - z)
True
sage: L in Fields
True


Lazy Laurent series ring over a finite field:

sage: L.<z> = LazyLaurentSeriesRing(GF(3)); L
Lazy Laurent Series Ring in z over Finite Field of size 3
sage: e = 1 / (1 + z)
sage: e.coefficient(100)
1
sage: e.coefficient(100).parent()
Finite Field of size 3


Series can be defined by specifying a coefficient function along with a valuation or a degree where after the series is evenutally constant:

sage: R.<x,y> = QQ[]
sage: L.<z> = LazyLaurentSeriesRing(R)
sage: def coeff(n):
....:     if n < 0:
....:         return -2 + n
....:     if n == 0:
....:         return 6
....:     return x + y^n
sage: f = L(coeff, valuation=-5)
sage: f
-7*z^-5 - 6*z^-4 - 5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + O(z^2)
sage: 1 / (1 - f)
1/7*z^5 - 6/49*z^6 + 1/343*z^7 + 8/2401*z^8 + 64/16807*z^9
+ 17319/117649*z^10 + (1/49*x + 1/49*y - 180781/823543)*z^11 + O(z^12)
sage: L(coeff, valuation=-3, degree=3, constant=x)
-5*z^-3 - 4*z^-2 - 3*z^-1 + 6 + (x + y)*z + (y^2 + x)*z^2
+ x*z^3 + x*z^4 + x*z^5 + O(z^6)


Similarly, we can specify a polynomial or the initial coefficients with anything that converts into the corresponding Laurent polynomial ring:

sage: L([1, x, y, 0, x+y])
1 + x*z + y*z^2 + (x + y)*z^4
sage: L([1, x, y, 0, x+y], constant=2)
1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^5 + 2*z^6 + 2*z^7 + O(z^8)
sage: L([1, x, y, 0, x+y], degree=7, constant=2)
1 + x*z + y*z^2 + (x + y)*z^4 + 2*z^7 + 2*z^8 + 2*z^9 + O(z^10)
sage: L([1, x, y, 0, x+y], valuation=-2)
z^-2 + x*z^-1 + y + (x + y)*z^2
sage: L([1, x, y, 0, x+y], valuation=-2, constant=3)
z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^3 + 3*z^4 + 3*z^5 + O(z^6)
sage: L([1, x, y, 0, x+y], valuation=-2, degree=4, constant=3)
z^-2 + x*z^-1 + y + (x + y)*z^2 + 3*z^4 + 3*z^5 + 3*z^6 + O(z^7)


Some additional examples over the integer ring:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: L in Fields
False
sage: 1 / (1 - 2*z)^3
1 + 6*z + 24*z^2 + 80*z^3 + 240*z^4 + 672*z^5 + 1792*z^6 + O(z^7)

sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: L(x^-2 + 3 + x)
z^-2 + 3 + z
sage: L(x^-2 + 3 + x, valuation=-5, constant=2)
z^-5 + 3*z^-3 + z^-2 + 2*z^-1 + 2 + 2*z + O(z^2)
sage: L(x^-2 + 3 + x, valuation=-5, degree=0, constant=2)
z^-5 + 3*z^-3 + z^-2 + 2 + 2*z + 2*z^2 + O(z^3)


We can also truncate, shift, and make eventually constant any Laurent series:

sage: f = 1 / (z + z^2)
sage: f
z^-1 - 1 + z - z^2 + z^3 - z^4 + z^5 + O(z^6)
sage: L(f, valuation=2)
z^2 - z^3 + z^4 - z^5 + z^6 - z^7 + z^8 + O(z^9)
sage: L(f, degree=3)
z^-1 - 1 + z - z^2
sage: L(f, degree=3, constant=2)
z^-1 - 1 + z - z^2 + 2*z^3 + 2*z^4 + 2*z^5 + O(z^6)
sage: L(f, valuation=1, degree=4)
z - z^2 + z^3
sage: L(f, valuation=1, degree=4, constant=5)
z - z^2 + z^3 + 5*z^4 + 5*z^5 + 5*z^6 + O(z^7)


Power series can be defined recursively (see sage.rings.lazy_series.LazyModuleElement.define() for more examples):

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: s = L(None, valuation=0)
sage: s.define(1 + z*s^2)
sage: s
1 + z + 2*z^2 + 5*z^3 + 14*z^4 + 42*z^5 + 132*z^6 + O(z^7)


If we do not explcitly know the exact value of every coefficient, then equality checking will depend on the computed coefficients. If at a certain point we cannot prove two series are different (which involves the coefficients we have computed), then we will raise an error:

sage: f = 1 / (z + z^2); f
z^-1 - 1 + z - z^2 + z^3 - z^4 + z^5 + O(z^6)
sage: f2 = f * 2  # currently no coefficients computed
sage: f3 = f * 3  # currently no coefficients computed
sage: f2 == f3
Traceback (most recent call last):
...
ValueError: undecidable
sage: f2  # computes some of the coefficients of f2
2*z^-1 - 2 + 2*z - 2*z^2 + 2*z^3 - 2*z^4 + 2*z^5 + O(z^6)
sage: f3  # computes some of the coefficients of f3
3*z^-1 - 3 + 3*z - 3*z^2 + 3*z^3 - 3*z^4 + 3*z^5 + O(z^6)
sage: f2 == f3
False


The implementation of the ring can be either be a sparse or a dense one. The default is a sparse implementation:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: L.is_sparse()
True
sage: L.<z> = LazyLaurentSeriesRing(ZZ, sparse=False)
sage: L.is_sparse()
False

Element#
gen(n=0)#

Return the n-th generator of self.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.gen()
z
sage: L.gen(3)
Traceback (most recent call last):
...
IndexError: there is only one generator

gens()#

Return the generators of self.

EXAMPLES:

sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: L.gens()
(z,)
sage: 1/(1 - z)
1 + z + z^2 + O(z^3)

ngens()#

Return the number of generators of self.

This is always 1.

EXAMPLES:

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

series(coefficient, valuation, degree=None, constant=None)#

Return a lazy Laurent series.

INPUT:

• coefficient – Python function that computes coefficients or a list

• valuation – integer; approximate valuation of the series

• degree – (optional) integer

• constant – (optional) an element of the base ring

Let the coefficient of index $$i$$ mean the coefficient of the term of the series with exponent $$i$$.

Python function coefficient returns the value of the coefficient of index $$i$$ from input $$s$$ and $$i$$ where $$s$$ is the series itself.

Let valuation be $$n$$. All coefficients of index below $$n$$ are zero. If constant is not specified, then the coefficient function is responsible to compute the values of all coefficients of index $$\ge n$$. If degree or constant is a pair $$(c,m)$$, then the coefficient function is responsible to compute the values of all coefficients of index $$\ge n$$ and $$< m$$ and all the coefficients of index $$\ge m$$ is the constant $$c$$.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.series(lambda s, i: i, 5, (1,10))
5*z^5 + 6*z^6 + 7*z^7 + 8*z^8 + 9*z^9 + z^10 + z^11 + z^12 + O(z^13)

sage: def g(s, i):
....:     if i < 0:
....:         return 1
....:     else:
....:         return s.coefficient(i - 1) + i
sage: e = L.series(g, -5); e
z^-5 + z^-4 + z^-3 + z^-2 + z^-1 + 1 + 2*z + O(z^2)
sage: f = e^-1; f
z^5 - z^6 - z^11 + O(z^12)
sage: f.coefficient(10)
0
sage: f.coefficient(20)
9
sage: f.coefficient(30)
-219


Alternatively, the coefficient can be a list of elements of the base ring. Then these elements are read as coefficients of the terms of degrees starting from the valuation. In this case, constant may be just an element of the base ring instead of a tuple or can be simply omitted if it is zero.

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: f = L.series([1,2,3,4], -5); f
z^-5 + 2*z^-4 + 3*z^-3 + 4*z^-2
sage: g = L.series([1,3,5,7,9], 5, constant=-1); g
z^5 + 3*z^6 + 5*z^7 + 7*z^8 + 9*z^9 - z^10 - z^11 - z^12 + O(z^13)

some_elements()#

Return a list of elements of self.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.some_elements()
[0, 1, z,
-3*z^-4 + z^-3 - 12*z^-2 - 2*z^-1 - 10 - 8*z + z^2 + z^3,
z^-2 + 3*z^-1 + 2*z + z^2 + z^3 + z^4 + z^5 + O(z^6),
-2*z^-3 - 2*z^-2 + 4*z^-1 + 11 - z - 34*z^2 - 31*z^3 + O(z^4),
4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + O(z^5)]

sage: L = LazyLaurentSeriesRing(GF(2), 'z')
sage: L.some_elements()
[0, 1, z,
z^-4 + z^-3 + z^2 + z^3,
z^-1 + z^2 + z^3 + z^4 + z^5 + O(z^6),
1 + z + z^3 + z^4 + z^6 + O(z^7),
z^-1 + z + z^3 + O(z^5)]

sage: L = LazyLaurentSeriesRing(GF(3), 'z')
sage: L.some_elements()
[0, 1, z,
z^-3 + z^-1 + 2 + z + z^2 + z^3,
z^2 + z^3 + z^4 + z^5 + O(z^6),
z^-3 + z^-2 + z^-1 + 2 + 2*z + 2*z^2 + O(z^3),
z^-2 + z^-1 + z + z^2 + z^4 + O(z^5)]

class sage.rings.lazy_series_ring.LazySeriesRing#

Abstract base class for lazy series.

characteristic()#

Return the characteristic of this lazy power series ring, which is the same as the characteristic of its base ring.

EXAMPLES:

sage: L.<t> = LazyLaurentSeriesRing(ZZ)
sage: L.characteristic()
0

sage: R.<w> = LazyLaurentSeriesRing(GF(11)); R
Lazy Laurent Series Ring in w over Finite Field of size 11
sage: R.characteristic()
11

sage: R.<x, y> = LazyTaylorSeriesRing(GF(7)); R
Multivariate Lazy Taylor Series Ring in x, y over Finite Field of size 7
sage: R.characteristic()
7

sage: L = LazyDirichletSeriesRing(ZZ, "s")
sage: L.characteristic()
0

is_exact()#

Return if self is exact or not.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.is_exact()
True
sage: L = LazyLaurentSeriesRing(RR, 'z')
sage: L.is_exact()
False

is_sparse()#

Return whether self is sparse or not.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z', sparse=False)
sage: L.is_sparse()
False

sage: L = LazyLaurentSeriesRing(ZZ, 'z', sparse=True)
sage: L.is_sparse()
True

one()#

Return the constant series $$1$$.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.one()
1

sage: L = LazyTaylorSeriesRing(ZZ, 'z')
sage: L.one()
1

sage: m = SymmetricFunctions(ZZ).m()
sage: L = LazySymmetricFunctions(m)
sage: L.one()
m[]

options(*get_value, **set_value)#

Set and display the options for lazy series.

If no parameters are set, then the function returns a copy of the options dictionary.

The options to lazy series can be accessed as using LazySeriesRing.options.

OPTIONS:

• constant_length – (default: 3) the number of coefficients to display for nonzero constant series

• display_length – (default: 7) the number of coefficients to display from the valuation

EXAMPLES:

sage: LLS.<z> = LazyLaurentSeriesRing(QQ)
sage: LLS.options
Current options for lazy series rings
- constant_length: 3
- display_length:  7

sage: LLS.options.display_length
7
sage: f = 1 / (1 + z)
sage: f
1 - z + z^2 - z^3 + z^4 - z^5 + z^6 + O(z^7)
sage: LLS.options.display_length = 10
sage: f
1 - z + z^2 - z^3 + z^4 - z^5 + z^6 - z^7 + z^8 - z^9 + O(z^10)
sage: g = LLS(lambda n: n^2, valuation=-2, degree=5, constant=42)
sage: g
4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + 42*z^5 + 42*z^6 + 42*z^7 + O(z^8)
sage: h = 1 / (1 - z)  # This is exact
sage: h
1 + z + z^2 + O(z^3)
sage: LLS.options.constant_length = 1
sage: g
4*z^-2 + z^-1 + z + 4*z^2 + 9*z^3 + 16*z^4 + 42*z^5 + O(z^6)
sage: h
1 + O(z)
sage: LazyLaurentSeriesRing.options._reset()
sage: LazyLaurentSeriesRing.options.display_length
7


See GlobalOptions for more features of these options.

undefined(valuation=None)#

Return an uninitialized series.

INPUT:

• valuation – integer; a lower bound for the valuation of the series

Power series can be defined recursively (see sage.rings.lazy_series.LazyModuleElement.define() for more examples).

EXAMPLES:

sage: L.<z> = LazyTaylorSeriesRing(QQ)
sage: s = L.undefined(1)
sage: s.define(z + (s^2+s(z^2))/2)
sage: s
z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8)

unknown(valuation=None)#

Return an uninitialized series.

INPUT:

• valuation – integer; a lower bound for the valuation of the series

Power series can be defined recursively (see sage.rings.lazy_series.LazyModuleElement.define() for more examples).

EXAMPLES:

sage: L.<z> = LazyTaylorSeriesRing(QQ)
sage: s = L.undefined(1)
sage: s.define(z + (s^2+s(z^2))/2)
sage: s
z + z^2 + z^3 + 2*z^4 + 3*z^5 + 6*z^6 + 11*z^7 + O(z^8)

zero()#

Return the zero series.

EXAMPLES:

sage: L = LazyLaurentSeriesRing(ZZ, 'z')
sage: L.zero()
0

sage: s = SymmetricFunctions(ZZ).s()
sage: L = LazySymmetricFunctions(s)
sage: L.zero()
0

sage: L = LazyDirichletSeriesRing(ZZ, 'z')
sage: L.zero()
0

sage: L = LazyTaylorSeriesRing(ZZ, 'z')
sage: L.zero()
0

class sage.rings.lazy_series_ring.LazySymmetricFunctions(basis, sparse=True, category=None)#

The ring of lazy symmetric functions.

INPUT:

• basis – the ring of symmetric functions

• names – name(s) of the alphabets

• sparse – (default: True) whether we use a sparse or a dense representation

EXAMPLES:

sage: s = SymmetricFunctions(ZZ).s()
sage: LazySymmetricFunctions(s)
Lazy completion of Symmetric Functions over Integer Ring in the Schur basis

sage: m = SymmetricFunctions(ZZ).m()
sage: LazySymmetricFunctions(tensor([s, m]))
Lazy completion of Symmetric Functions over Integer Ring in the Schur basis # Symmetric Functions over Integer Ring in the monomial basis

Element#
class sage.rings.lazy_series_ring.LazyTaylorSeriesRing(base_ring, names, sparse=True, category=None)#

The ring of (possibly multivariate) lazy Taylor series.

INPUT:

• base_ring – base ring of this Taylor series ring

• names – name(s) of the generator of this Taylor series ring

• sparse – (default: True) whether this series is sparse or not

EXAMPLES:

sage: LazyTaylorSeriesRing(ZZ, 't')
Lazy Taylor Series Ring in t over Integer Ring

sage: L.<x, y> = LazyTaylorSeriesRing(QQ); L
Multivariate Lazy Taylor Series Ring in x, y over Rational Field

Element#
gen(n=0)#

Return the n-th generator of self.

EXAMPLES:

sage: L = LazyTaylorSeriesRing(ZZ, 'z')
sage: L.gen()
z
sage: L.gen(3)
Traceback (most recent call last):
...
IndexError: there is only one generator

gens()#

Return the generators of self.

EXAMPLES:

sage: L = LazyTaylorSeriesRing(ZZ, 'x,y')
sage: L.gens()
(x, y)

ngens()#

Return the number of generators of self.

EXAMPLES:

sage: L.<z> = LazyTaylorSeriesRing(ZZ)
sage: L.ngens()
1