Skip to content

Commit 0f0a0d4

Browse files
author
Release Manager
committed
gh-35004: Speed up some methods for quasimodular forms ring elements Fixes #34778 URL: #35004 Reported by: David Ayotte Reviewer(s): Travis Scrimshaw
2 parents a0250df + 19195b2 commit 0f0a0d4

File tree

1 file changed

+49
-25
lines changed

1 file changed

+49
-25
lines changed

src/sage/modular/quasimodform/element.py

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from sage.structure.richcmp import richcmp, op_NE, op_EQ
2626

2727
from sage.rings.polynomial.polynomial_element import Polynomial
28+
from sage.rings.integer_ring import ZZ
2829

2930
class QuasiModularFormsElement(ModuleElement):
3031
r"""
@@ -463,7 +464,7 @@ def weights_list(self):
463464
sage: (QM.0 + QM.1 + QM.2*QM.1 + QM.3*QM.4).weights_list()
464465
[2, 5, 7]
465466
"""
466-
return sorted(list(self.to_polynomial().homogeneous_components()))
467+
return sorted(self.homogeneous_components().keys())
467468

468469
def is_homogeneous(self):
469470
r"""
@@ -474,28 +475,32 @@ def is_homogeneous(self):
474475
EXAMPLES::
475476
476477
sage: QM = QuasiModularForms(1)
477-
sage: (QM.0).is_homogeneous()
478+
sage: E2, E4, E6 = QM.gens()
479+
sage: (E2).is_homogeneous()
478480
True
479-
sage: (QM.0 + QM.1).is_homogeneous()
481+
sage: (E2 + E4).is_homogeneous()
480482
False
481-
sage: (QM.0 * QM.1 + QM.2).is_homogeneous()
483+
sage: (E2 * E4 + E6).is_homogeneous()
482484
True
483485
sage: QM(1).is_homogeneous()
484486
True
485-
sage: (1 + QM.0).is_homogeneous()
487+
sage: (1 + E2).is_homogeneous()
486488
False
487-
sage: QM = QuasiModularForms(Gamma0(4))
488-
sage: (QM.0).is_homogeneous()
489-
True
490-
sage: (QM.0 + QM.1).is_homogeneous()
489+
sage: F = E6^3 + E4^4*E2 + (E4^2*E6)*E2^2 + (E4^3 + E6^2)*E2^3
490+
sage: F.is_homogeneous()
491491
True
492-
sage: (QM.0 + QM.1 + QM.2).is_homogeneous()
493-
True
494-
sage: (QM.0 + QM.1^3).is_homogeneous()
495-
False
496-
497492
"""
498-
return len(self.weights_list()) == 1
493+
k = None
494+
for i, c in enumerate(self._polynomial.coefficients(sparse=False)):
495+
if c:
496+
if not c.is_homogeneous():
497+
return False
498+
if k is None:
499+
k = c.weight() + 2*i
500+
continue
501+
if c.weight() + 2*i != k:
502+
return False
503+
return True
499504

500505
def weight(self):
501506
r"""
@@ -518,9 +523,11 @@ def weight(self):
518523
ValueError: the given graded quasiform is not an homogeneous element
519524
"""
520525
if self.is_homogeneous():
521-
return self.to_polynomial().degree()
526+
return (self._polynomial.leading_coefficient().weight()
527+
+ 2*self._polynomial.degree())
522528
else:
523-
raise ValueError("the given graded quasiform is not an homogeneous element")
529+
raise ValueError("the given graded quasiform is not an homogeneous \
530+
element")
524531

525532
def homogeneous_components(self):
526533
r"""
@@ -538,17 +545,34 @@ def homogeneous_components(self):
538545
6: 1 - 504*q - 16632*q^2 - 122976*q^3 - 532728*q^4 - 1575504*q^5 + O(q^6)}
539546
sage: (1 + QM.0).homogeneous_components()
540547
{0: 1, 2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6)}
541-
sage: QM = QuasiModularForms(Gamma0(5))
542-
sage: F = QM.0 + QM.1 * QM.0 + QM.3^2*QM.0
548+
sage: QM5 = QuasiModularForms(Gamma1(3))
549+
sage: F = QM.1 + QM.1*QM.2 + QM.1*QM.0 + (QM.1 + QM.2^2)*QM.0^3
543550
sage: F.homogeneous_components()
544-
{2: 1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 - 144*q^5 + O(q^6),
545-
4: 1 - 18*q - 198*q^2 - 936*q^3 - 2574*q^4 - 5610*q^5 + O(q^6),
546-
10: q^2 - 24*q^3 - 52*q^4 - 520*q^5 + O(q^6)}
551+
{4: 1 + 240*q + 2160*q^2 + 6720*q^3 + 17520*q^4 + 30240*q^5 + O(q^6),
552+
6: 1 + 216*q - 3672*q^2 - 62496*q^3 - 322488*q^4 - 1121904*q^5 + O(q^6),
553+
10: 2 - 96*q - 149040*q^2 - 4986240*q^3 - 67535952*q^4 - 538187328*q^5 + O(q^6),
554+
18: 1 - 1080*q + 294840*q^2 - 902880*q^3 - 452402280*q^4 + 105456816*q^5 + O(q^6)}
555+
sage: F = QM.zero()
556+
sage: F.homogeneous_components()
557+
{0: 0}
558+
sage: F = QM(42/13)
559+
sage: F.homogeneous_components()
560+
{0: 42/13}
547561
"""
548562
QM = self.parent()
549-
poly_self = self.to_polynomial()
550-
pol_hom_comp = poly_self.homogeneous_components()
551-
return {k: QM.from_polynomial(pol) for k, pol in pol_hom_comp.items()}
563+
if self.is_zero():
564+
return {ZZ(0): self}
565+
components = {}
566+
E2 = self.parent().weight_2_eisenstein_series()
567+
for i, c in enumerate(self._polynomial.coefficients(sparse=False)):
568+
if c:
569+
forms = c._forms_dictionary
570+
for k in forms.keys():
571+
try:
572+
components[ZZ(k + 2*i)] += QM(forms[k]*(E2**i))
573+
except KeyError:
574+
components[ZZ(k + 2*i)] = QM(forms[k]*(E2**i))
575+
return components
552576

553577
def serre_derivative(self):
554578
r"""

0 commit comments

Comments
 (0)