Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix the category of quasi-modular form rings #37797

Merged
merged 2 commits into from
May 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 16 additions & 13 deletions src/sage/modular/quasimodform/ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

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),
Expand Down Expand Up @@ -252,20 +254,21 @@ def __init__(self, group=1, base_ring=QQ, name='E2'):
"""
if not isinstance(name, str):
raise TypeError("`name` must be a string")
#check if the group is SL2(Z)
# check if the group is SL2(Z)
if isinstance(group, (int, Integer)):
group = Gamma0(group)
elif not is_CongruenceSubgroup(group):
raise ValueError("Group (=%s) should be a congruence subgroup" % group)

#Check if the base ring is the rationnal field
# Check if the base ring is the rational field
if base_ring != QQ:
raise NotImplementedError("base ring other than Q are not yet supported for quasimodular forms ring")

self.__group = group
self.__modular_forms_subring = ModularFormsRing(group, base_ring)
self.__polynomial_subring = self.__modular_forms_subring[name]
Parent.__init__(self, base=base_ring, category=GradedAlgebras(base_ring))
cat = GradedAlgebras(base_ring).Commutative()
Parent.__init__(self, base=base_ring, category=cat)

def group(self):
r"""
Expand Down Expand Up @@ -422,15 +425,15 @@ def _element_constructor_(self, datum):
NotImplementedError: conversion from q-expansion not yet implemented
"""
if isinstance(datum, list):
if len(datum) == 0:
if not datum:
raise ValueError("the given list should be non-empty")
for idx, f in enumerate(datum):
if not isinstance(f, (GradedModularFormElement, ModularFormElement)):
raise ValueError("one list element is not a modular form")
datum[idx] = self.__modular_forms_subring(f) #to ensure that every forms is a GradedModularFormElement
datum[idx] = self.__modular_forms_subring(f) # to ensure that every form is a GradedModularFormElement
datum = self.__polynomial_subring(datum)
elif isinstance(datum, (GradedModularFormElement, ModularFormElement)):
datum = self.__modular_forms_subring(datum) # GradedModularFormElement
datum = self.__modular_forms_subring(datum) # GradedModularFormElement
datum = self.__polynomial_subring(datum)
elif isinstance(datum, Polynomial):
datum = self.__polynomial_subring(datum.coefficients(sparse=False))
Expand Down Expand Up @@ -490,7 +493,7 @@ def gens(self):
gen_list.append(self(f))
return gen_list

generators = gens # alias
generators = gens # alias

def ngens(self):
r"""
Expand Down Expand Up @@ -691,7 +694,7 @@ def polynomial_ring(self, names=None):
# the letters E and S are reserved for basis elements of the
# Eisenstein subspaces and cuspidal subspaces respectively.
iter_names = (product(letters, repeat=r)
for r in range(1, len(same_weights)//len(letters) + 2))
for r in range(1, len(same_weights)//len(letters) + 2))
iter_names = chain(*iter_names)
for k in same_weights:
form = next(gens)
Expand All @@ -715,7 +718,7 @@ def polynomial_ring(self, names=None):
else:
name = "".join(next(iter_names)) + str(k)
names.append(name)
weights.insert(0, 2) # add the weight 2 Eisenstein series
weights.insert(0, 2) # add the weight 2 Eisenstein series
return PolynomialRing(self.base_ring(), len(weights), names,
order=TermOrder('wdeglex', weights))

Expand Down Expand Up @@ -778,7 +781,7 @@ def from_polynomial(self, polynomial):
nb_var = poly_parent.ngens()
if nb_var > self.ngens():
raise ValueError("the number of variables (%s) of the given polynomial cannot exceed the number of generators (%s) of the quasimodular forms ring" % (nb_var, self.ngens()))
gens_dict = {poly_parent.gen(i):self.gen(i) for i in range(0, nb_var)}
gens_dict = {poly_parent.gen(i): self.gen(i) for i in range(nb_var)}
return self(polynomial.subs(gens_dict))

def basis_of_weight(self, weight):
Expand Down Expand Up @@ -819,9 +822,9 @@ def basis_of_weight(self, weight):
E2 = self.weight_2_eisenstein_series()
M = self.__modular_forms_subring
E2_pow = self.one()
for j in range(weight//2):
basis += [f*E2_pow for f
in M.modular_forms_of_weight(weight - 2*j).basis()]
for j in range(weight // 2):
basis.extend(f * E2_pow
for f in M.modular_forms_of_weight(weight - 2*j).basis())
E2_pow *= E2
if not weight % 2:
basis.append(E2_pow)
Expand Down