Graded rings of modular forms¶
This module contains functions to find generators for the graded ring of modular forms of given level.
AUTHORS:
- William Stein (2007-08-24): first version 
- David Ayotte (2021-06): implemented category and Parent/Element frameworks 
- class sage.modular.modform.ring.ModularFormsRing(group, base_ring=Rational Field)[source]¶
- Bases: - Parent- The ring of modular forms (of weights 0 or at least 2) for a congruence subgroup of \(\SL_2(\ZZ)\), with coefficients in a specified base ring. - EXAMPLES: - sage: ModularFormsRing(Gamma1(13)) Ring of Modular Forms for Congruence Subgroup Gamma1(13) over Rational Field sage: m = ModularFormsRing(4); m Ring of Modular Forms for Congruence Subgroup Gamma0(4) over Rational Field sage: m.modular_forms_of_weight(2) Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(4) of weight 2 over Rational Field sage: m.modular_forms_of_weight(10) Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(4) of weight 10 over Rational Field sage: m == loads(dumps(m)) True sage: m.generators() [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10))] sage: m.q_expansion_basis(2,10) [1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10), q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)] sage: m.q_expansion_basis(3,10) [] sage: m.q_expansion_basis(10,10) [1 + 10560*q^6 + 3960*q^8 + O(q^10), q - 8056*q^7 - 30855*q^9 + O(q^10), q^2 - 796*q^6 - 8192*q^8 + O(q^10), q^3 + 66*q^7 + 832*q^9 + O(q^10), q^4 + 40*q^6 + 528*q^8 + O(q^10), q^5 + 20*q^7 + 190*q^9 + O(q^10)] - >>> from sage.all import * >>> ModularFormsRing(Gamma1(Integer(13))) Ring of Modular Forms for Congruence Subgroup Gamma1(13) over Rational Field >>> m = ModularFormsRing(Integer(4)); m Ring of Modular Forms for Congruence Subgroup Gamma0(4) over Rational Field >>> m.modular_forms_of_weight(Integer(2)) Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(4) of weight 2 over Rational Field >>> m.modular_forms_of_weight(Integer(10)) Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(4) of weight 10 over Rational Field >>> m == loads(dumps(m)) True >>> m.generators() [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10))] >>> m.q_expansion_basis(Integer(2),Integer(10)) [1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10), q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)] >>> m.q_expansion_basis(Integer(3),Integer(10)) [] >>> m.q_expansion_basis(Integer(10),Integer(10)) [1 + 10560*q^6 + 3960*q^8 + O(q^10), q - 8056*q^7 - 30855*q^9 + O(q^10), q^2 - 796*q^6 - 8192*q^8 + O(q^10), q^3 + 66*q^7 + 832*q^9 + O(q^10), q^4 + 40*q^6 + 528*q^8 + O(q^10), q^5 + 20*q^7 + 190*q^9 + O(q^10)] - Elements of modular forms ring can be initiated via multivariate polynomials (see - from_polynomial()):- sage: M = ModularFormsRing(1) sage: M.ngens() 2 sage: E4, E6 = polygens(QQ, 'E4, E6') sage: M(E4) 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: M(E6) 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) sage: M((E4^3 - E6^2)/1728) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> M.ngens() 2 >>> E4, E6 = polygens(QQ, 'E4, E6') >>> M(E4) 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> M(E6) 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) >>> M((E4**Integer(3) - E6**Integer(2))/Integer(1728)) q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) - Element[source]¶
- alias of - GradedModularFormElement
 - change_ring(base_ring)[source]¶
- Return a ring of modular forms over a new base ring of the same congruence subgroup. - INPUT: - base_ring– a base ring, which should be \(\QQ\), \(\ZZ\), or the integers mod \(p\) for some prime \(p\)
 - EXAMPLES: - sage: M = ModularFormsRing(11); M Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Rational Field sage: M.change_ring(Zmod(7)) Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Ring of integers modulo 7 sage: M.change_ring(ZZ) Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Integer Ring - >>> from sage.all import * >>> M = ModularFormsRing(Integer(11)); M Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Rational Field >>> M.change_ring(Zmod(Integer(7))) Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Ring of integers modulo 7 >>> M.change_ring(ZZ) Ring of Modular Forms for Congruence Subgroup Gamma0(11) over Integer Ring 
 - cuspidal_ideal_generators(maxweight=8, prec=None)[source]¶
