Creating spaces of modular forms#

EXAMPLES:

sage: m = ModularForms(Gamma1(4),11)
sage: m
Modular Forms space of dimension 6 for
 Congruence Subgroup Gamma1(4) of weight 11 over Rational Field
sage: m.basis()
[
q - 134*q^5 + O(q^6),
q^2 + 80*q^5 + O(q^6),
q^3 + 16*q^5 + O(q^6),
q^4 - 4*q^5 + O(q^6),
1 + 4092/50521*q^2 + 472384/50521*q^3 + 4194300/50521*q^4 + O(q^6),
q + 1024*q^2 + 59048*q^3 + 1048576*q^4 + 9765626*q^5 + O(q^6)
]
sage.modular.modform.constructor.CuspForms(group=1, weight=2, base_ring=None, use_cache=True, prec=6)#

Create a space of cuspidal modular forms.

See the documentation for the ModularForms command for a description of the input parameters.

EXAMPLES:

sage: CuspForms(11,2)
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2
 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
sage.modular.modform.constructor.EisensteinForms(group=1, weight=2, base_ring=None, use_cache=True, prec=6)#

Create a space of Eisenstein modular forms.

See the documentation for the ModularForms command for a description of the input parameters.

EXAMPLES:

sage: EisensteinForms(11,2)
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2
 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
sage.modular.modform.constructor.ModularForms(group=1, weight=2, base_ring=None, eis_only=False, use_cache=True, prec=6)#

Create an ambient space of modular forms.

INPUT:

  • group - A congruence subgroup or a Dirichlet character eps.

  • weight - int, the weight, which must be an integer >= 1.

  • base_ring - the base ring (ignored if group is a Dirichlet character)

  • eis_only - if True, compute only the Eisenstein part of the space. Only permitted (and only useful) in weight 1, where computing dimensions of cusp form spaces is expensive.

Create using the command ModularForms(group, weight, base_ring) where group could be either a congruence subgroup or a Dirichlet character.

EXAMPLES: First we create some spaces with trivial character:

sage: ModularForms(Gamma0(11),2).dimension()
2
sage: ModularForms(Gamma0(1),12).dimension()
2

If we give an integer N for the congruence subgroup, it defaults to \(\Gamma_0(N)\):

sage: ModularForms(1,12).dimension()
2
sage: ModularForms(11,4)
Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(11)
 of weight 4 over Rational Field

We create some spaces for \(\Gamma_1(N)\).

sage: ModularForms(Gamma1(13),2)
Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13)
 of weight 2 over Rational Field
sage: ModularForms(Gamma1(13),2).dimension()
13
sage: [ModularForms(Gamma1(7),k).dimension() for k in [2,3,4,5]]
[5, 7, 9, 11]
sage: ModularForms(Gamma1(5),11).dimension()
12

We create a space with character:

sage: # needs sage.rings.number_field
sage: e = (DirichletGroup(13).0)^2
sage: e.order()
6
sage: M = ModularForms(e, 2); M
Modular Forms space of dimension 3, character [zeta6] and weight 2
 over Cyclotomic Field of order 6 and degree 2
sage: f = M.T(2).charpoly('x'); f
x^3 + (-2*zeta6 - 2)*x^2 - 2*zeta6*x + 14*zeta6 - 7
sage: f.factor()
(x - zeta6 - 2) * (x - 2*zeta6 - 1) * (x + zeta6 + 1)

We can also create spaces corresponding to the groups \(\Gamma_H(N)\) intermediate between \(\Gamma_0(N)\) and \(\Gamma_1(N)\):

sage: G = GammaH(30, [11])
sage: M = ModularForms(G, 2); M
Modular Forms space of dimension 20 for Congruence Subgroup Gamma_H(30)
 with H generated by [11] of weight 2 over Rational Field
sage: M.T(7).charpoly().factor()  # long time (7s on sage.math, 2011)
(x + 4) * x^2 * (x - 6)^4 * (x + 6)^4 * (x - 8)^7 * (x^2 + 4)

More examples of spaces with character:

sage: e = DirichletGroup(5, RationalField()).gen(); e
Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1

sage: m = ModularForms(e, 2); m
Modular Forms space of dimension 2, character [-1] and weight 2
 over Rational Field
sage: m == loads(dumps(m))
True
sage: m.T(2).charpoly('x')
x^2 - 1
sage: m = ModularForms(e, 6); m.dimension()
4
sage: m.T(2).charpoly('x')
x^4 - 917*x^2 - 42284

