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
\[F = f_0 + f_1 E_2 + f_2 E_2^2 + \cdots + f_m E_2^m\]where each \(f_i\) a graded modular form element (see
GradedModularFormElement
)For an integer \(k\), we say that \(F\) is homogeneous of weight \(k\) if it lies in an homogeneous component of degree \(k\) 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
Quasimodular forms ring element can be created via a polynomial in \(E2\) 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)
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
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 \(i\)-th basis element of the weight \(k\) 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
- coefficients(X)[source]¶
Return the coefficients of \(q^n\) of the \(q\)-expansion of this, graded quasimodular form for \(n\) in the list \(X\).
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]
- 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
- depth()[source]¶
Return the depth of this quasimodular form.
Note that the quasimodular form must be homogeneous of weight \(k\). Recall that the depth is the integer \(p\) such that
\[f = f_0 + f_1 E_2 + \cdots + f_p E_2^p,\]where \(f_i\) is a modular form of weight \(k - 2i\) and \(f_p\) 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
- derivative()[source]¶
Return the derivative \(q \frac{d}{dq}\) 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
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
- 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)
- 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}
- 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
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
- 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
- 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
- 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
- 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
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
- q_expansion(prec=6)[source]¶
Return the \(q\)-expansion of the given quasimodular form up to precision
prec
(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)
- qexp(prec=6)[source]¶
Return the \(q\)-expansion of the given quasimodular form up to precision
prec
(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)
- 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
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
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)
- 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
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
- 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
- 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]