# Eta-products on modular curves $$X_0(N)$$#

This package provides a class for representing eta-products, which are meromorphic functions on modular curves of the form

$\prod_{d | N} \eta(q^d)^{r_d}$

where $$\eta(q)$$ is Dirichlet’s eta function

$q^{1/24} \prod_{n = 1}^\infty(1-q^n) .$

These are useful for obtaining explicit models of modular curves.

See Issue #3934 for background.

AUTHOR:

• David Loeffler (2008-08-22): initial version

sage.modular.etaproducts.AllCusps(N)[source]#

Return a list of CuspFamily objects corresponding to the cusps of $$X_0(N)$$.

INPUT:

• N – (integer): the level

EXAMPLES:

sage: AllCusps(18)
[(Inf), (c_{2}), (c_{3,1}), (c_{3,2}), (c_{6,1}), (c_{6,2}), (c_{9}), (0)]
sage: AllCusps(0)
Traceback (most recent call last):
...
ValueError: N must be positive

>>> from sage.all import *
>>> AllCusps(Integer(18))
[(Inf), (c_{2}), (c_{3,1}), (c_{3,2}), (c_{6,1}), (c_{6,2}), (c_{9}), (0)]
>>> AllCusps(Integer(0))
Traceback (most recent call last):
...
ValueError: N must be positive

class sage.modular.etaproducts.CuspFamily(N, width, label=None)[source]#

Bases: SageObject

A family of elliptic curves parametrising a region of $$X_0(N)$$.

level()[source]#

Return the level of this cusp.

EXAMPLES:

sage: e = CuspFamily(10, 1)
sage: e.level()
10

>>> from sage.all import *
>>> e = CuspFamily(Integer(10), Integer(1))
>>> e.level()
10

sage_cusp()[source]#

Return the corresponding element of $$\mathbb{P}^1(\QQ)$$.

EXAMPLES:

sage: CuspFamily(10, 1).sage_cusp() # not implemented
Infinity

>>> from sage.all import *
>>> CuspFamily(Integer(10), Integer(1)).sage_cusp() # not implemented
Infinity

width()[source]#

Return the width of this cusp.

EXAMPLES:

sage: e = CuspFamily(10, 1)
sage: e.width()
1

>>> from sage.all import *
>>> e = CuspFamily(Integer(10), Integer(1))
>>> e.width()
1

sage.modular.etaproducts.EtaGroup(level)[source]#

Create the group of eta products of the given level.

EXAMPLES:

sage: EtaGroup(12)
Group of eta products on X_0(12)
sage: EtaGroup(1/2)
Traceback (most recent call last):
...
TypeError: Level (=1/2) must be a positive integer
sage: EtaGroup(0)
Traceback (most recent call last):
...
ValueError: Level (=0) must be a positive integer

>>> from sage.all import *
>>> EtaGroup(Integer(12))
Group of eta products on X_0(12)
>>> EtaGroup(Integer(1)/Integer(2))
Traceback (most recent call last):
...
TypeError: Level (=1/2) must be a positive integer
>>> EtaGroup(Integer(0))
Traceback (most recent call last):
...
ValueError: Level (=0) must be a positive integer

class sage.modular.etaproducts.EtaGroupElement(parent, rdict)[source]#

Bases: Element

Create an eta product object. Usually called implicitly via EtaGroup_class.__call__ or the EtaProduct factory function.

EXAMPLES:

sage: EtaProduct(8, {1:24, 2:-24})
Eta product of level 8 : (eta_1)^24 (eta_2)^-24
sage: g = _; g == loads(dumps(g))
True
sage: TestSuite(g).run()

>>> from sage.all import *
>>> EtaProduct(Integer(8), {Integer(1):Integer(24), Integer(2):-Integer(24)})
Eta product of level 8 : (eta_1)^24 (eta_2)^-24
>>> g = _; g == loads(dumps(g))
True
>>> TestSuite(g).run()

degree()[source]#

Return the degree of self as a map $$X_0(N) \to \mathbb{P}^1$$.

This is the sum of all the positive coefficients in the divisor of self.

EXAMPLES:

sage: e = EtaProduct(12, {1:-336, 2:576, 3:696, 4:-216, 6:-576, 12:-144})
sage: e.degree()
230

>>> from sage.all import *
>>> e = EtaProduct(Integer(12), {Integer(1):-Integer(336), Integer(2):Integer(576), Integer(3):Integer(696), Integer(4):-Integer(216), Integer(6):-Integer(576), Integer(12):-Integer(144)})
>>> e.degree()
230