- Return a set of generators for the ideal of cuspidal forms in this ring, as a module over the whole ring. - EXAMPLES: - sage: ModularFormsRing(Gamma0(3)).cuspidal_ideal_generators(maxweight=12) [(6, q - 6*q^2 + 9*q^3 + 4*q^4 + O(q^5), q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6))] sage: [k for k,f,F in ModularFormsRing(13, base_ring=ZZ).cuspidal_ideal_generators(maxweight=14)] [4, 4, 4, 6, 6, 12] - >>> from sage.all import * >>> ModularFormsRing(Gamma0(Integer(3))).cuspidal_ideal_generators(maxweight=Integer(12)) [(6, q - 6*q^2 + 9*q^3 + 4*q^4 + O(q^5), q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6))] >>> [k for k,f,F in ModularFormsRing(Integer(13), base_ring=ZZ).cuspidal_ideal_generators(maxweight=Integer(14))] [4, 4, 4, 6, 6, 12] 
 - cuspidal_submodule_q_expansion_basis(weight, prec=None)[source]¶
- Return a basis of \(q\)-expansions for the space of cusp forms of weight - weightfor this group.- INPUT: - weight– the weight
- prec– integer (default:- None) precision of \(q\)-expansions to return
 - ALGORITHM: Uses the method - cuspidal_ideal_generators()to calculate generators of the ideal of cusp forms inside this ring. Then multiply these up to weight- weightusing the generators of the whole modular form space returned by- q_expansion_basis().- EXAMPLES: - sage: R = ModularFormsRing(Gamma0(3)) sage: R.cuspidal_submodule_q_expansion_basis(20) [q - 8532*q^6 - 88442*q^7 + O(q^8), q^2 + 207*q^6 + 24516*q^7 + O(q^8), q^3 + 456*q^6 + O(q^8), q^4 - 135*q^6 - 926*q^7 + O(q^8), q^5 + 18*q^6 + 135*q^7 + O(q^8)] - >>> from sage.all import * >>> R = ModularFormsRing(Gamma0(Integer(3))) >>> R.cuspidal_submodule_q_expansion_basis(Integer(20)) [q - 8532*q^6 - 88442*q^7 + O(q^8), q^2 + 207*q^6 + 24516*q^7 + O(q^8), q^3 + 456*q^6 + O(q^8), q^4 - 135*q^6 - 926*q^7 + O(q^8), q^5 + 18*q^6 + 135*q^7 + O(q^8)] - We compute a basis of a space of very large weight, quickly (using this module) and slowly (using modular symbols), and verify that the answers are the same. - sage: A = R.cuspidal_submodule_q_expansion_basis(80, prec=30) # long time (1s on sage.math, 2013) sage: B = R.modular_forms_of_weight(80).cuspidal_submodule().q_expansion_basis(prec=30) # long time (19s on sage.math, 2013) sage: A == B # long time True - >>> from sage.all import * >>> A = R.cuspidal_submodule_q_expansion_basis(Integer(80), prec=Integer(30)) # long time (1s on sage.math, 2013) >>> B = R.modular_forms_of_weight(Integer(80)).cuspidal_submodule().q_expansion_basis(prec=Integer(30)) # long time (19s on sage.math, 2013) >>> A == B # long time True 
 - from_polynomial(polynomial, gens=None)[source]¶
