Graded quasimodular forms ring¶
Let
where
The SageMath implementation of the graded ring of quasimodular forms uses the following isomorphism:
where sage.modular.modform.ring.ModularFormsRing
).
More generally, if
The SageMath implementation of the graded quasimodular forms ring allows computation of a set of generators and perform usual arithmetic operations.
EXAMPLES:
sage: QM = QuasiModularForms(1); QM
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
sage: QM.category()
Category of commutative graded algebras over Rational Field
sage: QM.gens()
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
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))
sage: E2 = QM.0; E4 = QM.1; E6 = QM.2
sage: E2 * E4 + E6
2 - 288*q - 20304*q^2 - 185472*q^3 - 855216*q^4 - 2697408*q^5 + O(q^6)
sage: E2.parent()
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
>>> from sage.all import *
>>> QM = QuasiModularForms(Integer(1)); QM
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
>>> QM.category()
Category of commutative graded algebras over Rational Field
>>> QM.gens()
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
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))
>>> E2 = QM.gen(0); E4 = QM.gen(1); E6 = QM.gen(2)
>>> E2 * E4 + E6
2 - 288*q - 20304*q^2 - 185472*q^3 - 855216*q^4 - 2697408*q^5 + O(q^6)
>>> E2.parent()
Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
QM = QuasiModularForms(1); QM QM.category() QM.gens() E2 = QM.0; E4 = QM.1; E6 = QM.2 E2 * E4 + E6 E2.parent()
The polygen
method also return the weight-2 Eisenstein series as a
polynomial variable over the ring of modular forms:
sage: QM = QuasiModularForms(1)
sage: E2 = QM.polygen(); E2
E2
sage: E2.parent()
Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
>>> from sage.all import *
>>> QM = QuasiModularForms(Integer(1))
>>> E2 = QM.polygen(); E2
E2
>>> E2.parent()
Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
QM = QuasiModularForms(1) E2 = QM.polygen(); E2 E2.parent()
An element of a ring of quasimodular forms can be created via a list of modular
forms or graded modular forms. The
sage: QM = QuasiModularForms(1)
sage: E2 = QM.0
sage: Delta = CuspForms(1, 12).0
sage: E4 = ModularForms(1, 4).0
sage: F = QM([Delta, E4, Delta + E4]); F
2 + 410*q - 12696*q^2 - 50424*q^3 + 1076264*q^4 + 10431996*q^5 + O(q^6)
sage: F == Delta + E4 * E2 + (Delta + E4) * E2^2
True
>>> from sage.all import *
>>> QM = QuasiModularForms(Integer(1))
>>> E2 = QM.gen(0)
>>> Delta = CuspForms(Integer(1), Integer(12)).gen(0)
>>> E4 = ModularForms(Integer(1), Integer(4)).gen(0)
>>> F = QM([Delta, E4, Delta + E4]); F
2 + 410*q - 12696*q^2 - 50424*q^3 + 1076264*q^4 + 10431996*q^5 + O(q^6)
>>> F == Delta + E4 * E2 + (Delta + E4) * E2**Integer(2)
True
QM = QuasiModularForms(1) E2 = QM.0 Delta = CuspForms(1, 12).0 E4 = ModularForms(1, 4).0 F = QM([Delta, E4, Delta + E4]); F F == Delta + E4 * E2 + (Delta + E4) * E2^2
One may also create rings of quasimodular forms for certain congruence subgroups:
sage: QM = QuasiModularForms(Gamma0(5)); QM
Ring of Quasimodular Forms for Congruence Subgroup Gamma0(5) over Rational Field
sage: QM.ngens()
4
>>> from sage.all import *
>>> QM = QuasiModularForms(Gamma0(Integer(5))); QM
Ring of Quasimodular Forms for Congruence Subgroup Gamma0(5) over Rational Field
>>> QM.ngens()
4
QM = QuasiModularForms(Gamma0(5)); QM QM.ngens()
The first generator is the weight 2 Eisenstein series:
sage: E2 = QM.0; E2
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
>>> from sage.all import *
>>> E2 = QM.gen(0); E2
1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
E2 = QM.0; E2
The other generators correspond to the generators given by the method
sage.modular.modform.ring.ModularFormsRing.gens()
:
sage: QM.gens()
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
1 + 240*q^5 + O(q^6),
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
sage: QM.modular_forms_subring().gens()
[1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
1 + 240*q^5 + O(q^6),
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6)]
>>> from sage.all import *
>>> QM.gens()
(1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
1 + 240*q^5 + O(q^6),
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
>>> QM.modular_forms_subring().gens()
[1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6),
1 + 240*q^5 + O(q^6),
q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6)]
QM.gens() QM.modular_forms_subring().gens()
It is possible to convert a graded quasimodular form into a polynomial where each variable corresponds to a generator of the ring:
sage: QM = QuasiModularForms(1)
sage: E2, E4, E6 = QM.gens()
sage: F = E2*E4*E6 + E6^2; F
2 - 1296*q + 91584*q^2 + 14591808*q^3 + 464670432*q^4 + 6160281120*q^5 + O(q^6)
sage: p = F.polynomial('E2, E4, E6'); p
E2*E4*E6 + E6^2
sage: P = p.parent(); P
Multivariate Polynomial Ring in E2, E4, E6 over Rational Field
>>> from sage.all import *
>>> QM = QuasiModularForms(Integer(1))
>>> E2, E4, E6 = QM.gens()
>>> F = E2*E4*E6 + E6**Integer(2); F
2 - 1296*q + 91584*q^2 + 14591808*q^3 + 464670432*q^4 + 6160281120*q^5 + O(q^6)
>>> p = F.polynomial('E2, E4, E6'); p
E2*E4*E6 + E6^2
>>> P = p.parent(); P
Multivariate Polynomial Ring in E2, E4, E6 over Rational Field
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() F = E2*E4*E6 + E6^2; F p = F.polynomial('E2, E4, E6'); p P = p.parent(); P
The generators of the polynomial ring have degree equal to the weight of the corresponding form:
sage: P.inject_variables()
Defining E2, E4, E6
sage: E2.degree()
2
sage: E4.degree()
4
sage: E6.degree()
6
>>> from sage.all import *
>>> P.inject_variables()
Defining E2, E4, E6
>>> E2.degree()
2
>>> E4.degree()
4
>>> E6.degree()
6
P.inject_variables() E2.degree() E4.degree() E6.degree()
This works also for congruence subgroup:
sage: QM = QuasiModularForms(Gamma1(4))
sage: QM.ngens()
5
sage: QM.polynomial_ring()
Multivariate Polynomial Ring in E2, E2_0, E2_1, E3_0, E3_1 over Rational Field
sage: (QM.0 + QM.1*QM.0^2 + QM.3 + QM.4^3).polynomial()
E3_1^3 + E2^2*E2_0 + E3_0 + E2
>>> from sage.all import *
>>> QM = QuasiModularForms(Gamma1(Integer(4)))
>>> QM.ngens()
5
>>> QM.polynomial_ring()
Multivariate Polynomial Ring in E2, E2_0, E2_1, E3_0, E3_1 over Rational Field
>>> (QM.gen(0) + QM.gen(1)*QM.gen(0)**Integer(2) + QM.gen(3) + QM.gen(4)**Integer(3)).polynomial()
E3_1^3 + E2^2*E2_0 + E3_0 + E2
QM = QuasiModularForms(Gamma1(4)) QM.ngens() QM.polynomial_ring() (QM.0 + QM.1*QM.0^2 + QM.3 + QM.4^3).polynomial()
One can also convert a multivariate polynomial into a quasimodular form:
sage: QM.polynomial_ring().inject_variables()
Defining E2, E2_0, E2_1, E3_0, E3_1
sage: QM.from_polynomial(E3_1^3 + E2^2*E2_0 + E3_0 + E2)
3 - 72*q + 396*q^2 + 2081*q^3 + 19752*q^4 + 98712*q^5 + O(q^6)
>>> from sage.all import *
>>> QM.polynomial_ring().inject_variables()
Defining E2, E2_0, E2_1, E3_0, E3_1
>>> QM.from_polynomial(E3_1**Integer(3) + E2**Integer(2)*E2_0 + E3_0 + E2)
3 - 72*q + 396*q^2 + 2081*q^3 + 19752*q^4 + 98712*q^5 + O(q^6)
QM.polynomial_ring().inject_variables() QM.from_polynomial(E3_1^3 + E2^2*E2_0 + E3_0 + E2)
Note
Currently, the only supported base ring is the Rational Field;
Spaces of quasimodular forms of fixed weight are not yet implemented.
REFERENCE:
See section 5.3 (page 58) of [Zag2008]
AUTHORS:
David Ayotte (2021-03-18): initial version
- class sage.modular.quasimodform.ring.QuasiModularForms(group=1, base_ring=Rational Field, name='E2')[source]¶
Bases:
Parent
,UniqueRepresentation
The graded ring of quasimodular forms for the full modular group
, with coefficients in a ring.EXAMPLES:
sage: QM = QuasiModularForms(1); QM Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field sage: QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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 * >>> QM = QuasiModularForms(Integer(1)); QM Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field >>> QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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))
QM = QuasiModularForms(1); QM QM.gens()
It is possible to access the weight 2 Eisenstein series:
sage: QM.weight_2_eisenstein_series() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
>>> from sage.all import * >>> QM.weight_2_eisenstein_series() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
QM.weight_2_eisenstein_series()
Currently, the only supported base ring is the rational numbers:
sage: QuasiModularForms(1, GF(5)) Traceback (most recent call last): ... NotImplementedError: base ring other than Q are not yet supported for quasimodular forms ring
>>> from sage.all import * >>> QuasiModularForms(Integer(1), GF(Integer(5))) Traceback (most recent call last): ... NotImplementedError: base ring other than Q are not yet supported for quasimodular forms ring
QuasiModularForms(1, GF(5))
- Element[source]¶
alias of
QuasiModularFormsElement
- basis_of_weight(weight)[source]¶
Return a basis of elements generating the subspace of the given weight.
INPUT:
weight
– integer; the weight of the subspace
OUTPUT: list of quasimodular forms of the given weight
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.basis_of_weight(12) [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6), 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6), 1 - 288*q - 129168*q^2 - 1927296*q^3 + 65152656*q^4 + 1535768640*q^5 + O(q^6), 1 + 432*q + 39312*q^2 - 1711296*q^3 - 14159664*q^4 + 317412000*q^5 + O(q^6), 1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6), 1 + 144*q - 17712*q^2 + 524736*q^3 - 2279088*q^4 - 79760160*q^5 + O(q^6), 1 - 144*q + 8208*q^2 - 225216*q^3 + 2634192*q^4 + 1488672*q^5 + O(q^6)] sage: QM = QuasiModularForms(Gamma1(3)) sage: QM.basis_of_weight(3) [1 + 54*q^2 + 72*q^3 + 432*q^5 + O(q^6), q + 3*q^2 + 9*q^3 + 13*q^4 + 24*q^5 + O(q^6)] sage: QM.basis_of_weight(5) [1 - 90*q^2 - 240*q^3 - 3744*q^5 + O(q^6), q + 15*q^2 + 81*q^3 + 241*q^4 + 624*q^5 + O(q^6), 1 - 24*q - 18*q^2 - 1320*q^3 - 5784*q^4 - 10080*q^5 + O(q^6), q - 21*q^2 - 135*q^3 - 515*q^4 - 1392*q^5 + O(q^6)]
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.basis_of_weight(Integer(12)) [q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6), 1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + 3199218815520/691*q^5 + O(q^6), 1 - 288*q - 129168*q^2 - 1927296*q^3 + 65152656*q^4 + 1535768640*q^5 + O(q^6), 1 + 432*q + 39312*q^2 - 1711296*q^3 - 14159664*q^4 + 317412000*q^5 + O(q^6), 1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6), 1 + 144*q - 17712*q^2 + 524736*q^3 - 2279088*q^4 - 79760160*q^5 + O(q^6), 1 - 144*q + 8208*q^2 - 225216*q^3 + 2634192*q^4 + 1488672*q^5 + O(q^6)] >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> QM.basis_of_weight(Integer(3)) [1 + 54*q^2 + 72*q^3 + 432*q^5 + O(q^6), q + 3*q^2 + 9*q^3 + 13*q^4 + 24*q^5 + O(q^6)] >>> QM.basis_of_weight(Integer(5)) [1 - 90*q^2 - 240*q^3 - 3744*q^5 + O(q^6), q + 15*q^2 + 81*q^3 + 241*q^4 + 624*q^5 + O(q^6), 1 - 24*q - 18*q^2 - 1320*q^3 - 5784*q^4 - 10080*q^5 + O(q^6), q - 21*q^2 - 135*q^3 - 515*q^4 - 1392*q^5 + O(q^6)]
QM = QuasiModularForms(1) QM.basis_of_weight(12) QM = QuasiModularForms(Gamma1(3)) QM.basis_of_weight(3) QM.basis_of_weight(5)
- from_polynomial(polynomial)[source]¶
Convert the given polynomial
to the graded quasiform where the are the generators given bygens()
.INPUT:
polynomial
– a multivariate polynomial
OUTPUT: the graded quasimodular forms
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: P.<x, y, z> = QQ[] sage: QM.from_polynomial(x) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: QM.from_polynomial(x) == QM.0 True sage: QM.from_polynomial(y) == QM.1 True sage: QM.from_polynomial(z) == QM.2 True sage: QM.from_polynomial(x^2 + y + x*z + 1) 4 - 336*q - 2016*q^2 + 322368*q^3 + 3691392*q^4 + 21797280*q^5 + O(q^6) sage: QM = QuasiModularForms(Gamma0(2)) sage: P = QM.polynomial_ring() sage: P.inject_variables() Defining E2, E2_0, E4_0 sage: QM.from_polynomial(E2) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: QM.from_polynomial(E2 + E4_0*E2_0) == QM.0 + QM.2*QM.1 True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> P = QQ['x, y, z']; (x, y, z,) = P._first_ngens(3) >>> QM.from_polynomial(x) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> QM.from_polynomial(x) == QM.gen(0) True >>> QM.from_polynomial(y) == QM.gen(1) True >>> QM.from_polynomial(z) == QM.gen(2) True >>> QM.from_polynomial(x**Integer(2) + y + x*z + Integer(1)) 4 - 336*q - 2016*q^2 + 322368*q^3 + 3691392*q^4 + 21797280*q^5 + O(q^6) >>> QM = QuasiModularForms(Gamma0(Integer(2))) >>> P = QM.polynomial_ring() >>> P.inject_variables() Defining E2, E2_0, E4_0 >>> QM.from_polynomial(E2) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> QM.from_polynomial(E2 + E4_0*E2_0) == QM.gen(0) + QM.gen(2)*QM.gen(1) True
QM = QuasiModularForms(1) P.<x, y, z> = QQ[] QM.from_polynomial(x) QM.from_polynomial(x) == QM.0 QM.from_polynomial(y) == QM.1 QM.from_polynomial(z) == QM.2 QM.from_polynomial(x^2 + y + x*z + 1) QM = QuasiModularForms(Gamma0(2)) P = QM.polynomial_ring() P.inject_variables() QM.from_polynomial(E2) QM.from_polynomial(E2 + E4_0*E2_0) == QM.0 + QM.2*QM.1
Naturally, the number of variable must not exceed the number of generators:
sage: P = PolynomialRing(QQ, 'F', 4) sage: P.inject_variables() Defining F0, F1, F2, F3 sage: QM.from_polynomial(F0 + F1 + F2 + F3) Traceback (most recent call last): ... ValueError: the number of variables (4) of the given polynomial cannot exceed the number of generators (3) of the quasimodular forms ring
>>> from sage.all import * >>> P = PolynomialRing(QQ, 'F', Integer(4)) >>> P.inject_variables() Defining F0, F1, F2, F3 >>> QM.from_polynomial(F0 + F1 + F2 + F3) Traceback (most recent call last): ... ValueError: the number of variables (4) of the given polynomial cannot exceed the number of generators (3) of the quasimodular forms ring
P = PolynomialRing(QQ, 'F', 4) P.inject_variables() QM.from_polynomial(F0 + F1 + F2 + F3)
- gen(n)[source]¶
Return the
-th generator of the quasimodular forms ring.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.0 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: QM.1 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) sage: QM.2 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) sage: QM = QuasiModularForms(5) sage: QM.0 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: QM.1 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6) sage: QM.2 1 + 240*q^5 + O(q^6) sage: QM.3 q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6) sage: QM.4 Traceback (most recent call last): ... IndexError: tuple index out of range
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.gen(0) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> QM.gen(1) 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6) >>> QM.gen(2) 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6) >>> QM = QuasiModularForms(Integer(5)) >>> QM.gen(0) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> QM.gen(1) 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6) >>> QM.gen(2) 1 + 240*q^5 + O(q^6) >>> QM.gen(3) q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6) >>> QM.gen(4) Traceback (most recent call last): ... IndexError: tuple index out of range
QM = QuasiModularForms(1) QM.0 QM.1 QM.2 QM = QuasiModularForms(5) QM.0 QM.1 QM.2 QM.3 QM.4
- generators()[source]¶
Return a tuple of generators of the quasimodular forms ring.
Note that the generators of the modular forms subring are the one given by the method
sage.modular.modform.ring.ModularFormsRing.gen_forms()
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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)) sage: QM.modular_forms_subring().gen_forms() [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)] sage: QM = QuasiModularForms(5) sage: QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6), 1 + 240*q^5 + O(q^6), q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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)) >>> QM.modular_forms_subring().gen_forms() [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)] >>> QM = QuasiModularForms(Integer(5)) >>> QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6), 1 + 240*q^5 + O(q^6), q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
QM = QuasiModularForms(1) QM.gens() QM.modular_forms_subring().gen_forms() QM = QuasiModularForms(5) QM.gens()
An alias of this method is
generators
:sage: QuasiModularForms(1).generators() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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 * >>> QuasiModularForms(Integer(1)).generators() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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))
QuasiModularForms(1).generators()
- gens()[source]¶
Return a tuple of generators of the quasimodular forms ring.
Note that the generators of the modular forms subring are the one given by the method
sage.modular.modform.ring.ModularFormsRing.gen_forms()
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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)) sage: QM.modular_forms_subring().gen_forms() [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)] sage: QM = QuasiModularForms(5) sage: QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6), 1 + 240*q^5 + O(q^6), q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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)) >>> QM.modular_forms_subring().gen_forms() [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)] >>> QM = QuasiModularForms(Integer(5)) >>> QM.gens() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 1 + 6*q + 18*q^2 + 24*q^3 + 42*q^4 + 6*q^5 + O(q^6), 1 + 240*q^5 + O(q^6), q + 10*q^3 + 28*q^4 + 35*q^5 + O(q^6))
QM = QuasiModularForms(1) QM.gens() QM.modular_forms_subring().gen_forms() QM = QuasiModularForms(5) QM.gens()
An alias of this method is
generators
:sage: QuasiModularForms(1).generators() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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 * >>> QuasiModularForms(Integer(1)).generators() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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))
QuasiModularForms(1).generators()
- group()[source]¶
Return the congruence subgroup attached to the given quasimodular forms ring.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.group() Modular Group SL(2,Z) sage: QM.group() is SL2Z True sage: QuasiModularForms(3).group() Congruence Subgroup Gamma0(3) sage: QuasiModularForms(Gamma1(5)).group() Congruence Subgroup Gamma1(5)
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.group() Modular Group SL(2,Z) >>> QM.group() is SL2Z True >>> QuasiModularForms(Integer(3)).group() Congruence Subgroup Gamma0(3) >>> QuasiModularForms(Gamma1(Integer(5))).group() Congruence Subgroup Gamma1(5)
QM = QuasiModularForms(1) QM.group() QM.group() is SL2Z QuasiModularForms(3).group() QuasiModularForms(Gamma1(5)).group()
- modular_forms_of_weight(weight)[source]¶
Return the space of modular forms on this group of the given weight.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.modular_forms_of_weight(12) Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field sage: QM = QuasiModularForms(Gamma1(3)) sage: QM.modular_forms_of_weight(4) Modular Forms space of dimension 2 for Congruence Subgroup Gamma1(3) of weight 4 over Rational Field
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.modular_forms_of_weight(Integer(12)) Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> QM.modular_forms_of_weight(Integer(4)) Modular Forms space of dimension 2 for Congruence Subgroup Gamma1(3) of weight 4 over Rational Field
QM = QuasiModularForms(1) QM.modular_forms_of_weight(12) QM = QuasiModularForms(Gamma1(3)) QM.modular_forms_of_weight(4)
- modular_forms_subring()[source]¶
Return the subring of modular forms of this ring of quasimodular forms.
EXAMPLES:
sage: QuasiModularForms(1).modular_forms_subring() Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field sage: QuasiModularForms(5).modular_forms_subring() Ring of Modular Forms for Congruence Subgroup Gamma0(5) over Rational Field
>>> from sage.all import * >>> QuasiModularForms(Integer(1)).modular_forms_subring() Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field >>> QuasiModularForms(Integer(5)).modular_forms_subring() Ring of Modular Forms for Congruence Subgroup Gamma0(5) over Rational Field
QuasiModularForms(1).modular_forms_subring() QuasiModularForms(5).modular_forms_subring()
- ngens()[source]¶
Return the number of generators of the given graded quasimodular forms ring.
EXAMPLES:
sage: QuasiModularForms(1).ngens() 3
>>> from sage.all import * >>> QuasiModularForms(Integer(1)).ngens() 3
QuasiModularForms(1).ngens()
- one()[source]¶
Return the one element of this ring.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.one() 1 sage: QM.one().is_one() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.one() 1 >>> QM.one().is_one() True
QM = QuasiModularForms(1) QM.one() QM.one().is_one()
- polygen()[source]¶
Return the generator of this quasimodular form space as a polynomial ring over the modular form subring.
Note that this generator correspond to the weight-2 Eisenstein series. The default name of this generator is
E2
.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.polygen() E2 sage: QuasiModularForms(1, name='X').polygen() X sage: QM.polygen().parent() Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.polygen() E2 >>> QuasiModularForms(Integer(1), name='X').polygen() X >>> QM.polygen().parent() Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field
QM = QuasiModularForms(1) QM.polygen() QuasiModularForms(1, name='X').polygen() QM.polygen().parent()
- polynomial_ring(names=None)[source]¶
Return a multivariate polynomial ring of which the quasimodular forms ring is a quotient.
In the case of the full modular group, this ring is
where , and have degrees 2, 4 and 6 respectively.INPUT:
names
– string (default:None
); list or tuple of names (strings), or a comma separated string. Defines the names for the generators of the multivariate polynomial ring. The default names are of the following form:E2
denotes the weight 2 Eisenstein series;Ek_i
andSk_i
denote the -th basis element of the weight Eisenstein subspace and cuspidal subspace respectively;If the level is one, the default names are
E2
,E4
andE6
;In any other cases, we use the letters
Fk
,Gk
,Hk
, …,FFk
,FGk
, … to denote any generator of weight .
OUTPUT: a multivariate polynomial ring in the variables
names
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: P = QM.polynomial_ring(); P Multivariate Polynomial Ring in E2, E4, E6 over Rational Field sage: P.inject_variables() Defining E2, E4, E6 sage: E2.degree() 2 sage: E4.degree() 4 sage: E6.degree() 6
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> P = QM.polynomial_ring(); P Multivariate Polynomial Ring in E2, E4, E6 over Rational Field >>> P.inject_variables() Defining E2, E4, E6 >>> E2.degree() 2 >>> E4.degree() 4 >>> E6.degree() 6
QM = QuasiModularForms(1) P = QM.polynomial_ring(); P P.inject_variables() E2.degree() E4.degree() E6.degree()
Example when the level is not one:
sage: QM = QuasiModularForms(Gamma0(29)) sage: P_29 = QM.polynomial_ring() sage: P_29 Multivariate Polynomial Ring in E2, F2, S2_0, S2_1, E4_0, F4, G4, H4 over Rational Field sage: P_29.inject_variables() Defining E2, F2, S2_0, S2_1, E4_0, F4, G4, H4 sage: F2.degree() 2 sage: E4_0.degree() 4
>>> from sage.all import * >>> QM = QuasiModularForms(Gamma0(Integer(29))) >>> P_29 = QM.polynomial_ring() >>> P_29 Multivariate Polynomial Ring in E2, F2, S2_0, S2_1, E4_0, F4, G4, H4 over Rational Field >>> P_29.inject_variables() Defining E2, F2, S2_0, S2_1, E4_0, F4, G4, H4 >>> F2.degree() 2 >>> E4_0.degree() 4
QM = QuasiModularForms(Gamma0(29)) P_29 = QM.polynomial_ring() P_29 P_29.inject_variables() F2.degree() E4_0.degree()
The name
Sk_i
stands for the -th basis element of the cuspidal subspace of weight :sage: F2 = QM.from_polynomial(S2_0) sage: F2.qexp(10) q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10) sage: CuspForms(Gamma0(29), 2).0.qexp(10) q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10) sage: F2 == CuspForms(Gamma0(29), 2).0 True
>>> from sage.all import * >>> F2 = QM.from_polynomial(S2_0) >>> F2.qexp(Integer(10)) q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10) >>> CuspForms(Gamma0(Integer(29)), Integer(2)).gen(0).qexp(Integer(10)) q - q^4 - q^5 - q^6 + 2*q^7 - 2*q^8 - 2*q^9 + O(q^10) >>> F2 == CuspForms(Gamma0(Integer(29)), Integer(2)).gen(0) True
F2 = QM.from_polynomial(S2_0) F2.qexp(10) CuspForms(Gamma0(29), 2).0.qexp(10) F2 == CuspForms(Gamma0(29), 2).0
The name
Ek_i
stands for the -th basis element of the Eisenstein subspace of weight :sage: F4 = QM.from_polynomial(E4_0) sage: F4.qexp(30) 1 + 240*q^29 + O(q^30) sage: EisensteinForms(Gamma0(29), 4).0.qexp(30) 1 + 240*q^29 + O(q^30) sage: F4 == EisensteinForms(Gamma0(29), 4).0 True
>>> from sage.all import * >>> F4 = QM.from_polynomial(E4_0) >>> F4.qexp(Integer(30)) 1 + 240*q^29 + O(q^30) >>> EisensteinForms(Gamma0(Integer(29)), Integer(4)).gen(0).qexp(Integer(30)) 1 + 240*q^29 + O(q^30) >>> F4 == EisensteinForms(Gamma0(Integer(29)), Integer(4)).gen(0) True
F4 = QM.from_polynomial(E4_0) F4.qexp(30) EisensteinForms(Gamma0(29), 4).0.qexp(30) F4 == EisensteinForms(Gamma0(29), 4).0
One may also choose the name of the variables:
sage: QM = QuasiModularForms(1) sage: QM.polynomial_ring(names="P, Q, R") Multivariate Polynomial Ring in P, Q, R over Rational Field
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.polynomial_ring(names="P, Q, R") Multivariate Polynomial Ring in P, Q, R over Rational Field
QM = QuasiModularForms(1) QM.polynomial_ring(names="P, Q, R")
- quasimodular_forms_of_weight(weight)[source]¶
Return the space of quasimodular forms on this group of the given weight.
INPUT:
weight
– integer
OUTPUT: a quasimodular forms space of the given weight
EXAMPLES:
sage: QuasiModularForms(1).quasimodular_forms_of_weight(4) Traceback (most recent call last): ... NotImplementedError: spaces of quasimodular forms of fixed weight not yet implemented
>>> from sage.all import * >>> QuasiModularForms(Integer(1)).quasimodular_forms_of_weight(Integer(4)) Traceback (most recent call last): ... NotImplementedError: spaces of quasimodular forms of fixed weight not yet implemented
QuasiModularForms(1).quasimodular_forms_of_weight(4)
- some_elements()[source]¶
Return a list of generators of
self
.EXAMPLES:
sage: QuasiModularForms(1).some_elements() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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 * >>> QuasiModularForms(Integer(1)).some_elements() (1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 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))
QuasiModularForms(1).some_elements()
- weight_2_eisenstein_series()[source]¶
Return the weight 2 Eisenstein series.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2 = QM.weight_2_eisenstein_series(); E2 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: E2.parent() Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2 = QM.weight_2_eisenstein_series(); E2 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> E2.parent() Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field
QM = QuasiModularForms(1) E2 = QM.weight_2_eisenstein_series(); E2 E2.parent()
- zero()[source]¶
Return the zero element of this ring.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.zero() 0 sage: QM.zero().is_zero() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.zero() 0 >>> QM.zero().is_zero() True
QM = QuasiModularForms(1) QM.zero() QM.zero().is_zero()