divisor()[source]#

Return the divisor of self, as a formal sum of CuspFamily objects.

EXAMPLES:

sage: e = EtaProduct(12, {1:-336, 2:576, 3:696, 4:-216, 6:-576, 12:-144})
sage: e.divisor() # FormalSum seems to print things in a random order?
-131*(Inf) - 50*(c_{2}) + 11*(0) + 50*(c_{6}) + 169*(c_{4}) - 49*(c_{3})
sage: e = EtaProduct(2^8, {8:1,32:-1})
sage: e.divisor() # random
-(c_{2}) - (Inf) - (c_{8,2}) - (c_{8,3}) - (c_{8,4}) - (c_{4,2})
- (c_{8,1}) - (c_{4,1}) + (c_{32,4}) + (c_{32,3}) + (c_{64,1})
+ (0) + (c_{32,2}) + (c_{64,2}) + (c_{128}) + (c_{32,1})

>>> from sage.all import *
>>> e = EtaProduct(Integer(12), {Integer(1):-Integer(336), Integer(2):Integer(576), Integer(3):Integer(696), Integer(4):-Integer(216), Integer(6):-Integer(576), Integer(12):-Integer(144)})
>>> e.divisor() # FormalSum seems to print things in a random order?
-131*(Inf) - 50*(c_{2}) + 11*(0) + 50*(c_{6}) + 169*(c_{4}) - 49*(c_{3})
>>> e = EtaProduct(Integer(2)**Integer(8), {Integer(8):Integer(1),Integer(32):-Integer(1)})
>>> e.divisor() # random
-(c_{2}) - (Inf) - (c_{8,2}) - (c_{8,3}) - (c_{8,4}) - (c_{4,2})
- (c_{8,1}) - (c_{4,1}) + (c_{32,4}) + (c_{32,3}) + (c_{64,1})
+ (0) + (c_{32,2}) + (c_{64,2}) + (c_{128}) + (c_{32,1})

is_one()[source]#

Return whether self is the one of the monoid.

EXAMPLES:

sage: e = EtaProduct(3, {3:12, 1:-12})
sage: e.is_one()
False
sage: e.parent().one().is_one()
True
sage: ep = EtaProduct(5, {})
sage: ep.is_one()
True
sage: ep.parent().one() == ep
True

>>> from sage.all import *
>>> e = EtaProduct(Integer(3), {Integer(3):Integer(12), Integer(1):-Integer(12)})
>>> e.is_one()
False
>>> e.parent().one().is_one()
True
>>> ep = EtaProduct(Integer(5), {})
>>> ep.is_one()
True
>>> ep.parent().one() == ep
True

level()[source]#

Return the level of this eta product.

EXAMPLES:

sage: e = EtaProduct(3, {3:12, 1:-12})
sage: e.level()
3
sage: EtaProduct(12, {6:6, 2:-6}).level() # not the lcm of the d's
12
sage: EtaProduct(36, {6:6, 2:-6}).level() # not minimal
36

>>> from sage.all import *
>>> e = EtaProduct(Integer(3), {Integer(3):Integer(12), Integer(1):-Integer(12)})
>>> e.level()
3
>>> EtaProduct(Integer(12), {Integer(6):Integer(6), Integer(2):-Integer(6)}).level() # not the lcm of the d's
12
>>> EtaProduct(Integer(36), {Integer(6):Integer(6), Integer(2):-Integer(6)}).level() # not minimal
36

order_at_cusp(cusp)[source]#

Return the order of vanishing of self at the given cusp.

INPUT:

OUTPUT:

• an integer

EXAMPLES:

sage: e = EtaProduct(2, {2:24, 1:-24})
sage: e.order_at_cusp(CuspFamily(2, 1)) # cusp at infinity
1
sage: e.order_at_cusp(CuspFamily(2, 2)) # cusp 0
-1

>>> from sage.all import *
>>> e = EtaProduct(Integer(2), {Integer(2):Integer(24), Integer(1):-Integer(24)})
>>> e.order_at_cusp(CuspFamily(Integer(2), Integer(1))) # cusp at infinity
1
>>> e.order_at_cusp(CuspFamily(Integer(2), Integer(2))) # cusp 0
-1

q_expansion(n)[source]#

Return the $$q$$-expansion of self at the cusp at infinity.

INPUT:

• n (integer): number of terms to calculate

OUTPUT:

• a power series over $$\ZZ$$ in the variable $$q$$, with a relative precision of $$1 + O(q^n)$$.