- Return a graded modular form constructed by evaluating a given multivariate polynomial at a set of generators. - INPUT: - polynomial– a multivariate polynomial. The variables names of the polynomial should be different from- 'q'. The number of variable of this polynomial should equal the number of given generators.
- gens– list of modular forms generating this ring (default:- None); if- gensis- Nonethen the list of generators returned by the method- gen_forms()is used instead. Note that we do not check if the list is indeed a generating set.
 - OUTPUT: a - GradedModularFormElementgiven by the polynomial relation- polynomial- EXAMPLES: - sage: M = ModularFormsRing(1) sage: x,y = polygens(QQ, 'x,y') sage: M.from_polynomial(x^2+y^3) 2 - 1032*q + 774072*q^2 - 77047584*q^3 - 11466304584*q^4 - 498052467504*q^5 + O(q^6) sage: M = ModularFormsRing(Gamma0(6)) sage: M.ngens() 3 sage: x,y,z = polygens(QQ, 'x,y,z') sage: M.from_polynomial(x+y+z) 1 + q + q^2 + 27*q^3 + q^4 + 6*q^5 + O(q^6) sage: M.0 + M.1 + M.2 1 + q + q^2 + 27*q^3 + q^4 + 6*q^5 + O(q^6) sage: P = x.parent() sage: M.from_polynomial(P(1/2)) 1/2 - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> x,y = polygens(QQ, 'x,y') >>> M.from_polynomial(x**Integer(2)+y**Integer(3)) 2 - 1032*q + 774072*q^2 - 77047584*q^3 - 11466304584*q^4 - 498052467504*q^5 + O(q^6) >>> M = ModularFormsRing(Gamma0(Integer(6))) >>> M.ngens() 3 >>> x,y,z = polygens(QQ, 'x,y,z') >>> M.from_polynomial(x+y+z) 1 + q + q^2 + 27*q^3 + q^4 + 6*q^5 + O(q^6) >>> M.gen(0) + M.gen(1) + M.gen(2) 1 + q + q^2 + 27*q^3 + q^4 + 6*q^5 + O(q^6) >>> P = x.parent() >>> M.from_polynomial(P(Integer(1)/Integer(2))) 1/2 - Note that the number of variables must be equal to the number of generators: - sage: x, y = polygens(QQ, 'x, y') sage: M(x + y) Traceback (most recent call last): ... ValueError: the number of variables (2) must be equal to the number of generators of the modular forms ring (3) - >>> from sage.all import * >>> x, y = polygens(QQ, 'x, y') >>> M(x + y) Traceback (most recent call last): ... ValueError: the number of variables (2) must be equal to the number of generators of the modular forms ring (3) 
 - gen(i)[source]¶
- Return the \(i\)-th generator of this ring. - INPUT: - i– integer
 - OUTPUT: an instance of - GradedModularFormElement- EXAMPLES: - sage: M = ModularFormsRing(1) sage: E4 = M.0; E4 # indirect doctest 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: E6 = M.1; E6 # indirect doctest 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> E4 = M.gen(0); E4 # indirect doctest 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> E6 = M.gen(1); E6 # indirect doctest 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) 
 - gen_forms(maxweight=8, start_gens=[], start_weight=2)[source]¶
- Return a list of modular forms generating this ring (as an algebra over the appropriate base ring). - This method differs from - generators()only in that it returns graded modular form objects, rather than bare \(q\)-expansions.- INPUT: - maxweight– integer (default: 8); calculate forms generating all forms up to this weight
- start_gens– list (default:- []); a list of modular forms. If this list is nonempty, we find a minimal generating set containing these forms.
- start_weight– integer (default: 2); calculate the graded subalgebra of forms of weight at least- start_weight
 - Note - If called with the default values of - start_gens(an empty list) and- start_weight(2), the values will be cached for re-use on subsequent calls to this function. (This cache is shared with- generators()). If called with non-default values for these parameters, caching will be disabled.- EXAMPLES: - sage: A = ModularFormsRing(Gamma0(11), Zmod(5)).gen_forms(); A [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), q - 9*q^4 - 10*q^5 + O(q^6)] sage: A[0].parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field - >>> from sage.all import * >>> A = ModularFormsRing(Gamma0(Integer(11)), Zmod(Integer(5))).gen_forms(); A [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), q - 9*q^4 - 10*q^5 + O(q^6)] >>> A[Integer(0)].parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field 
 - generators(maxweight=8, prec=10, start_gens=[], start_weight=2)[source]¶
- Return a list of generator of this ring as a list of pairs \((k, f)\) where \(k\) is an integer and \(f\) is a univariate power series in \(q\) corresponding to the \(q\)-expansion of a modular form of weight \(k\). - More precisely, if \(R\) is the base ring of self, then this function calculates a set of modular forms which generate the \(R\)-algebra of all modular forms of weight up to - maxweightwith coefficients in \(R\).- INPUT: - maxweight– integer (default: 8); check up to this weight for generators
- prec– integer (default: 10); return \(q\)-expansions to this precision
- start_gens– list (default:- []); list of pairs \((k, f)\), or triples \((k, f, F)\), where:- \(k\) is an integer, 
- \(f\) is the \(q\)-expansion of a modular form of weight \(k\), as a power series over the base ring of self, 
- \(F\) (if provided) is a modular form object corresponding to F. 
 - If this list is nonempty, we find a minimal generating set containing these forms. If \(F\) is not supplied, then \(f\) needs to have sufficiently large precision (an error will be raised if this is not the case); otherwise, more terms will be calculated from the modular form object \(F\). 
