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 trac ticket #3934 for background.

AUTHOR:

  • David Loeffler (2008-08-22): initial version
sage.modular.etaproducts.AllCusps(N)

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)]
class sage.modular.etaproducts.CuspFamily(N, width, label=None)

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

__init__(N, width, label=None)

Create the cusp of width d on X_0(N) corresponding to the family of Tate curves (\CC_p/q^d, \langle \zeta q\rangle). Here \zeta is a primitive root of unity of order r with \mathrm{lcm}(r,d) = N. The cusp doesn’t store zeta, so we store an arbitrary label instead.

EXAMPLE:

sage: CuspFamily(8, 4)
(c_{4})
sage: CuspFamily(16, 4, '1')
(c_{4,1})
__weakref__
list of weak references to the object (if defined)
_repr_()

Return a string representation of self.

EXAMPLE:

sage: CuspFamily(16, 4, "1")._repr_()
'(c_{4,1})'
level()

The level of this cusp.

EXAMPLES:

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

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

EXAMPLE:

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

The width of this cusp.

EXAMPLES:

sage: e = CuspFamily(10, 1)
sage: e.width()
1
sage.modular.etaproducts.EtaGroup(level)

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)
...
TypeError: Level (=1/2) must be a positive integer
sage: EtaGroup(0)
...
ValueError: Level (=0) must be a positive integer
class sage.modular.etaproducts.EtaGroupElement(parent, rdict)
__cmp__(other)

Compare self to other. Eta products compare first according to their levels, then according to their rdicts.

EXAMPLES:

sage: EtaProduct(2, {2:24,1:-24}) == 1
False
sage: EtaProduct(2, {2:24, 1:-24}) < EtaProduct(4, {2:24, 1:-24})
True
sage: EtaProduct(2, {2:24, 1:-24}) == EtaProduct(4, {2:24, 1:-24})
False
sage: EtaProduct(2, {2:24, 1:-24}) < EtaProduct(4, {2:48, 1:-48})
True
__init__(parent, rdict)

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

EXAMPLE:

sage: EtaGroupElement(EtaGroup(8), {1:24, 2:-24})
Eta product of level 8 : (eta_1)^24 (eta_2)^-24
sage: g = _; g == loads(dumps(g))
True
__weakref__
list of weak references to the object (if defined)
_div_(other)

Return self * other^{-1}.

EXAMPLES:

sage: eta1, eta2 = EtaGroup(4).basis()
sage: eta1 / eta2 # indirect doctest
Eta product of level 4 : (eta_1)^-16 (eta_2)^24 (eta_4)^-8
sage: (eta1 / eta2) * eta2 == eta1
True
_mul_(other)

Return the product of self and other.

EXAMPLES:

sage: eta1, eta2 = EtaGroup(4).basis() # indirect doctest
sage: eta1 * eta2 
Eta product of level 4 : (eta_2)^24 (eta_4)^-24
_repr_()

Return the string representation of self.

EXAMPLES:

sage: EtaProduct(3, {3:12, 1:-12})._repr_()
'Eta product of level 3 : (eta_1)^-12 (eta_3)^12'
_short_repr()

A short string representation of self, which doesn’t specify the level.

EXAMPLES:

sage: EtaProduct(3, {3:12, 1:-12})._short_repr()
'(eta_1)^-12 (eta_3)^12'
degree()

Return the degree of self as a map X_0(N) \to \mathbb{P}^1, which is equal to 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
divisor()

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})
level()

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
order_at_cusp(cusp)

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

INPUT:

  • cusp - a CuspFamily object

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
q_expansion(n)

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
qexp(n)

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
r(d)

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
class sage.modular.etaproducts.EtaGroup_class(level)

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

__call__(dict)

Create an element of this group (an eta product object) with exponents from the given dictionary. See the docstring for the EtaProduct() factory function for how dict is used.

EXAMPLE:

sage: EtaGroup(2).__call__({1:24, 2:-24})
Eta product of level 2 : (eta_1)^24 (eta_2)^-24
__cmp__(other)

Compare self to other. If other is not an EtaGroup, compare by type; otherwise compare by level. EtaGroups of the same level compare as identical.

EXAMPLE:

sage: EtaGroup(12) == 12
False
sage: EtaGroup(12) < EtaGroup(13)
True
sage: EtaGroup(12) == EtaGroup(12)
True
__init__(level)

Create the group of eta products of a given level, which must be a positive integer.