ALGORITHM: Calculates eta to (n/m) terms, where m is the smallest integer dividing self.level() such that self.r(m) != 0. Then multiplies.

EXAMPLES:

sage: EtaProduct(36, {6:6, 2:-6}).q_expansion(10)
q + 6*q^3 + 27*q^5 + 92*q^7 + 279*q^9 + O(q^11)
sage: R.<q> = ZZ[[]]
sage: EtaProduct(2,{2:24,1:-24}).q_expansion(100) == delta_qexp(101)(q^2)/delta_qexp(101)(q)
True

>>> from sage.all import *
>>> EtaProduct(Integer(36), {Integer(6):Integer(6), Integer(2):-Integer(6)}).q_expansion(Integer(10))
q + 6*q^3 + 27*q^5 + 92*q^7 + 279*q^9 + O(q^11)
>>> R = ZZ[['q']]; (q,) = R._first_ngens(1)
>>> EtaProduct(Integer(2),{Integer(2):Integer(24),Integer(1):-Integer(24)}).q_expansion(Integer(100)) == delta_qexp(Integer(101))(q**Integer(2))/delta_qexp(Integer(101))(q)
True

qexp(n)[source]#

Alias for self.q_expansion().

EXAMPLES:

sage: e = EtaProduct(36, {6:8, 3:-8})
sage: e.qexp(10)
q + 8*q^4 + 36*q^7 + O(q^10)
sage: e.qexp(30) == e.q_expansion(30)
True

>>> from sage.all import *
>>> e = EtaProduct(Integer(36), {Integer(6):Integer(8), Integer(3):-Integer(8)})
>>> e.qexp(Integer(10))
q + 8*q^4 + 36*q^7 + O(q^10)
>>> e.qexp(Integer(30)) == e.q_expansion(Integer(30))
True

r(d)[source]#

Return the exponent $$r_d$$ of $$\eta(q^d)$$ in self.

EXAMPLES:

sage: e = EtaProduct(12, {2:24, 3:-24})
sage: e.r(3)
-24
sage: e.r(4)
0

>>> from sage.all import *
>>> e = EtaProduct(Integer(12), {Integer(2):Integer(24), Integer(3):-Integer(24)})
>>> e.r(Integer(3))
-24
>>> e.r(Integer(4))
0

class sage.modular.etaproducts.EtaGroup_class(level)[source]#

The group of eta products of a given level under multiplication.

Element[source]#

alias of EtaGroupElement

basis(reduce=True)[source]#

Produce a basis for the free abelian group of eta-products of level N (under multiplication), attempting to find basis vectors of the smallest possible degree.

INPUT:

• reduce – a boolean (default: True) indicating whether or not to apply LLL-reduction to the calculated basis

EXAMPLES:

sage: EtaGroup(5).basis()
[Eta product of level 5 : (eta_1)^6 (eta_5)^-6]
sage: EtaGroup(12).basis()
[Eta product of level 12 : (eta_1)^-3 (eta_2)^2 (eta_3)^1 (eta_4)^-1 (eta_6)^-2 (eta_12)^3,
Eta product of level 12 : (eta_1)^-4 (eta_2)^2 (eta_3)^4 (eta_6)^-2,
Eta product of level 12 : (eta_1)^6 (eta_2)^-9 (eta_3)^-2 (eta_4)^3 (eta_6)^3 (eta_12)^-1,
Eta product of level 12 : (eta_1)^-1 (eta_2)^3 (eta_3)^3 (eta_4)^-2 (eta_6)^-9 (eta_12)^6,
Eta product of level 12 : (eta_1)^3 (eta_3)^-1 (eta_4)^-3 (eta_12)^1]
sage: EtaGroup(12).basis(reduce=False) # much bigger coefficients
[Eta product of level 12 : (eta_1)^384 (eta_2)^-576 (eta_3)^-696 (eta_4)^216 (eta_6)^576 (eta_12)^96,
Eta product of level 12 : (eta_2)^24 (eta_12)^-24,
Eta product of level 12 : (eta_1)^-40 (eta_2)^116 (eta_3)^96 (eta_4)^-30 (eta_6)^-80 (eta_12)^-62,
Eta product of level 12 : (eta_1)^-4 (eta_2)^-33 (eta_3)^-4 (eta_4)^1 (eta_6)^3 (eta_12)^37,
Eta product of level 12 : (eta_1)^15 (eta_2)^-24 (eta_3)^-29 (eta_4)^9 (eta_6)^24 (eta_12)^5]