- start_weight– integer (default: 2); calculate the graded subalgebra of forms of weight at least- start_weight
 - OUTPUT: - a list of pairs (k, f), where f is the \(q\)-expansion to precision - precof a modular form of weight k.- See also - gen_forms(), which does exactly the same thing, but returns Sage modular form objects rather than bare power series, and keeps track of a lifting to characteristic 0 when the base ring is a finite field.- Note - If called with the default values of - start_gens(an empty list) and- start_weight(2), the values will be cached for re-use on subsequent calls to this function. (This cache is shared with- gen_forms()). If called with non-default values for these parameters, caching will be disabled.- EXAMPLES: - sage: ModularFormsRing(SL2Z).generators() [(4, 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + 60480*q^6 + 82560*q^7 + 140400*q^8 + 181680*q^9 + O(q^10)), (6, 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 - 4058208*q^6 - 8471232*q^7 - 17047800*q^8 - 29883672*q^9 + O(q^10))] sage: s = ModularFormsRing(SL2Z).generators(maxweight=5, prec=3); s [(4, 1 + 240*q + 2160*q^2 + O(q^3))] sage: s[0][1].parent() Power Series Ring in q over Rational Field sage: ModularFormsRing(1).generators(prec=4) [(4, 1 + 240*q + 2160*q^2 + 6720*q^3 + O(q^4)), (6, 1 - 504*q - 16632*q^2 - 122976*q^3 + O(q^4))] sage: ModularFormsRing(2).generators(prec=12) [(2, 1 + 24*q + 24*q^2 + 96*q^3 + 24*q^4 + 144*q^5 + 96*q^6 + 192*q^7 + 24*q^8 + 312*q^9 + 144*q^10 + 288*q^11 + O(q^12)), (4, 1 + 240*q^2 + 2160*q^4 + 6720*q^6 + 17520*q^8 + 30240*q^10 + O(q^12))] sage: ModularFormsRing(4).generators(maxweight=2, prec=20) [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + 144*q^10 + 96*q^12 + 192*q^14 + 24*q^16 + 312*q^18 + O(q^20)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + 12*q^11 + 14*q^13 + 24*q^15 + 18*q^17 + 20*q^19 + O(q^20))] - >>> from sage.all import * >>> ModularFormsRing(SL2Z).generators() [(4, 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + 60480*q^6 + 82560*q^7 + 140400*q^8 + 181680*q^9 + O(q^10)), (6, 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 - 4058208*q^6 - 8471232*q^7 - 17047800*q^8 - 29883672*q^9 + O(q^10))] >>> s = ModularFormsRing(SL2Z).generators(maxweight=Integer(5), prec=Integer(3)); s [(4, 1 + 240*q + 2160*q^2 + O(q^3))] >>> s[Integer(0)][Integer(1)].parent() Power Series Ring in q over Rational Field >>> ModularFormsRing(Integer(1)).generators(prec=Integer(4)) [(4, 1 + 240*q + 2160*q^2 + 6720*q^3 + O(q^4)), (6, 1 - 504*q - 16632*q^2 - 122976*q^3 + O(q^4))] >>> ModularFormsRing(Integer(2)).generators(prec=Integer(12)) [(2, 1 + 24*q + 24*q^2 + 96*q^3 + 24*q^4 + 144*q^5 + 96*q^6 + 192*q^7 + 24*q^8 + 312*q^9 + 144*q^10 + 288*q^11 + O(q^12)), (4, 1 + 240*q^2 + 2160*q^4 + 6720*q^6 + 17520*q^8 + 30240*q^10 + O(q^12))] >>> ModularFormsRing(Integer(4)).generators(maxweight=Integer(2), prec=Integer(20)) [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + 144*q^10 + 96*q^12 + 192*q^14 + 24*q^16 + 312*q^18 + O(q^20)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + 12*q^11 + 14*q^13 + 24*q^15 + 18*q^17 + 20*q^19 + O(q^20))] - Here we see that for - \Gamma_0(11)taking a basis of forms in weights 2 and 4 is enough to generate everything up to weight 12 (and probably everything else).:- sage: v = ModularFormsRing(11).generators(maxweight=12) sage: len(v) 3 sage: [k for k, _ in v] [2, 2, 4] sage: from sage.modular.dims import dimension_modular_forms sage: dimension_modular_forms(11,2) 2 sage: dimension_modular_forms(11,4) 4 - >>> from sage.all import * >>> v = ModularFormsRing(Integer(11)).generators(maxweight=Integer(12)) >>> len(v) 3 >>> [k for k, _ in v] [2, 2, 4] >>> from sage.modular.dims import dimension_modular_forms >>> dimension_modular_forms(Integer(11),Integer(2)) 2 >>> dimension_modular_forms(Integer(11),Integer(4)) 4 - For congruence subgroups not containing -1, we miss out some forms since we can’t calculate weight 1 forms at present, but we can still find generators for the ring of forms of weight \(\ge 2\): - sage: ModularFormsRing(Gamma1(4)).generators(prec=10, maxweight=10) [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)), (3, 1 + 12*q^2 + 64*q^3 + 60*q^4 + 160*q^6 + 384*q^7 + 252*q^8 + O(q^10)), (3, q + 4*q^2 + 8*q^3 + 16*q^4 + 26*q^5 + 32*q^6 + 48*q^7 + 64*q^8 + 73*q^9 + O(q^10))] - >>> from sage.all import * >>> ModularFormsRing(Gamma1(Integer(4))).generators(prec=Integer(10), maxweight=Integer(10)) [(2, 1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10)), (2, q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)), (3, 1 + 12*q^2 + 64*q^3 + 60*q^4 + 160*q^6 + 384*q^7 + 252*q^8 + O(q^10)), (3, q + 4*q^2 + 8*q^3 + 16*q^4 + 26*q^5 + 32*q^6 + 48*q^7 + 64*q^8 + 73*q^9 + O(q^10))] - Using different base rings will change the generators: - sage: ModularFormsRing(Gamma0(13)).generators(maxweight=12, prec=4) [(2, 1 + 2*q + 6*q^2 + 8*q^3 + O(q^4)), (4, 1 + O(q^4)), (4, q + O(q^4)), (4, q^2 + O(q^4)), (4, q^3 + O(q^4)), (6, 1 + O(q^4)), (6, q + O(q^4))] sage: ModularFormsRing(Gamma0(13),base_ring=ZZ).generators(maxweight=12, prec=4) [(2, 1 + 2*q + 6*q^2 + 8*q^3 + O(q^4)), (4, q + 4*q^2 + 10*q^3 + O(q^4)), (4, 2*q^2 + 5*q^3 + O(q^4)), (4, q^2 + O(q^4)), (4, -2*q^3 + O(q^4)), (6, O(q^4)), (6, O(q^4)), (12, O(q^4))] sage: [k for k,f in ModularFormsRing(1, QQ).generators(maxweight=12)] [4, 6] sage: [k for k,f in ModularFormsRing(1, ZZ).generators(maxweight=12)] [4, 6, 12] sage: [k for k,f in ModularFormsRing(1, Zmod(5)).generators(maxweight=12)] [4, 6] sage: [k for k,f in ModularFormsRing(1, Zmod(2)).generators(maxweight=12)] [4, 6, 12] - >>> from sage.all import * >>> ModularFormsRing(Gamma0(Integer(13))).generators(maxweight=Integer(12), prec=Integer(4)) [(2, 1 + 2*q + 6*q^2 + 8*q^3 + O(q^4)), (4, 1 + O(q^4)), (4, q + O(q^4)), (4, q^2 + O(q^4)), (4, q^3 + O(q^4)), (6, 1 + O(q^4)), (6, q + O(q^4))] >>> ModularFormsRing(Gamma0(Integer(13)),base_ring=ZZ).generators(maxweight=Integer(12), prec=Integer(4)) [(2, 1 + 2*q + 6*q^2 + 8*q^3 + O(q^4)), (4, q + 4*q^2 + 10*q^3 + O(q^4)), (4, 2*q^2 + 5*q^3 + O(q^4)), (4, q^2 + O(q^4)), (4, -2*q^3 + O(q^4)), (6, O(q^4)), (6, O(q^4)), (12, O(q^4))] >>> [k for k,f in ModularFormsRing(Integer(1), QQ).generators(maxweight=Integer(12))] [4, 6] >>> [k for k,f in ModularFormsRing(Integer(1), ZZ).generators(maxweight=Integer(12))] [4, 6, 12] >>> [k for k,f in ModularFormsRing(Integer(1), Zmod(Integer(5))).generators(maxweight=Integer(12))] [4, 6] >>> [k for k,f in ModularFormsRing(Integer(1), Zmod(Integer(2))).generators(maxweight=Integer(12))] [4, 6, 12] - An example where - start_gensare specified:- sage: M = ModularForms(11, 2); f = (M.0 + M.1).qexp(8) sage: ModularFormsRing(11).generators(start_gens = [(2, f)]) Traceback (most recent call last): ... ValueError: Requested precision cannot be higher than precision of approximate starting generators! sage: f = (M.0 + M.1).qexp(10); f 1 + 17/5*q + 26/5*q^2 + 43/5*q^3 + 94/5*q^4 + 77/5*q^5 + 154/5*q^6 + 86/5*q^7 + 36*q^8 + 146/5*q^9 + O(q^10) sage: ModularFormsRing(11).generators(start_gens = [(2, f)]) [(2, 1 + 17/5*q + 26/5*q^2 + 43/5*q^3 + 94/5*q^4 + 77/5*q^5 + 154/5*q^6 + 86/5*q^7 + 36*q^8 + 146/5*q^9 + O(q^10)), (2, 1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + 24*q^6 + 24*q^7 + 36*q^8 + 36*q^9 + O(q^10)), (4, 1 + O(q^10))] - >>> from sage.all import * >>> M = ModularForms(Integer(11), Integer(2)); f = (M.gen(0) + M.gen(1)).qexp(Integer(8)) >>> ModularFormsRing(Integer(11)).generators(start_gens = [(Integer(2), f)]) Traceback (most recent call last): ... ValueError: Requested precision cannot be higher than precision of approximate starting generators! >>> f = (M.gen(0) + M.gen(1)).qexp(Integer(10)); f 1 + 17/5*q + 26/5*q^2 + 43/5*q^3 + 94/5*q^4 + 77/5*q^5 + 154/5*q^6 + 86/5*q^7 + 36*q^8 + 146/5*q^9 + O(q^10) >>> ModularFormsRing(Integer(11)).generators(start_gens = [(Integer(2), f)]) [(2, 1 + 17/5*q + 26/5*q^2 + 43/5*q^3 + 94/5*q^4 + 77/5*q^5 + 154/5*q^6 + 86/5*q^7 + 36*q^8 + 146/5*q^9 + O(q^10)), (2, 1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + 24*q^6 + 24*q^7 + 36*q^8 + 36*q^9 + O(q^10)), (4, 1 + O(q^10))] 
 - gens(maxweight=8, start_gens=[], start_weight=2)[source]¶