This came up in a subtle bug (github issue #5923):

sage: ModularForms(gp(1), gap(12))
Modular Forms space of dimension 2 for Modular Group SL(2,Z)
 of weight 12 over Rational Field

This came up in another bug (related to github issue #8630):

sage: chi = DirichletGroup(109, CyclotomicField(3)).0
sage: ModularForms(chi, 2, base_ring = CyclotomicField(15))
Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2
 over Cyclotomic Field of order 15 and degree 8

We create some weight 1 spaces. Here modular symbol algorithms do not work. In some small examples we can prove using Riemann–Roch that there are no cusp forms anyway, so the entire space is Eisenstein:

sage: M = ModularForms(Gamma1(11), 1); M
Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(11)
 of weight 1 over Rational Field
sage: M.basis()
[
1 + 22*q^5 + O(q^6),
q + 4*q^5 + O(q^6),
q^2 - 4*q^5 + O(q^6),
q^3 - 5*q^5 + O(q^6),
q^4 - 3*q^5 + O(q^6)
]
sage: M.cuspidal_subspace().basis()
[
]
sage: M == M.eisenstein_subspace()
True

When this does not work (which happens as soon as the level is more than about 30), we use the Hecke stability algorithm of George Schaeffer:

sage: M = ModularForms(Gamma1(57), 1); M  # long time
Modular Forms space of dimension 38 for Congruence Subgroup Gamma1(57)
 of weight 1 over Rational Field
sage: M.cuspidal_submodule().basis()      # long time
[
q - q^4 + O(q^6),
q^3 - q^4 + O(q^6)
]

The Eisenstein subspace in weight 1 can be computed quickly, without triggering the expensive computation of the cuspidal part:

sage: E = EisensteinForms(Gamma1(59), 1); E  # indirect doctest
Eisenstein subspace of dimension 29 of Modular Forms space for
 Congruence Subgroup Gamma1(59) of weight 1 over Rational Field
sage: (E.0 + E.2).q_expansion(40)
1 + q^2 + 196*q^29 - 197*q^30 - q^31 + q^33 + q^34 + q^37 + q^38 - q^39 + O(q^40)
sage.modular.modform.constructor.ModularForms_clear_cache()#

Clear the cache of modular forms.

EXAMPLES:

sage: M = ModularForms(37,2)
sage: sage.modular.modform.constructor._cache == {}
False
sage: sage.modular.modform.constructor.ModularForms_clear_cache()
sage: sage.modular.modform.constructor._cache
{}
sage.modular.modform.constructor.Newform(identifier, group=None, weight=2, base_ring=Rational Field, names=None)#

INPUT:

  • identifier - a canonical label, or the index of the specific newform desired

  • group - the congruence subgroup of the newform

  • weight - the weight of the newform (default 2)

  • base_ring - the base ring

  • names - if the newform has coefficients in a number field, a generator name must be specified

EXAMPLES:

sage: Newform('67a', names='a')
q + 2*q^2 - 2*q^3 + 2*q^4 + 2*q^5 + O(q^6)
sage: Newform('67b', names='a')
q + a1*q^2 + (-a1 - 3)*q^3 + (-3*a1 - 3)*q^4 - 3*q^5 + O(q^6)
sage.modular.modform.constructor.Newforms(group, weight=2, base_ring=None, names=None)#

Returns a list of the newforms of the given weight and level (or weight, level and character). These are calculated as \(\operatorname{Gal}(\overline{F} / F)\)-orbits, where \(F\) is the given base field.

INPUT:

  • group - the congruence subgroup of the newform, or a Nebentypus character

  • weight - the weight of the newform (default 2)

  • base_ring - the base ring (defaults to \(\QQ\) for spaces without character, or the base ring of the character otherwise)

  • names - if the newform has coefficients in a number field, a generator name must be specified

EXAMPLES:

sage: Newforms(11, 2)
[q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)]
sage: Newforms(65, names='a')
[q - q^2 - 2*q^3 - q^4 - q^5 + O(q^6),
 q + a1*q^2 + (a1 + 1)*q^3 + (-2*a1 - 1)*q^4 + q^5 + O(q^6),
 q + a2*q^2 + (-a2 + 1)*q^3 + q^4 - q^5 + O(q^6)]

A more complicated example involving both a nontrivial character, and a base field that is not minimal for that character:

sage: K.<i> = QuadraticField(-1)
sage: chi = DirichletGroup(5, K)[1]
sage: len(Newforms(chi, 7, names='a'))
1
sage: x = polygen(K); L.<c> = K.extension(x^2 - 402*i)
sage: N = Newforms(chi, 7, base_ring = L); len(N)
2
sage: sorted([N[0][2], N[1][2]]) == sorted([1/2*c - 5/2*i - 5/2, -1/2*c - 5/2*i - 5/2])
True
sage.modular.modform.constructor.canonical_parameters(group, level, weight, base_ring)#

Given a group, level, weight, and base_ring as input by the user, return a canonicalized version of them, where level is a Sage integer, group really is a group, weight is a Sage integer, and base_ring a Sage ring. Note that we can’t just get the level from the group, because we have the convention that the character for Gamma1(N) is None (which makes good sense).

INPUT:

  • group - int, long, Sage integer, group, Dirichlet character, or

  • level - int, long, Sage integer, or group

  • weight - coercible to Sage integer

  • base_ring - commutative Sage ring

OUTPUT:

  • level - Sage integer

  • group - congruence subgroup

  • weight - Sage integer

  • ring - commutative Sage ring

EXAMPLES:

sage: from sage.modular.modform.constructor import canonical_parameters
sage: v = canonical_parameters(5, 5, int(7), ZZ); v
(5, Congruence Subgroup Gamma0(5), 7, Integer Ring)
sage: type(v[0]), type(v[1]), type(v[2]), type(v[3])
(<class 'sage.rings.integer.Integer'>,
 <class 'sage.modular.arithgroup.congroup_gamma0.Gamma0_class_with_category'>,
 <class 'sage.rings.integer.Integer'>,
 <class 'sage.rings.integer_ring.IntegerRing_class'>)
sage: canonical_parameters( 5, 7, 7, ZZ )
Traceback (most recent call last):
...
ValueError: group and level do not match.
sage.modular.modform.constructor.parse_label(s)#

Given a string s corresponding to a newform label, return the corresponding group and index.

EXAMPLES:

sage: sage.modular.modform.constructor.parse_label('11a')
(Congruence Subgroup Gamma0(11), 0)
sage: sage.modular.modform.constructor.parse_label('11aG1')
(Congruence Subgroup Gamma1(11), 0)
sage: sage.modular.modform.constructor.parse_label('11wG1')
(Congruence Subgroup Gamma1(11), 22)

GammaH labels should also return the group and index (github issue #20823):

sage: sage.modular.modform.constructor.parse_label('389cGH[16]')
(Congruence Subgroup Gamma_H(389) with H generated by [16], 2)