>>> from sage.all import *
>>> EtaGroup(Integer(5)).basis()
[Eta product of level 5 : (eta_1)^6 (eta_5)^-6]
>>> EtaGroup(Integer(12)).basis()
[Eta product of level 12 : (eta_1)^-3 (eta_2)^2 (eta_3)^1 (eta_4)^-1 (eta_6)^-2 (eta_12)^3,
Eta product of level 12 : (eta_1)^-4 (eta_2)^2 (eta_3)^4 (eta_6)^-2,
Eta product of level 12 : (eta_1)^6 (eta_2)^-9 (eta_3)^-2 (eta_4)^3 (eta_6)^3 (eta_12)^-1,
Eta product of level 12 : (eta_1)^-1 (eta_2)^3 (eta_3)^3 (eta_4)^-2 (eta_6)^-9 (eta_12)^6,
Eta product of level 12 : (eta_1)^3 (eta_3)^-1 (eta_4)^-3 (eta_12)^1]
>>> EtaGroup(Integer(12)).basis(reduce=False) # much bigger coefficients
[Eta product of level 12 : (eta_1)^384 (eta_2)^-576 (eta_3)^-696 (eta_4)^216 (eta_6)^576 (eta_12)^96,
Eta product of level 12 : (eta_2)^24 (eta_12)^-24,
Eta product of level 12 : (eta_1)^-40 (eta_2)^116 (eta_3)^96 (eta_4)^-30 (eta_6)^-80 (eta_12)^-62,
Eta product of level 12 : (eta_1)^-4 (eta_2)^-33 (eta_3)^-4 (eta_4)^1 (eta_6)^3 (eta_12)^37,
Eta product of level 12 : (eta_1)^15 (eta_2)^-24 (eta_3)^-29 (eta_4)^9 (eta_6)^24 (eta_12)^5]


ALGORITHM: An eta product of level $$N$$ is uniquely determined by the integers $$r_d$$ for $$d | N$$ with $$d < N$$, since $$\sum_{d | N} r_d = 0$$. The valid $$r_d$$ are those that satisfy two congruences modulo 24, and one congruence modulo 2 for every prime divisor of N. We beef up the congruences modulo 2 to congruences modulo 24 by multiplying by 12. To calculate the kernel of the ensuing map $$\ZZ^m \to (\ZZ/24\ZZ)^n$$ we lift it arbitrarily to an integer matrix and calculate its Smith normal form. This gives a basis for the lattice.

This lattice typically contains “large” elements, so by default we pass it to the reduce_basis() function which performs LLL-reduction to give a more manageable basis.

level()[source]#

Return the level of self.

EXAMPLES:

sage: EtaGroup(10).level()
10

>>> from sage.all import *
>>> EtaGroup(Integer(10)).level()
10

one()[source]#

Return the identity element of self.

EXAMPLES:

sage: EtaGroup(12).one()
Eta product of level 12 : 1

>>> from sage.all import *
>>> EtaGroup(Integer(12)).one()
Eta product of level 12 : 1

reduce_basis(long_etas)[source]#

Produce a more manageable basis via LLL-reduction.

INPUT:

• long_etas – a list of EtaGroupElement objects (which should all be of the same level)

OUTPUT:

• a new list of EtaGroupElement objects having hopefully smaller norm

ALGORITHM: We define the norm of an eta-product to be the $$L^2$$ norm of its divisor (as an element of the free $$\ZZ$$-module with the cusps as basis and the standard inner product). Applying LLL-reduction to this gives a basis of hopefully more tractable elements. Of course we’d like to use the $$L^1$$ norm as this is just twice the degree, which is a much more natural invariant, but $$L^2$$ norm is easier to work with!

EXAMPLES:

sage: EtaGroup(4).reduce_basis([ EtaProduct(4, {1:8,2:24,4:-32}), EtaProduct(4, {1:8, 4:-8})])
[Eta product of level 4 : (eta_1)^8 (eta_4)^-8,
Eta product of level 4 : (eta_1)^-8 (eta_2)^24 (eta_4)^-16]

>>> from sage.all import *
>>> EtaGroup(Integer(4)).reduce_basis([ EtaProduct(Integer(4), {Integer(1):Integer(8),Integer(2):Integer(24),Integer(4):-Integer(32)}), EtaProduct(Integer(4), {Integer(1):Integer(8), Integer(4):-Integer(8)})])
[Eta product of level 4 : (eta_1)^8 (eta_4)^-8,
Eta product of level 4 : (eta_1)^-8 (eta_2)^24 (eta_4)^-16]