EXAMPLES:
sage: G = EtaGroup(12); G # indirect doctest Group of eta products on X_0(12) sage: G is loads(dumps(G)) True
__reduce__()

Return the data used to construct self. Used for pickling.

EXAMPLE:

sage: EtaGroup(13).__reduce__()
(<function EtaGroup at ...>, (13,))
_repr_()

String representation of self.

EXAMPLE:

sage: EtaGroup(12)._repr_()
'Group of eta products on X_0(12)'
basis(reduce=True)

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

EXAMPLE:

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)^2 (eta_2)^1 (eta_3)^2 (eta_4)^-1 (eta_6)^-7 (eta_12)^3,
Eta product of level 12 : (eta_1)^-2 (eta_2)^3 (eta_3)^6 (eta_4)^-1 (eta_6)^-9 (eta_12)^3,
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)^1 (eta_2)^-1 (eta_3)^-3 (eta_4)^-2 (eta_6)^7 (eta_12)^-2,
Eta product of level 12 : (eta_1)^-6 (eta_2)^9 (eta_3)^2 (eta_4)^-3 (eta_6)^-3 (eta_12)^1]
sage: EtaGroup(12).basis(reduce=False) # much bigger coefficients
[Eta product of level 12 : (eta_2)^24 (eta_12)^-24,
Eta product of level 12 : (eta_1)^-336 (eta_2)^576 (eta_3)^696 (eta_4)^-216 (eta_6)^-576 (eta_12)^-144,
Eta product of level 12 : (eta_1)^-8 (eta_2)^-2 (eta_6)^2 (eta_12)^8,
Eta product of level 12 : (eta_1)^1 (eta_2)^9 (eta_3)^13 (eta_4)^-4 (eta_6)^-15 (eta_12)^-4,
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()

Return the level of self. EXAMPLES:

sage: EtaGroup(10).level()
10
reduce_basis(long_etas)

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]
sage.modular.etaproducts.EtaProduct(level, dict)

Create an EtaGroupElement object representing the function \prod_{d | N} \eta(q^d)^{r_d}. 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).
  • dict - (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 dict 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})
...
ValueError: sum d r_d (=12) is not 0 mod 24
sage: EtaProduct(3, {4:6, 1:-6})
...
ValueError: 4 does not divide 3
sage.modular.etaproducts._eta_relations_helper(eta1, eta2, degree, qexp_terms, labels, verbose)

Helper function used by eta_poly_relations. Finds a basis for the space of linear relations between the first qexp_terms of the q-expansions of the monomials \eta_1^i * \eta_2^j for 0 \le i,j < degree, and calculates a Groebner basis for the ideal generated by these relations.

Liable to return meaningless results if qexp_terms isn’t at least 1 + d*(m_1,m_2) where

System Message: WARNING/2 (m_i = min(0, {\text degree of the pole of $\eta_i$ at $\infty$}))