- Return a list of modular forms generating this ring (as an algebra over the appropriate base ring). - This method differs from - generators()only in that it returns graded modular form objects, rather than bare \(q\)-expansions.- INPUT: - maxweight– integer (default: 8); calculate forms generating all forms up to this weight
- start_gens– list (default:- []); a list of modular forms. If this list is nonempty, we find a minimal generating set containing these forms.
- start_weight– integer (default: 2); calculate the graded subalgebra of forms of weight at least- start_weight
 - Note - If called with the default values of - start_gens(an empty list) and- start_weight(2), the values will be cached for re-use on subsequent calls to this function. (This cache is shared with- generators()). If called with non-default values for these parameters, caching will be disabled.- EXAMPLES: - sage: A = ModularFormsRing(Gamma0(11), Zmod(5)).gen_forms(); A [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), q - 9*q^4 - 10*q^5 + O(q^6)] sage: A[0].parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field - >>> from sage.all import * >>> A = ModularFormsRing(Gamma0(Integer(11)), Zmod(Integer(5))).gen_forms(); A [1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6), q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6), q - 9*q^4 - 10*q^5 + O(q^6)] >>> A[Integer(0)].parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field 
 - group()[source]¶
- Return the congruence subgroup of this ring of modular forms. - EXAMPLES: - sage: R = ModularFormsRing(Gamma1(13)) sage: R.group() is Gamma1(13) True - >>> from sage.all import * >>> R = ModularFormsRing(Gamma1(Integer(13))) >>> R.group() is Gamma1(Integer(13)) True 
 - modular_forms_of_weight(weight)[source]¶
