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)]
>>> from sage.all import *
>>> m = ModularForms(Gamma1(Integer(4)),Integer(11))
>>> m
Modular Forms space of dimension 6 for
 Congruence Subgroup Gamma1(4) of weight 11 over Rational Field
>>> 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)[source]¶
- 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 - >>> from sage.all import * >>> CuspForms(Integer(11),Integer(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)[source]¶
- 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 - >>> from sage.all import * >>> EisensteinForms(Integer(11),Integer(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)[source]¶
- Create an ambient space of modular forms. - INPUT: - group– a congruence subgroup or a Dirichlet character eps
- weight– integer; the weight (\(\geq 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 - >>> from sage.all import * >>> ModularForms(Gamma0(Integer(11)),Integer(2)).dimension() 2 >>> ModularForms(Gamma0(Integer(1)),Integer(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 - >>> from sage.all import * >>> ModularForms(Integer(1),Integer(12)).dimension() 2 >>> ModularForms(Integer(11),Integer(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 - >>> from sage.all import * >>> ModularForms(Gamma1(Integer(13)),Integer(2)) Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field >>> ModularForms(Gamma1(Integer(13)),Integer(2)).dimension() 13 >>> [ModularForms(Gamma1(Integer(7)),k).dimension() for k in [Integer(2),Integer(3),Integer(4),Integer(5)]] [5, 7, 9, 11] >>> ModularForms(Gamma1(Integer(5)),Integer(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) - >>> from sage.all import * >>> # needs sage.rings.number_field >>> e = (DirichletGroup(Integer(13)).gen(0))**Integer(2) >>> e.order() 6 >>> M = ModularForms(e, Integer(2)); M Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 >>> f = M.T(Integer(2)).charpoly('x'); f x^3 + (-2*zeta6 - 2)*x^2 - 2*zeta6*x + 14*zeta6 - 7 >>> 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) - >>> from sage.all import * >>> G = GammaH(Integer(30), [Integer(11)]) >>> M = ModularForms(G, Integer(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 >>> M.T(Integer(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 - >>> from sage.all import * >>> e = DirichletGroup(Integer(5), RationalField()).gen(); e Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1 >>> m = ModularForms(e, Integer(2)); m Modular Forms space of dimension 2, character [-1] and weight 2 over Rational Field >>> m == loads(dumps(m)) True >>> m.T(Integer(2)).charpoly('x') x^2 - 1 >>> m = ModularForms(e, Integer(6)); m.dimension() 4 >>> m.T(Integer(2)).charpoly('x') x^4 - 917*x^2 - 42284 - This came up in a subtle bug (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 - >>> from sage.all import * >>> ModularForms(gp(Integer(1)), gap(Integer(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 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 - >>> from sage.all import * >>> chi = DirichletGroup(Integer(109), CyclotomicField(Integer(3))).gen(0) >>> ModularForms(chi, Integer(2), base_ring = CyclotomicField(Integer(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 - >>> from sage.all import * >>> M = ModularForms(Gamma1(Integer(11)), Integer(1)); M Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(11) of weight 1 over Rational Field >>> 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)] >>> M.cuspidal_subspace().basis() [] >>> 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)] - >>> from sage.all import * >>> M = ModularForms(Gamma1(Integer(57)), Integer(1)); M # long time Modular Forms space of dimension 38 for Congruence Subgroup Gamma1(57) of weight 1 over Rational Field >>> 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) - >>> from sage.all import * >>> E = EisensteinForms(Gamma1(Integer(59)), Integer(1)); E # indirect doctest Eisenstein subspace of dimension 29 of Modular Forms space for Congruence Subgroup Gamma1(59) of weight 1 over Rational Field >>> (E.gen(0) + E.gen(2)).q_expansion(Integer(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()[source]¶
- Clear the cache of modular forms. - EXAMPLES: - sage: M = ModularForms(37,2) sage: sage.modular.modform.constructor._cache == {} False - >>> from sage.all import * >>> M = ModularForms(Integer(37),Integer(2)) >>> sage.modular.modform.constructor._cache == {} False - sage: sage.modular.modform.constructor.ModularForms_clear_cache() sage: sage.modular.modform.constructor._cache {} - >>> from sage.all import * >>> sage.modular.modform.constructor.ModularForms_clear_cache() >>> sage.modular.modform.constructor._cache {} 
- sage.modular.modform.constructor.Newform(identifier, group=None, weight=2, base_ring=Rational Field, names=None)[source]¶
- 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) - >>> from sage.all import * >>> Newform('67a', names='a') q + 2*q^2 - 2*q^3 + 2*q^4 + 2*q^5 + O(q^6) >>> 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)[source]¶
- Return 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)] - >>> from sage.all import * >>> Newforms(Integer(11), Integer(2)) [q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)] >>> Newforms(Integer(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 - >>> from sage.all import * >>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1) >>> chi = DirichletGroup(Integer(5), K)[Integer(1)] >>> len(Newforms(chi, Integer(7), names='a')) 1 >>> x = polygen(K); L = K.extension(x**Integer(2) - Integer(402)*i, names=('c',)); (c,) = L._first_ngens(1) >>> N = Newforms(chi, Integer(7), base_ring = L); len(N) 2 >>> sorted([N[Integer(0)][Integer(2)], N[Integer(1)][Integer(2)]]) == sorted([Integer(1)/Integer(2)*c - Integer(5)/Integer(2)*i - Integer(5)/Integer(2), -Integer(1)/Integer(2)*c - Integer(5)/Integer(2)*i - Integer(5)/Integer(2)]) True 
- sage.modular.modform.constructor.canonical_parameters(group, level, weight, base_ring)[source]¶
- 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– integer, group, or Dirichlet character
- level– integer or group
- weight– coercible to integer
- base_ring– commutative ring
 - OUTPUT: - level– integer
- group– congruence subgroup
- weight– integer
- ring– commutative 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. - >>> from sage.all import * >>> from sage.modular.modform.constructor import canonical_parameters >>> v = canonical_parameters(Integer(5), Integer(5), int(Integer(7)), ZZ); v (5, Congruence Subgroup Gamma0(5), 7, Integer Ring) >>> type(v[Integer(0)]), type(v[Integer(1)]), type(v[Integer(2)]), type(v[Integer(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'>) >>> canonical_parameters( Integer(5), Integer(7), Integer(7), ZZ ) Traceback (most recent call last): ... ValueError: group and level do not match. 
- sage.modular.modform.constructor.parse_label(s)[source]¶
- 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) - >>> from sage.all import * >>> sage.modular.modform.constructor.parse_label('11a') (Congruence Subgroup Gamma0(11), 0) >>> sage.modular.modform.constructor.parse_label('11aG1') (Congruence Subgroup Gamma1(11), 0) >>> sage.modular.modform.constructor.parse_label('11wG1') (Congruence Subgroup Gamma1(11), 22) - GammaH labels should also return the group and index (Issue #20823): - sage: sage.modular.modform.constructor.parse_label('389cGH[16]') (Congruence Subgroup Gamma_H(389) with H generated by [16], 2) - >>> from sage.all import * >>> sage.modular.modform.constructor.parse_label('389cGH[16]') (Congruence Subgroup Gamma_H(389) with H generated by [16], 2)