Eta-products on modular curves X0(N)

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

d|Nη(qd)rd

where η(q) is Dirichlet’s eta function

q1/24n=1(1qn).

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 X0(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
AllCusps(18)
AllCusps(0)
class sage.modular.etaproducts.CuspFamily(N, width, label=None)[source]

Bases: SageObject

A family of elliptic curves parametrising a region of X0(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
e = CuspFamily(10, 1)
e.level()
sage_cusp()[source]

Return the corresponding element of P1(Q).

EXAMPLES:

sage: CuspFamily(10, 1).sage_cusp() # not implemented
Infinity
>>> from sage.all import *
>>> CuspFamily(Integer(10), Integer(1)).sage_cusp() # not implemented
Infinity
CuspFamily(10, 1).sage_cusp() # not implemented
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
e = CuspFamily(10, 1)
e.width()
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
EtaGroup(12)
EtaGroup(1/2)
EtaGroup(0)
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()
EtaProduct(8, {1:24, 2:-24})
g = _; g == loads(dumps(g))
TestSuite(g).run()
degree()[source]

Return the degree of self as a map X0(N)P1.

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
e = EtaProduct(12, {1:-336, 2:576, 3:696, 4:-216, 6:-576, 12:-144})
e.degree()
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})
e = EtaProduct(12, {1:-336, 2:576, 3:696, 4:-216, 6:-576, 12:-144})
e.divisor() # FormalSum seems to print things in a random order?
e = EtaProduct(2^8, {8:1,32:-1})
e.divisor() # random
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
e = EtaProduct(3, {3:12, 1:-12})
e.is_one()
e.parent().one().is_one()
ep = EtaProduct(5, {})
ep.is_one()
ep.parent().one() == ep
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
e = EtaProduct(3, {3:12, 1:-12})
e.level()
EtaProduct(12, {6:6, 2:-6}).level() # not the lcm of the d's
EtaProduct(36, {6:6, 2:-6}).level() # not minimal
order_at_cusp(cusp)[source]

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

INPUT:

OUTPUT: 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
e = EtaProduct(2, {2:24, 1:-24})
e.order_at_cusp(CuspFamily(2, 1)) # cusp at infinity
e.order_at_cusp(CuspFamily(2, 2)) # cusp 0
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 Z in the variable q, with a relative precision of 1+O(qn).

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
EtaProduct(36, {6:6, 2:-6}).q_expansion(10)
R.<q> = ZZ[[]]
EtaProduct(2,{2:24,1:-24}).q_expansion(100) == delta_qexp(101)(q^2)/delta_qexp(101)(q)
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
e = EtaProduct(36, {6:8, 3:-8})
e.qexp(10)
e.qexp(30) == e.q_expansion(30)
r(d)[source]

Return the exponent rd of η(qd) 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
e = EtaProduct(12, {2:24, 3:-24})
e.r(3)
e.r(4)
class sage.modular.etaproducts.EtaGroup_class(level)[source]

Bases: UniqueRepresentation, Parent

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 – boolean (default: True); 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]
EtaGroup(5).basis()
EtaGroup(12).basis()
EtaGroup(12).basis(reduce=False) # much bigger coefficients

ALGORITHM: An eta product of level N is uniquely determined by the integers rd for d|N with d<N, since d|Nrd=0. The valid rd 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 Zm(Z/24Z)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
EtaGroup(10).level()
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
EtaGroup(12).one()
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 L2 norm of its divisor (as an element of the free Z-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 L1 norm as this is just twice the degree, which is a much more natural invariant, but L2 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]
EtaGroup(4).reduce_basis([ EtaProduct(4, {1:8,2:24,4:-32}), EtaProduct(4, {1:8, 4:-8})])
sage.modular.etaproducts.EtaProduct(level, dic)[source]

Create an EtaGroupElement object representing the function d|Nη(qd)rd.

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

INPUT:

  • level – integer; the N such that this eta product is a function on X0(N)

  • dic – a dictionary indexed by divisors of N such that the coefficient of η(qd) 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 ).

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
EtaProduct(3, {3:12, 1:-12})
EtaProduct(3, {3:6, 1:-6})
EtaProduct(3, {4:6, 1:-6})
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: 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 0i,jdaijxiyj 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 qv in the q-expansion of this expression to be zero is a system of v+k linear equations in d2 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]
from sage.modular.etaproducts import eta_poly_relations
t = EtaProduct(26, {2:2,13:2,26:-2,1:-2})
u = EtaProduct(26, {2:4,13:2,26:-4,1:-2})
eta_poly_relations([t, u], 3)
eta_poly_relations([t, u], 4)

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
eta_poly_relations([t, u], 3, verbose=True)

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]
eta_poly_relations([t, u], 4, verbose=True)
sage.modular.etaproducts.num_cusps_of_width(N, d)[source]

Return the number of cusps on X0(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
from sage.modular.etaproducts import num_cusps_of_width
[num_cusps_of_width(18,d) for d in divisors(18)]
num_cusps_of_width(4,8)
sage.modular.etaproducts.qexp_eta(ps_ring, prec)[source]

Return the q-expansion of η(q)/q1/24.

Here η(q) is Dedekind’s function

η(q)=q1/24n=1(1qn).

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 η(q)/q1/24 truncated to prec terms.

ALGORITHM: We use the Euler identity

η(q)=q1/24(1+n1(1)n(qn(3n+1)/2+qn(3n1)/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)
from sage.modular.etaproducts import qexp_eta
qexp_eta(ZZ[['q']], 100)