- Return the space of modular forms of the given weight and the same congruence subgroup. - EXAMPLES: - sage: R = ModularFormsRing(13) sage: R.modular_forms_of_weight(10) Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(13) of weight 10 over Rational Field sage: ModularFormsRing(Gamma1(13)).modular_forms_of_weight(3) Modular Forms space of dimension 20 for Congruence Subgroup Gamma1(13) of weight 3 over Rational Field - >>> from sage.all import * >>> R = ModularFormsRing(Integer(13)) >>> R.modular_forms_of_weight(Integer(10)) Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(13) of weight 10 over Rational Field >>> ModularFormsRing(Gamma1(Integer(13))).modular_forms_of_weight(Integer(3)) Modular Forms space of dimension 20 for Congruence Subgroup Gamma1(13) of weight 3 over Rational Field 
 - ngens()[source]¶
- Return the number of generators of this ring. - EXAMPLES: - sage: ModularFormsRing(1).ngens() 2 sage: ModularFormsRing(Gamma0(2)).ngens() 2 sage: ModularFormsRing(Gamma1(13)).ngens() # long time 33 - >>> from sage.all import * >>> ModularFormsRing(Integer(1)).ngens() 2 >>> ModularFormsRing(Gamma0(Integer(2))).ngens() 2 >>> ModularFormsRing(Gamma1(Integer(13))).ngens() # long time 33 - Warning - Computing the number of generators of a graded ring of modular form for a certain congruence subgroup can be very long. 
 - one()[source]¶