sage.modular.etaproducts.EtaProduct(level, dic)[source]#

Create an EtaGroupElement object representing the function $$\prod_{d | N} \eta(q^d)^{r_d}$$.

This checks the criteria of Ligozat to ensure that this product really is the $$q$$-expansion of a meromorphic function on $$X_0(N)$$.

INPUT:

• level – (integer): the N such that this eta product is a function on X_0(N).

• dic – (dictionary): a dictionary indexed by divisors of N such that the coefficient of $$\eta(q^d)$$ is r[d]. Only nonzero coefficients need be specified. If Ligozat’s criteria are not satisfied, a ValueError will be raised.

OUTPUT:

• an EtaGroupElement object, whose parent is the EtaGroup of level N and whose coefficients are the given dictionary.

Note

The dictionary dic does not uniquely specify N. It is possible for two EtaGroupElements with different $$N$$’s to be created with the same dictionary, and these represent different objects (although they will have the same $$q$$-expansion at the cusp $$\infty$$).

EXAMPLES:

sage: EtaProduct(3, {3:12, 1:-12})
Eta product of level 3 : (eta_1)^-12 (eta_3)^12
sage: EtaProduct(3, {3:6, 1:-6})
Traceback (most recent call last):
...
ValueError: sum d r_d (=12) is not 0 mod 24
sage: EtaProduct(3, {4:6, 1:-6})
Traceback (most recent call last):
...
ValueError: 4 does not divide 3

>>> from sage.all import *
>>> EtaProduct(Integer(3), {Integer(3):Integer(12), Integer(1):-Integer(12)})
Eta product of level 3 : (eta_1)^-12 (eta_3)^12
>>> EtaProduct(Integer(3), {Integer(3):Integer(6), Integer(1):-Integer(6)})
Traceback (most recent call last):
...
ValueError: sum d r_d (=12) is not 0 mod 24
>>> EtaProduct(Integer(3), {Integer(4):Integer(6), Integer(1):-Integer(6)})
Traceback (most recent call last):
...
ValueError: 4 does not divide 3

sage.modular.etaproducts.eta_poly_relations(eta_elements, degree, labels=['x1', 'x2'], verbose=False)[source]#

Find polynomial relations between eta products.

INPUT:

• eta_elements – (list): a list of EtaGroupElement objects. Not implemented unless this list has precisely two elements. degree

• degree – (integer): the maximal degree of polynomial to look for.

• labels – (list of strings): labels to use for the polynomial returned.

• verbose – (boolean, default False): if True, prints information as it goes.

OUTPUT: a list of polynomials which is a Groebner basis for the part of the ideal of relations between eta_elements which is generated by elements up to the given degree; or None, if no relations were found.

ALGORITHM: An expression of the form $$\sum_{0 \le i,j \le d} a_{ij} x^i y^j$$ is zero if and only if it vanishes at the cusp infinity to degree at least $$v = d(deg(x) + deg(y))$$. For all terms up to $$q^v$$ in the $$q$$-expansion of this expression to be zero is a system of $$v + k$$ linear equations in $$d^2$$ coefficients, where $$k$$ is the number of nonzero negative coefficients that can appear.

Solving these equations and calculating a basis for the solution space gives us a set of polynomial relations, but this is generally far from a minimal generating set for the ideal, so we calculate a Groebner basis.

As a test, we calculate five extra terms of $$q$$-expansion and check that this doesn’t change the answer.

EXAMPLES:

sage: from sage.modular.etaproducts import eta_poly_relations
sage: t = EtaProduct(26, {2:2,13:2,26:-2,1:-2})
sage: u = EtaProduct(26, {2:4,13:2,26:-4,1:-2})
sage: eta_poly_relations([t, u], 3)
sage: eta_poly_relations([t, u], 4)
[x1^3*x2 - 13*x1^3 - 4*x1^2*x2 - 4*x1*x2 - x2^2 + x2]

>>> from sage.all import *
>>> from sage.modular.etaproducts import eta_poly_relations
>>> t = EtaProduct(Integer(26), {Integer(2):Integer(2),Integer(13):Integer(2),Integer(26):-Integer(2),Integer(1):-Integer(2)})
>>> u = EtaProduct(Integer(26), {Integer(2):Integer(4),Integer(13):Integer(2),Integer(26):-Integer(4),Integer(1):-Integer(2)})
>>> eta_poly_relations([t, u], Integer(3))
>>> eta_poly_relations([t, u], Integer(4))
[x1^3*x2 - 13*x1^3 - 4*x1^2*x2 - 4*x1*x2 - x2^2 + x2]


