Elements of quasimodular forms rings¶
AUTHORS:
DAVID AYOTTE (2021-03-18): initial version
Seewoo Lee (2023-09): coefficients method
- class sage.modular.quasimodform.element.QuasiModularFormsElement(parent, polynomial)[source]¶
Bases:
ModuleElement
A quasimodular forms ring element. Such an element is described by SageMath as a polynomial
where each
a graded modular form element (seeGradedModularFormElement
)For an integer
, we say that is homogeneous of weight if it lies in an homogeneous component of degree of the graded ring of quasimodular 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.0 + QM.1 2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6) sage: QM.0 * QM.1 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6) sage: (QM.0)^2 1 - 48*q + 432*q^2 + 3264*q^3 + 9456*q^4 + 21600*q^5 + O(q^6) sage: QM.0 == QM.1 False
>>> 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.gen(0) + QM.gen(1) 2 + 216*q + 2088*q^2 + 6624*q^3 + 17352*q^4 + 30096*q^5 + O(q^6) >>> QM.gen(0) * QM.gen(1) 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6) >>> (QM.gen(0))**Integer(2) 1 - 48*q + 432*q^2 + 3264*q^3 + 9456*q^4 + 21600*q^5 + O(q^6) >>> QM.gen(0) == QM.gen(1) False
QM = QuasiModularForms(1) QM.gens() QM.0 + QM.1 QM.0 * QM.1 (QM.0)^2 QM.0 == QM.1
Quasimodular forms ring element can be created via a polynomial in
over the ring of modular forms:sage: E2 = QM.polygen() sage: E2.parent() Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field sage: QM(E2) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: M = QM.modular_forms_subring() sage: QM(M.0 * E2 + M.1 * E2^2) 2 - 336*q + 4320*q^2 + 398400*q^3 - 3772992*q^4 - 89283168*q^5 + O(q^6)
>>> from sage.all import * >>> E2 = QM.polygen() >>> E2.parent() Univariate Polynomial Ring in E2 over Ring of Modular Forms for Modular Group SL(2,Z) over Rational Field >>> QM(E2) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> M = QM.modular_forms_subring() >>> QM(M.gen(0) * E2 + M.gen(1) * E2**Integer(2)) 2 - 336*q + 4320*q^2 + 398400*q^3 - 3772992*q^4 - 89283168*q^5 + O(q^6)
E2 = QM.polygen() E2.parent() QM(E2) M = QM.modular_forms_subring() QM(M.0 * E2 + M.1 * E2^2)
One may convert a quasimodular form into a multivariate polynomial in the generators of the ring by calling
polynomial()
:sage: QM = QuasiModularForms(1) sage: F = QM.0^2 + QM.1^2 + QM.0*QM.1*QM.2 sage: F.polynomial() E2*E4*E6 + E4^2 + E2^2
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> F = QM.gen(0)**Integer(2) + QM.gen(1)**Integer(2) + QM.gen(0)*QM.gen(1)*QM.gen(2) >>> F.polynomial() E2*E4*E6 + E4^2 + E2^2
QM = QuasiModularForms(1) F = QM.0^2 + QM.1^2 + QM.0*QM.1*QM.2 F.polynomial()
If the group is not the full modular group, the default names of the generators are given by
Ek_i
andSk_i
to denote the -th basis element of the weight Eisenstein subspace and cuspidal subspace respectively (for more details, see the documentation ofpolynomial_ring()
)sage: QM = QuasiModularForms(Gamma1(4)) sage: F = (QM.0^4)*(QM.1^3) + QM.3 sage: F.polynomial() -512*E2^4*E2_1^3 + E2^4*E3_0^2 + 48*E2^4*E3_1^2 + E3_0
>>> from sage.all import * >>> QM = QuasiModularForms(Gamma1(Integer(4))) >>> F = (QM.gen(0)**Integer(4))*(QM.gen(1)**Integer(3)) + QM.gen(3) >>> F.polynomial() -512*E2^4*E2_1^3 + E2^4*E3_0^2 + 48*E2^4*E3_1^2 + E3_0
QM = QuasiModularForms(Gamma1(4)) F = (QM.0^4)*(QM.1^3) + QM.3 F.polynomial()
- coefficients(X)[source]¶
Return the coefficients of
of the -expansion of this, graded quasimodular form for in the list .If X is an integer, return coefficients for indices from 1 to X. This method caches the result.
EXAMPLES:
sage: E2, E4 = QuasiModularForms(1).0, QuasiModularForms(1).1 sage: f = E2^2 sage: g = E2^3 * E4 sage: f.coefficients(10) [-48, 432, 3264, 9456, 21600, 39744, 66432, 105840, 147984, 220320] sage: f.coefficients([0,1]) [1, -48] sage: f.coefficients([0,1,2,3]) [1, -48, 432, 3264] sage: f.coefficients([2,3]) [432, 3264] sage: g.coefficients(10) [168, -13608, 210336, 1805496, -22562064, -322437024, -2063087808, -9165872520, -32250917496, -96383477232] sage: g.coefficients([3, 7]) [210336, -2063087808]
>>> from sage.all import * >>> E2, E4 = QuasiModularForms(Integer(1)).gen(0), QuasiModularForms(Integer(1)).gen(1) >>> f = E2**Integer(2) >>> g = E2**Integer(3) * E4 >>> f.coefficients(Integer(10)) [-48, 432, 3264, 9456, 21600, 39744, 66432, 105840, 147984, 220320] >>> f.coefficients([Integer(0),Integer(1)]) [1, -48] >>> f.coefficients([Integer(0),Integer(1),Integer(2),Integer(3)]) [1, -48, 432, 3264] >>> f.coefficients([Integer(2),Integer(3)]) [432, 3264] >>> g.coefficients(Integer(10)) [168, -13608, 210336, 1805496, -22562064, -322437024, -2063087808, -9165872520, -32250917496, -96383477232] >>> g.coefficients([Integer(3), Integer(7)]) [210336, -2063087808]
E2, E4 = QuasiModularForms(1).0, QuasiModularForms(1).1 f = E2^2 g = E2^3 * E4 f.coefficients(10) f.coefficients([0,1]) f.coefficients([0,1,2,3]) f.coefficients([2,3]) g.coefficients(10) g.coefficients([3, 7])
- degree()[source]¶
Return the weight of the given quasimodular form.
Note that the given form must be homogeneous. An alias of this method is
degree
.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).weight() 2 sage: (QM.0 * QM.1 + QM.2).weight() 6 sage: QM(1/2).weight() 0 sage: (QM.0).degree() 2 sage: (QM.0 + QM.1).weight() Traceback (most recent call last): ... ValueError: the given graded quasiform is not an homogeneous element
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).weight() 2 >>> (QM.gen(0) * QM.gen(1) + QM.gen(2)).weight() 6 >>> QM(Integer(1)/Integer(2)).weight() 0 >>> (QM.gen(0)).degree() 2 >>> (QM.gen(0) + QM.gen(1)).weight() Traceback (most recent call last): ... ValueError: the given graded quasiform is not an homogeneous element
QM = QuasiModularForms(1) (QM.0).weight() (QM.0 * QM.1 + QM.2).weight() QM(1/2).weight() (QM.0).degree() (QM.0 + QM.1).weight()
- depth()[source]¶
Return the depth of this quasimodular form.
Note that the quasimodular form must be homogeneous of weight
. Recall that the depth is the integer such thatwhere
is a modular form of weight and is nonzero.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2, E4, E6 = QM.gens() sage: E2.depth() 1 sage: F = E4^2 + E6*E2 + E4*E2^2 + E2^4 sage: F.depth() 4 sage: QM(7/11).depth() 0
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2, E4, E6 = QM.gens() >>> E2.depth() 1 >>> F = E4**Integer(2) + E6*E2 + E4*E2**Integer(2) + E2**Integer(4) >>> F.depth() 4 >>> QM(Integer(7)/Integer(11)).depth() 0
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() E2.depth() F = E4^2 + E6*E2 + E4*E2^2 + E2^4 F.depth() QM(7/11).depth()
- derivative()[source]¶
Return the derivative
of the given quasimodular form.If the form is not homogeneous, then this method sums the derivative of each homogeneous component.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2, E4, E6 = QM.gens() sage: dE2 = E2.derivative(); dE2 -24*q - 144*q^2 - 288*q^3 - 672*q^4 - 720*q^5 + O(q^6) sage: dE2 == (E2^2 - E4)/12 # Ramanujan identity True sage: dE4 = E4.derivative(); dE4 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6) sage: dE4 == (E2 * E4 - E6)/3 # Ramanujan identity True sage: dE6 = E6.derivative(); dE6 -504*q - 33264*q^2 - 368928*q^3 - 2130912*q^4 - 7877520*q^5 + O(q^6) sage: dE6 == (E2 * E6 - E4^2)/2 # Ramanujan identity True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2, E4, E6 = QM.gens() >>> dE2 = E2.derivative(); dE2 -24*q - 144*q^2 - 288*q^3 - 672*q^4 - 720*q^5 + O(q^6) >>> dE2 == (E2**Integer(2) - E4)/Integer(12) # Ramanujan identity True >>> dE4 = E4.derivative(); dE4 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6) >>> dE4 == (E2 * E4 - E6)/Integer(3) # Ramanujan identity True >>> dE6 = E6.derivative(); dE6 -504*q - 33264*q^2 - 368928*q^3 - 2130912*q^4 - 7877520*q^5 + O(q^6) >>> dE6 == (E2 * E6 - E4**Integer(2))/Integer(2) # Ramanujan identity True
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() dE2 = E2.derivative(); dE2 dE2 == (E2^2 - E4)/12 # Ramanujan identity dE4 = E4.derivative(); dE4 dE4 == (E2 * E4 - E6)/3 # Ramanujan identity dE6 = E6.derivative(); dE6 dE6 == (E2 * E6 - E4^2)/2 # Ramanujan identity
Note that the derivative of a modular form is not necessarily a modular form:
sage: dE4.is_modular_form() False sage: dE4.weight() 6
>>> from sage.all import * >>> dE4.is_modular_form() False >>> dE4.weight() 6
dE4.is_modular_form() dE4.weight()
- homogeneous_component(weight)[source]¶
Return the homogeneous component of the given quasimodular form ring element.
An alias of this method is
homogeneous_component
.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2, E4, E6 = QM.gens() sage: F = E2 + E4*E6 + E2^3*E6 sage: F[2] 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: F[10] 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6) sage: F[12] 1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6) sage: F[4] 0 sage: F.homogeneous_component(2) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2, E4, E6 = QM.gens() >>> F = E2 + E4*E6 + E2**Integer(3)*E6 >>> F[Integer(2)] 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> F[Integer(10)] 1 - 264*q - 135432*q^2 - 5196576*q^3 - 69341448*q^4 - 515625264*q^5 + O(q^6) >>> F[Integer(12)] 1 - 576*q + 21168*q^2 + 308736*q^3 - 15034608*q^4 - 39208320*q^5 + O(q^6) >>> F[Integer(4)] 0 >>> F.homogeneous_component(Integer(2)) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() F = E2 + E4*E6 + E2^3*E6 F[2] F[10] F[12] F[4] F.homogeneous_component(2)
- homogeneous_components()[source]¶
Return a dictionary where the values are the homogeneous components of the given graded form and the keys are the weights of those components.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).homogeneous_components() {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)} sage: (QM.0 + QM.1 + QM.2).homogeneous_components() {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 6: 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)} sage: (1 + QM.0).homogeneous_components() {0: 1, 2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)} sage: QM5 = QuasiModularForms(Gamma1(3)) sage: F = QM.1 + QM.1*QM.2 + QM.1*QM.0 + (QM.1 + QM.2^2)*QM.0^3 sage: F.homogeneous_components() {4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 6: 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6), 10: 2 - 96*q - 149040*q^2 - 4986240*q^3 - 67535952*q^4 - 538187328*q^5 + O(q^6), 18: 1 - 1080*q + 294840*q^2 - 902880*q^3 - 452402280*q^4 + 105456816*q^5 + O(q^6)} sage: F = QM.zero() sage: F.homogeneous_components() {0: 0} sage: F = QM(42/13) sage: F.homogeneous_components() {0: 42/13}
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).homogeneous_components() {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)} >>> (QM.gen(0) + QM.gen(1) + QM.gen(2)).homogeneous_components() {2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6), 4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 6: 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)} >>> (Integer(1) + QM.gen(0)).homogeneous_components() {0: 1, 2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)} >>> QM5 = QuasiModularForms(Gamma1(Integer(3))) >>> F = QM.gen(1) + QM.gen(1)*QM.gen(2) + QM.gen(1)*QM.gen(0) + (QM.gen(1) + QM.gen(2)**Integer(2))*QM.gen(0)**Integer(3) >>> F.homogeneous_components() {4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6), 6: 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6), 10: 2 - 96*q - 149040*q^2 - 4986240*q^3 - 67535952*q^4 - 538187328*q^5 + O(q^6), 18: 1 - 1080*q + 294840*q^2 - 902880*q^3 - 452402280*q^4 + 105456816*q^5 + O(q^6)} >>> F = QM.zero() >>> F.homogeneous_components() {0: 0} >>> F = QM(Integer(42)/Integer(13)) >>> F.homogeneous_components() {0: 42/13}
QM = QuasiModularForms(1) (QM.0).homogeneous_components() (QM.0 + QM.1 + QM.2).homogeneous_components() (1 + QM.0).homogeneous_components() QM5 = QuasiModularForms(Gamma1(3)) F = QM.1 + QM.1*QM.2 + QM.1*QM.0 + (QM.1 + QM.2^2)*QM.0^3 F.homogeneous_components() F = QM.zero() F.homogeneous_components() F = QM(42/13) F.homogeneous_components()
- is_graded_modular_form()[source]¶
Return whether the given quasimodular form is a graded modular form element (see
GradedModularFormElement
).EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).is_graded_modular_form() False sage: (QM.1).is_graded_modular_form() True sage: (QM.1 + QM.0^2).is_graded_modular_form() False sage: (QM.1^2 + QM.2).is_graded_modular_form() True sage: QM = QuasiModularForms(Gamma0(6)) sage: (QM.0).is_graded_modular_form() False sage: (QM.1 + QM.2 + QM.1 * QM.3).is_graded_modular_form() True sage: QM.zero().is_graded_modular_form() True sage: QM = QuasiModularForms(Gamma0(6)) sage: (QM.0).is_graded_modular_form() False sage: (QM.0 + QM.1*QM.2 + QM.3).is_graded_modular_form() False sage: (QM.1*QM.2 + QM.3).is_graded_modular_form() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).is_graded_modular_form() False >>> (QM.gen(1)).is_graded_modular_form() True >>> (QM.gen(1) + QM.gen(0)**Integer(2)).is_graded_modular_form() False >>> (QM.gen(1)**Integer(2) + QM.gen(2)).is_graded_modular_form() True >>> QM = QuasiModularForms(Gamma0(Integer(6))) >>> (QM.gen(0)).is_graded_modular_form() False >>> (QM.gen(1) + QM.gen(2) + QM.gen(1) * QM.gen(3)).is_graded_modular_form() True >>> QM.zero().is_graded_modular_form() True >>> QM = QuasiModularForms(Gamma0(Integer(6))) >>> (QM.gen(0)).is_graded_modular_form() False >>> (QM.gen(0) + QM.gen(1)*QM.gen(2) + QM.gen(3)).is_graded_modular_form() False >>> (QM.gen(1)*QM.gen(2) + QM.gen(3)).is_graded_modular_form() True
QM = QuasiModularForms(1) (QM.0).is_graded_modular_form() (QM.1).is_graded_modular_form() (QM.1 + QM.0^2).is_graded_modular_form() (QM.1^2 + QM.2).is_graded_modular_form() QM = QuasiModularForms(Gamma0(6)) (QM.0).is_graded_modular_form() (QM.1 + QM.2 + QM.1 * QM.3).is_graded_modular_form() QM.zero().is_graded_modular_form() QM = QuasiModularForms(Gamma0(6)) (QM.0).is_graded_modular_form() (QM.0 + QM.1*QM.2 + QM.3).is_graded_modular_form() (QM.1*QM.2 + QM.3).is_graded_modular_form()
Note
A graded modular form in SageMath is not necessarily a modular form as it can have mixed weight components. To check for modular forms only, see the method
is_modular_form()
.
- is_homogeneous()[source]¶
Return whether the graded quasimodular form is a homogeneous element, that is, it lives in a unique graded components of the parent of
self
.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2, E4, E6 = QM.gens() sage: (E2).is_homogeneous() True sage: (E2 + E4).is_homogeneous() False sage: (E2 * E4 + E6).is_homogeneous() True sage: QM(1).is_homogeneous() True sage: (1 + E2).is_homogeneous() False sage: F = E6^3 + E4^4*E2 + (E4^2*E6)*E2^2 + (E4^3 + E6^2)*E2^3 sage: F.is_homogeneous() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2, E4, E6 = QM.gens() >>> (E2).is_homogeneous() True >>> (E2 + E4).is_homogeneous() False >>> (E2 * E4 + E6).is_homogeneous() True >>> QM(Integer(1)).is_homogeneous() True >>> (Integer(1) + E2).is_homogeneous() False >>> F = E6**Integer(3) + E4**Integer(4)*E2 + (E4**Integer(2)*E6)*E2**Integer(2) + (E4**Integer(3) + E6**Integer(2))*E2**Integer(3) >>> F.is_homogeneous() True
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() (E2).is_homogeneous() (E2 + E4).is_homogeneous() (E2 * E4 + E6).is_homogeneous() QM(1).is_homogeneous() (1 + E2).is_homogeneous() F = E6^3 + E4^4*E2 + (E4^2*E6)*E2^2 + (E4^3 + E6^2)*E2^3 F.is_homogeneous()
- is_modular_form()[source]¶
Return whether the given quasimodular form is a modular form.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).is_modular_form() False sage: (QM.1).is_modular_form() True sage: (QM.1 + QM.2).is_modular_form() # mixed weight components False sage: QM.zero().is_modular_form() True sage: QM = QuasiModularForms(Gamma0(4)) sage: (QM.0).is_modular_form() False sage: (QM.1).is_modular_form() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).is_modular_form() False >>> (QM.gen(1)).is_modular_form() True >>> (QM.gen(1) + QM.gen(2)).is_modular_form() # mixed weight components False >>> QM.zero().is_modular_form() True >>> QM = QuasiModularForms(Gamma0(Integer(4))) >>> (QM.gen(0)).is_modular_form() False >>> (QM.gen(1)).is_modular_form() True
QM = QuasiModularForms(1) (QM.0).is_modular_form() (QM.1).is_modular_form() (QM.1 + QM.2).is_modular_form() # mixed weight components QM.zero().is_modular_form() QM = QuasiModularForms(Gamma0(4)) (QM.0).is_modular_form() (QM.1).is_modular_form()
- is_one()[source]¶
Return whether the given quasimodular form is 1, i.e. the multiplicative identity.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.one().is_one() True sage: QM(1).is_one() True sage: (QM.0).is_one() False sage: QM = QuasiModularForms(Gamma0(2)) sage: QM(1).is_one() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.one().is_one() True >>> QM(Integer(1)).is_one() True >>> (QM.gen(0)).is_one() False >>> QM = QuasiModularForms(Gamma0(Integer(2))) >>> QM(Integer(1)).is_one() True
QM = QuasiModularForms(1) QM.one().is_one() QM(1).is_one() (QM.0).is_one() QM = QuasiModularForms(Gamma0(2)) QM(1).is_one()
- is_zero()[source]¶
Return whether the given quasimodular form is zero.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: QM.zero().is_zero() True sage: QM(0).is_zero() True sage: QM(1/2).is_zero() False sage: (QM.0).is_zero() False sage: QM = QuasiModularForms(Gamma0(2)) sage: QM(0).is_zero() True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> QM.zero().is_zero() True >>> QM(Integer(0)).is_zero() True >>> QM(Integer(1)/Integer(2)).is_zero() False >>> (QM.gen(0)).is_zero() False >>> QM = QuasiModularForms(Gamma0(Integer(2))) >>> QM(Integer(0)).is_zero() True
QM = QuasiModularForms(1) QM.zero().is_zero() QM(0).is_zero() QM(1/2).is_zero() (QM.0).is_zero() QM = QuasiModularForms(Gamma0(2)) QM(0).is_zero()
- polynomial(names=None)[source]¶
Return a multivariate polynomial such that every variable corresponds to a generator of the ring, ordered by the method:
gens()
.An alias of this method is
to_polynomial
.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 formABCk
wherek
is a number corresponding to the weight of the formABC
.
OUTPUT: a multivariate polynomial in the variables
names
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0 + QM.1).polynomial() E4 + E2 sage: (1/2 + QM.0 + 2*QM.1^2 + QM.0*QM.2).polynomial() E2*E6 + 2*E4^2 + E2 + 1/2
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0) + QM.gen(1)).polynomial() E4 + E2 >>> (Integer(1)/Integer(2) + QM.gen(0) + Integer(2)*QM.gen(1)**Integer(2) + QM.gen(0)*QM.gen(2)).polynomial() E2*E6 + 2*E4^2 + E2 + 1/2
QM = QuasiModularForms(1) (QM.0 + QM.1).polynomial() (1/2 + QM.0 + 2*QM.1^2 + QM.0*QM.2).polynomial()
Check that Issue #34569 is fixed:
sage: QM = QuasiModularForms(Gamma1(3)) sage: QM.ngens() 5 sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial() E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0
>>> from sage.all import * >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> QM.ngens() 5 >>> (QM.gen(0) + QM.gen(1) + QM.gen(2)*QM.gen(1) + QM.gen(3)*QM.gen(4)).polynomial() E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0
QM = QuasiModularForms(Gamma1(3)) QM.ngens() (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial()
- q_expansion(prec=6)[source]¶
Return the
-expansion of the given quasimodular form up to precisionprec
(default: 6).An alias of this method is
qexp
.EXAMPLES:
sage: QM = QuasiModularForms() sage: E2 = QM.0 sage: E2.q_expansion() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: E2.q_expansion(prec=10) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
>>> from sage.all import * >>> QM = QuasiModularForms() >>> E2 = QM.gen(0) >>> E2.q_expansion() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> E2.q_expansion(prec=Integer(10)) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
QM = QuasiModularForms() E2 = QM.0 E2.q_expansion() E2.q_expansion(prec=10)
- qexp(prec=6)[source]¶
Return the
-expansion of the given quasimodular form up to precisionprec
(default: 6).An alias of this method is
qexp
.EXAMPLES:
sage: QM = QuasiModularForms() sage: E2 = QM.0 sage: E2.q_expansion() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) sage: E2.q_expansion(prec=10) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
>>> from sage.all import * >>> QM = QuasiModularForms() >>> E2 = QM.gen(0) >>> E2.q_expansion() 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6) >>> E2.q_expansion(prec=Integer(10)) 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 - 288*q^6 - 192*q^7 - 360*q^8 - 312*q^9 + O(q^10)
QM = QuasiModularForms() E2 = QM.0 E2.q_expansion() E2.q_expansion(prec=10)
- serre_derivative()[source]¶
Return the Serre derivative of the given quasimodular form.
If the form is not homogeneous, then this method sums the Serre derivative of each homogeneous component.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: E2, E4, E6 = QM.gens() sage: DE2 = E2.serre_derivative(); DE2 -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6) sage: DE2 == (-E2^2 - E4)/12 True sage: DE4 = E4.serre_derivative(); DE4 -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6) sage: DE4 == (-1/3) * E6 True sage: DE6 = E6.serre_derivative(); DE6 -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6) sage: DE6 == (-1/2) * E4^2 True
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> E2, E4, E6 = QM.gens() >>> DE2 = E2.serre_derivative(); DE2 -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6) >>> DE2 == (-E2**Integer(2) - E4)/Integer(12) True >>> DE4 = E4.serre_derivative(); DE4 -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6) >>> DE4 == (-Integer(1)/Integer(3)) * E6 True >>> DE6 = E6.serre_derivative(); DE6 -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6) >>> DE6 == (-Integer(1)/Integer(2)) * E4**Integer(2) True
QM = QuasiModularForms(1) E2, E4, E6 = QM.gens() DE2 = E2.serre_derivative(); DE2 DE2 == (-E2^2 - E4)/12 DE4 = E4.serre_derivative(); DE4 DE4 == (-1/3) * E6 DE6 = E6.serre_derivative(); DE6 DE6 == (-1/2) * E4^2
The Serre derivative raises the weight of homogeneous elements by 2:
sage: F = E6 + E4 * E2 sage: F.weight() 6 sage: F.serre_derivative().weight() 8
>>> from sage.all import * >>> F = E6 + E4 * E2 >>> F.weight() 6 >>> F.serre_derivative().weight() 8
F = E6 + E4 * E2 F.weight() F.serre_derivative().weight()
Check that Issue #34569 is fixed:
sage: QM = QuasiModularForms(Gamma1(3)) sage: E2 = QM.weight_2_eisenstein_series() sage: E2.serre_derivative() -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6) sage: F = QM.0 + QM.1*QM.2
>>> from sage.all import * >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> E2 = QM.weight_2_eisenstein_series() >>> E2.serre_derivative() -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6) >>> F = QM.gen(0) + QM.gen(1)*QM.gen(2)
QM = QuasiModularForms(Gamma1(3)) E2 = QM.weight_2_eisenstein_series() E2.serre_derivative() F = QM.0 + QM.1*QM.2
- to_polynomial(names=None)[source]¶
Return a multivariate polynomial such that every variable corresponds to a generator of the ring, ordered by the method:
gens()
.An alias of this method is
to_polynomial
.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 formABCk
wherek
is a number corresponding to the weight of the formABC
.
OUTPUT: a multivariate polynomial in the variables
names
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0 + QM.1).polynomial() E4 + E2 sage: (1/2 + QM.0 + 2*QM.1^2 + QM.0*QM.2).polynomial() E2*E6 + 2*E4^2 + E2 + 1/2
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0) + QM.gen(1)).polynomial() E4 + E2 >>> (Integer(1)/Integer(2) + QM.gen(0) + Integer(2)*QM.gen(1)**Integer(2) + QM.gen(0)*QM.gen(2)).polynomial() E2*E6 + 2*E4^2 + E2 + 1/2
QM = QuasiModularForms(1) (QM.0 + QM.1).polynomial() (1/2 + QM.0 + 2*QM.1^2 + QM.0*QM.2).polynomial()
Check that Issue #34569 is fixed:
sage: QM = QuasiModularForms(Gamma1(3)) sage: QM.ngens() 5 sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial() E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0
>>> from sage.all import * >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> QM.ngens() 5 >>> (QM.gen(0) + QM.gen(1) + QM.gen(2)*QM.gen(1) + QM.gen(3)*QM.gen(4)).polynomial() E3_1*E4_0 + E2_0*E3_0 + E2 + E2_0
QM = QuasiModularForms(Gamma1(3)) QM.ngens() (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).polynomial()
- weight()[source]¶
Return the weight of the given quasimodular form.
Note that the given form must be homogeneous. An alias of this method is
degree
.EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).weight() 2 sage: (QM.0 * QM.1 + QM.2).weight() 6 sage: QM(1/2).weight() 0 sage: (QM.0).degree() 2 sage: (QM.0 + QM.1).weight() Traceback (most recent call last): ... ValueError: the given graded quasiform is not an homogeneous element
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).weight() 2 >>> (QM.gen(0) * QM.gen(1) + QM.gen(2)).weight() 6 >>> QM(Integer(1)/Integer(2)).weight() 0 >>> (QM.gen(0)).degree() 2 >>> (QM.gen(0) + QM.gen(1)).weight() Traceback (most recent call last): ... ValueError: the given graded quasiform is not an homogeneous element
QM = QuasiModularForms(1) (QM.0).weight() (QM.0 * QM.1 + QM.2).weight() QM(1/2).weight() (QM.0).degree() (QM.0 + QM.1).weight()
- weights_list()[source]¶
Return the list of the weights of all the graded components of the given graded quasimodular form.
EXAMPLES:
sage: QM = QuasiModularForms(1) sage: (QM.0).weights_list() [2] sage: (QM.0 + QM.1 + QM.2).weights_list() [2, 4, 6] sage: (QM.0 * QM.1 + QM.2).weights_list() [6] sage: QM(1/2).weights_list() [0] sage: QM = QuasiModularForms(Gamma1(3)) sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).weights_list() [2, 5, 7]
>>> from sage.all import * >>> QM = QuasiModularForms(Integer(1)) >>> (QM.gen(0)).weights_list() [2] >>> (QM.gen(0) + QM.gen(1) + QM.gen(2)).weights_list() [2, 4, 6] >>> (QM.gen(0) * QM.gen(1) + QM.gen(2)).weights_list() [6] >>> QM(Integer(1)/Integer(2)).weights_list() [0] >>> QM = QuasiModularForms(Gamma1(Integer(3))) >>> (QM.gen(0) + QM.gen(1) + QM.gen(2)*QM.gen(1) + QM.gen(3)*QM.gen(4)).weights_list() [2, 5, 7]
QM = QuasiModularForms(1) (QM.0).weights_list() (QM.0 + QM.1 + QM.2).weights_list() (QM.0 * QM.1 + QM.2).weights_list() QM(1/2).weights_list() QM = QuasiModularForms(Gamma1(3)) (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).weights_list()