latex exited with error: [stderr] [stdout] This is pdfTeX, Version 3.141592-1.40.5 (Web2C 7.5.5) entering extended mode (./math.tex LaTeX2e <2005/12/01> Babel <v3.8h> and hyphenation patterns for american, french, german, ngerman, b ahasa, basque, bulgarian, catalan, croatian, czech, danish, dutch, esperanto, e stonian, finnish, greek, icelandic, irish, italian, latin, magyar, norsk, polis h, portuges, romanian, russian, serbian, slovak, slovene, spanish, swedish, tur kish, ukrainian, nohyphenation, loaded. (/usr/share/texmf/tex/latex/base/article.cls Document Class: article 2005/09/16 v1.4f Standard LaTeX document class (/usr/share/texmf/tex/latex/base/size12.clo)) (/usr/share/texmf/tex/latex/base/inputenc.sty (/usr/share/texmf/tex/latex/base/utf8.def (/usr/share/texmf/tex/latex/base/t1enc.dfu) (/usr/share/texmf/tex/latex/base/ot1enc.dfu) (/usr/share/texmf/tex/latex/base/omsenc.dfu))) (/usr/share/texmf/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?’ option. (/usr/share/texmf/tex/latex/amsmath/amstext.sty (/usr/share/texmf/tex/latex/amsmath/amsgen.sty)) (/usr/share/texmf/tex/latex/amsmath/amsbsy.sty) (/usr/share/texmf/tex/latex/amsmath/amsopn.sty)) (/usr/share/texmf/tex/latex/amscls/amsthm.sty) (/usr/share/texmf/tex/latex/amsfonts/amssymb.sty (/usr/share/texmf/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texmf/tex/latex/tools/bm.sty) (./math.aux) (/usr/share/texmf/tex/latex/amsfonts/umsa.fd) (/usr/share/texmf/tex/latex/amsfonts/umsb.fd) ! Missing } inserted. <inserted text> } l.32 \end{gather} ! Missing } inserted. <inserted text> } l.32 \end{gather} ! Missing $ inserted. <inserted text> $ l.32 \end{gather} ! Missing \cr inserted. <inserted text> \cr l.32 \end{gather} ! Missing { inserted. <inserted text> { l.32 \end{gather} ! Missing $ inserted. <inserted text> $ l.32 \end{gather} ! Missing \endgroup inserted. <inserted text> \endgroup l.32 \end{gather} ! Missing } inserted. <inserted text> } l.32 \end{gather} ! LaTeX Error: \begin{gather} on input line 30 ended by \end{split}. See the LaTeX manual or LaTeX Companion for explanation. Type H <return> for immediate help. ... l.32 \end{gather} ! Misplaced alignment tab character &. \math@cr@@@ ->\ifst@rred \nonumber \fi & \relax \make@display@tag \ifst@rred ... l.32 \end{gather} ! Misplaced \cr. \math@cr@@@ ...fi \global \advance \row@ \@ne \cr l.32 \end{gather} ! Extra }, or forgotten $. \gmeasure@ ...savetaglength@ \crcr #1\math@cr@@@ } }\restorecounters@ \if@fle... l.32 \end{gather} ! Extra }, or forgotten $. \gmeasure@ ...avetaglength@ \crcr #1\math@cr@@@ }} \restorecounters@ \if@fleq... l.32 \end{gather} ! Missing $ inserted. <inserted text> $ l.32 \end{gather} ! Display math should end with $$. <to be read again> \endgroup l.32 \end{gather} ! Package amsmath Error: \begin{split} won’t work here. See the amsmath package documentation for explanation. Type H <return> for immediate help. ... l.32 \end{gather} ! Missing number, treated as zero. <to be read again> \relax l.32 \end{gather} ! Illegal unit of measure (pt inserted). <to be read again> \relax l.32 \end{gather} ! LaTeX Error: \begin{document} ended by \end{gather}. See the LaTeX manual or LaTeX Companion for explanation. Type H <return> for immediate help. ... l.32 \end{gather} ! Missing $ inserted. <inserted text> $ l.32 \end{gather} ! Display math should end with $$. <to be read again> \endgroup l.32 \end{gather} ! Extra \endgroup. <recently read> \endgroup l.32 \end{gather} [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 476 bytes). Transcript written on math.log.

as then 1 will be in the ideal.

EXAMPLE:

sage: from sage.modular.etaproducts import _eta_relations_helper
sage: r,s = EtaGroup(4).basis()
sage: _eta_relations_helper(r,s,4,100,['a','b'],False)
[a - b - 16]
sage: _eta_relations_helper(EtaProduct(26, {2:2,13:2,26:-2,1:-2}),EtaProduct(26, {2:4,13:2,26:-4,1:-2}),3,12,['a','b'],False) # not enough terms, will return rubbish
[1]
sage.modular.etaproducts.eta_poly_relations(eta_elements, degree, labels=[, 'x1', 'x2'], verbose=False)

Find polynomial relations between eta products.

INPUTS:

  • 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.

OUTPUTS: 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: 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]

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
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]
sage.modular.etaproducts.num_cusps_of_width(N, d)

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: [num_cusps_of_width(18,d) for d in divisors(18)]
[1, 1, 2, 2, 1, 1]
sage.modular.etaproducts.qexp_eta(ps_ring, n)

Return the q-expansion of \eta(q) / q^{1/24}, where \eta(q) is Dedekind’s function

\eta(q) = q^{1/24}\prod_{i=1}^\infty (1-q^i)

as an element of ps_ring, to precision n. Completely naive algorithm.

INPUT:

  • ps_ring - (PowerSeriesRing): a power series ring - we pass this as an argument as we frequently need to create multiple series in the same ring.
  • n - (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 n terms.

ALGORITHM: Multiply out the product \prod_{i=1}^n (1 - q^i). Could perhaps be sped-up by using the identity

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

but I’m lazy.

EXAMPLES:

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)

Previous topic

Conjectural Slopes of Hecke Polynomial

Next topic

The space of p-adic weights

This Page