Use verbose=True to see the details of the computation:

sage: eta_poly_relations([t, u], 3, verbose=True)
Trying to find a relation of degree 3
Lowest order of a term at infinity = -12
Highest possible degree of a term = 15
Trying all coefficients from q^-12 to q^15 inclusive
No polynomial relation of order 3 valid for 28 terms
Check:
Trying all coefficients from q^-12 to q^20 inclusive
No polynomial relation of order 3 valid for 33 terms

>>> from sage.all import *
>>> eta_poly_relations([t, u], Integer(3), verbose=True)
Trying to find a relation of degree 3
Lowest order of a term at infinity = -12
Highest possible degree of a term = 15
Trying all coefficients from q^-12 to q^15 inclusive
No polynomial relation of order 3 valid for 28 terms
Check:
Trying all coefficients from q^-12 to q^20 inclusive
No polynomial relation of order 3 valid for 33 terms

sage: eta_poly_relations([t, u], 4, verbose=True)
Trying to find a relation of degree 4
Lowest order of a term at infinity = -16
Highest possible degree of a term = 20
Trying all coefficients from q^-16 to q^20 inclusive
Check:
Trying all coefficients from q^-16 to q^25 inclusive
[x1^3*x2 - 13*x1^3 - 4*x1^2*x2 - 4*x1*x2 - x2^2 + x2]

>>> from sage.all import *
>>> eta_poly_relations([t, u], Integer(4), verbose=True)
Trying to find a relation of degree 4
Lowest order of a term at infinity = -16
Highest possible degree of a term = 20
Trying all coefficients from q^-16 to q^20 inclusive
Check:
Trying all coefficients from q^-16 to q^25 inclusive
[x1^3*x2 - 13*x1^3 - 4*x1^2*x2 - 4*x1*x2 - x2^2 + x2]

sage.modular.etaproducts.num_cusps_of_width(N, d)[source]#

Return the number of cusps on $$X_0(N)$$ of width d.

INPUT:

• N – (integer): the level

• d – (integer): an integer dividing N, the cusp width

EXAMPLES:

sage: from sage.modular.etaproducts import num_cusps_of_width
sage: [num_cusps_of_width(18,d) for d in divisors(18)]
[1, 1, 2, 2, 1, 1]
sage: num_cusps_of_width(4,8)
Traceback (most recent call last):
...
ValueError: N and d must be positive integers with d|N

>>> from sage.all import *
>>> from sage.modular.etaproducts import num_cusps_of_width
>>> [num_cusps_of_width(Integer(18),d) for d in divisors(Integer(18))]
[1, 1, 2, 2, 1, 1]
>>> num_cusps_of_width(Integer(4),Integer(8))
Traceback (most recent call last):
...
ValueError: N and d must be positive integers with d|N

sage.modular.etaproducts.qexp_eta(ps_ring, prec)[source]#

Return the q-expansion of $$\eta(q) / q^{1/24}$$.

Here $$\eta(q)$$ is Dedekind’s function

$\eta(q) = q^{1/24}\prod_{n=1}^\infty (1-q^n).$

The result is an element of ps_ring, with precision prec.

INPUT:

• ps_ring – (PowerSeriesRing): a power series ring

• prec – (integer): the number of terms to compute

OUTPUT: An element of ps_ring which is the q-expansion of $$\eta(q)/q^{1/24}$$ truncated to prec terms.

ALGORITHM: We use the Euler identity

$\eta(q) = q^{1/24}( 1 + \sum_{n \ge 1} (-1)^n (q^{n(3n+1)/2} + q^{n(3n-1)/2})$

to compute the expansion.

EXAMPLES:

sage: from sage.modular.etaproducts import qexp_eta
sage: qexp_eta(ZZ[['q']], 100)
1 - q - q^2 + q^5 + q^7 - q^12 - q^15 + q^22 + q^26 - q^35 - q^40 + q^51 + q^57 - q^70 - q^77 + q^92 + O(q^100)

>>> from sage.all import *
>>> from sage.modular.etaproducts import qexp_eta
>>> qexp_eta(ZZ[['q']], Integer(100))
1 - q - q^2 + q^5 + q^7 - q^12 - q^15 + q^22 + q^26 - q^35 - q^40 + q^51 + q^57 - q^70 - q^77 + q^92 + O(q^100)