- Return the one element of this ring. - EXAMPLES: - sage: M = ModularFormsRing(1) sage: u = M.one(); u 1 sage: u.is_one() True sage: u + u 2 sage: E4 = ModularForms(1,4).0; E4 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: E4 * u 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> u = M.one(); u 1 >>> u.is_one() True >>> u + u 2 >>> E4 = ModularForms(Integer(1),Integer(4)).gen(0); E4 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> E4 * u 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) 
 - polynomial_ring(names, gens=None)[source]¶
- Return a polynomial ring of which this ring of modular forms is a quotient. - INPUT: - names– a list or tuple of names (strings), or a comma separated string; consists in the names of the polynomial ring variables
- gens– list of modular forms generating this ring (default:- None); if- gensis- Nonethen the list of generators returned by the method- gen_forms()is used instead. Note that we do not check if the list is indeed a generating set.
 - OUTPUT: a multivariate polynomial ring in the variable - names. Each variable of the polynomial ring correspond to a generator given in the list- gens(following the ordering of the list).- EXAMPLES: - sage: M = ModularFormsRing(1) sage: gens = M.gen_forms() sage: M.polynomial_ring('E4, E6', gens) Multivariate Polynomial Ring in E4, E6 over Rational Field sage: M = ModularFormsRing(Gamma0(8)) sage: gens = M.gen_forms() sage: M.polynomial_ring('g', gens) Multivariate Polynomial Ring in g0, g1, g2 over Rational Field - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> gens = M.gen_forms() >>> M.polynomial_ring('E4, E6', gens) Multivariate Polynomial Ring in E4, E6 over Rational Field >>> M = ModularFormsRing(Gamma0(Integer(8))) >>> gens = M.gen_forms() >>> M.polynomial_ring('g', gens) Multivariate Polynomial Ring in g0, g1, g2 over Rational Field - The degrees of the variables are the weights of the corresponding forms: - sage: M = ModularFormsRing(1) sage: P.<E4, E6> = M.polynomial_ring() sage: E4.degree() 4 sage: E6.degree() 6 sage: (E4*E6).degree() 10 - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> P = M.polynomial_ring(names=('E4', 'E6',)); (E4, E6,) = P._first_ngens(2) >>> E4.degree() 4 >>> E6.degree() 6 >>> (E4*E6).degree() 10 
 - q_expansion_basis(weight, prec=None, use_random=True)[source]¶
- Return a basis of \(q\)-expansions for the space of modular forms of the given weight for this group, calculated using the ring generators given by - find_generators.- INPUT: - weight– the weight
- prec– integer (default:- None); power series precision. If- None, the precision defaults to the Sturm bound for the requested level and weight.
- use_random– boolean (default:- True); whether or not to use a randomized algorithm when building up the space of forms at the given weight from known generators of small weight.
 - EXAMPLES: - sage: m = ModularFormsRing(Gamma0(4)) sage: m.q_expansion_basis(2,10) [1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10), q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)] sage: m.q_expansion_basis(3,10) [] sage: X = ModularFormsRing(SL2Z) sage: X.q_expansion_basis(12, 10) [1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + 34417656000*q^6 + 187489935360*q^7 + 814879774800*q^8 + 2975551488000*q^9 + O(q^10), q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 + O(q^10)] - >>> from sage.all import * >>> m = ModularFormsRing(Gamma0(Integer(4))) >>> m.q_expansion_basis(Integer(2),Integer(10)) [1 + 24*q^2 + 24*q^4 + 96*q^6 + 24*q^8 + O(q^10), q + 4*q^3 + 6*q^5 + 8*q^7 + 13*q^9 + O(q^10)] >>> m.q_expansion_basis(Integer(3),Integer(10)) [] >>> X = ModularFormsRing(SL2Z) >>> X.q_expansion_basis(Integer(12), Integer(10)) [1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + 34417656000*q^6 + 187489935360*q^7 + 814879774800*q^8 + 2975551488000*q^9 + O(q^10), q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + 84480*q^8 - 113643*q^9 + O(q^10)] - We calculate a basis of a massive modular forms space, in two ways. Using this module is about twice as fast as Sage’s generic code. - sage: A = ModularFormsRing(11).q_expansion_basis(30, prec=40) # long time (5s) sage: B = ModularForms(Gamma0(11), 30).q_echelon_basis(prec=40) # long time (9s) sage: A == B # long time True - >>> from sage.all import * >>> A = ModularFormsRing(Integer(11)).q_expansion_basis(Integer(30), prec=Integer(40)) # long time (5s) >>> B = ModularForms(Gamma0(Integer(11)), Integer(30)).q_echelon_basis(prec=Integer(40)) # long time (9s) >>> A == B # long time True - Check that absurdly small values of - precdon’t mess things up:- sage: ModularFormsRing(11).q_expansion_basis(10, prec=5) [1 + O(q^5), q + O(q^5), q^2 + O(q^5), q^3 + O(q^5), q^4 + O(q^5), O(q^5), O(q^5), O(q^5), O(q^5), O(q^5)] - >>> from sage.all import * >>> ModularFormsRing(Integer(11)).q_expansion_basis(Integer(10), prec=Integer(5)) [1 + O(q^5), q + O(q^5), q^2 + O(q^5), q^3 + O(q^5), q^4 + O(q^5), O(q^5), O(q^5), O(q^5), O(q^5), O(q^5)] 
 - some_elements()[source]¶
- Return some elements of this ring. - EXAMPLES: - sage: ModularFormsRing(1).some_elements() [1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)] - >>> from sage.all import * >>> ModularFormsRing(Integer(1)).some_elements() [1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)] 
 - zero()[source]¶
- Return the zero element of this ring. - EXAMPLES: - sage: M = ModularFormsRing(1) sage: zer = M.zero(); zer 0 sage: zer.is_zero() True sage: E4 = ModularForms(1,4).0; E4 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: E4 + zer 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: zer * E4 0 sage: E4 * zer 0 - >>> from sage.all import * >>> M = ModularFormsRing(Integer(1)) >>> zer = M.zero(); zer 0 >>> zer.is_zero() True >>> E4 = ModularForms(Integer(1),Integer(4)).gen(0); E4 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> E4 + zer 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> zer * E4 0 >>> E4 * zer 0