Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions src/sage/modular/modform/find_generators.py

This file was deleted.

1 change: 0 additions & 1 deletion src/sage/modular/modform/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ py.install_sources(
'eis_series_cython.pyx',
'eisenstein_submodule.py',
'element.py',
'find_generators.py',
'half_integral.py',
'hecke_operator_on_qexp.py',
'j_invariant.py',
Expand Down
73 changes: 37 additions & 36 deletions src/sage/modular/modform/ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from sage.matrix.constructor import Matrix
from sage.misc.cachefunc import cached_method
from sage.misc.misc_c import prod
from sage.misc.superseded import deprecated_function_alias
from sage.misc.verbose import verbose
from sage.modular.arithgroup.congroup_gamma0 import Gamma0_constructor as Gamma0
from sage.modular.arithgroup.congroup_generic import CongruenceSubgroupBase
Expand All @@ -46,7 +45,8 @@
from .space import ModularFormsSpace


def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=False):
def _span_of_forms_in_weight(forms, weight, prec,
stop_dim=None, use_random=False):
r"""
Utility function. Given a nonempty list of pairs ``(k,f)``, where `k` is an
integer and `f` is a power series, and a weight l, return all weight l
Expand All @@ -62,10 +62,10 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals
- ``stop_dim`` -- integer; stop as soon as we have enough forms to span
a submodule of this rank (a saturated one if the base ring is `\ZZ`).
Ignored if ``use_random`` is ``False``.
- ``use_random`` -- which algorithm to use. If ``True``, tries random products
of the generators of the appropriate weight until a large enough
submodule is found (determined by ``stop_dim``). If ``False``, just tries
everything.
- ``use_random`` -- which algorithm to use. If ``True``, tries random
products of the generators of the appropriate weight until a
large enough submodule is found (determined by ``stop_dim``). If
``False``, just tries everything.

Note that if the given forms do generate the whole space, then
``use_random=True`` will often be quicker (particularly if the weight is
Expand All @@ -78,7 +78,8 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals
EXAMPLES::

sage: import sage.modular.modform.ring as f
sage: forms = [(4, 240*eisenstein_series_qexp(4,5)), (6,504*eisenstein_series_qexp(6,5))]
sage: forms = [(4, 240*eisenstein_series_qexp(4, 5)),
....: (6, 504*eisenstein_series_qexp(6, 5))]
sage: f._span_of_forms_in_weight(forms, 12, prec=5)
Vector space of degree 5 and dimension 2 over Rational Field
Basis matrix:
Expand Down Expand Up @@ -136,12 +137,13 @@ def _span_of_forms_in_weight(forms, weight, prec, stop_dim=None, use_random=Fals
return W
verbose("Nothing worked", t)
return W
else:
G = [V(prod(forms[i][1]**c[i] for i in range(n)).padded_list(prec)) for c in wts]
t = verbose('found %s candidates' % N, t)
W = V.span(G)
verbose('span has dimension %s' % W.rank(), t)
return W

G = [V(prod(forms[i][1]**c[i] for i in range(n)).padded_list(prec))
for c in wts]
t = verbose(f'found {N} candidates', t)
W = V.span(G)
verbose(f'span has dimension {W.rank()}', t)
return W


@richcmp_method
Expand Down Expand Up @@ -194,7 +196,7 @@ class ModularFormsRing(Parent):

Element = GradedModularFormElement

def __init__(self, group, base_ring=QQ):
def __init__(self, group, base_ring=QQ) -> None:
r"""
INPUT:

Expand Down Expand Up @@ -267,7 +269,7 @@ def change_ring(self, base_ring):
"""
return ModularFormsRing(self.group(), base_ring=base_ring)

def some_elements(self):
def some_elements(self) -> list:
r"""
Return some elements of this ring.

Expand Down Expand Up @@ -313,7 +315,7 @@ def gen(self, i):
raise NotImplementedError("the base ring of the given ring of modular form should be QQ")
return self(self.gen_forms()[i])

def ngens(self):
def ngens(self) -> int:
r"""
Return the number of generators of this ring.

Expand Down Expand Up @@ -473,7 +475,7 @@ def from_polynomial(self, polynomial, gens=None):

* add conversion for symbolic expressions?
"""
if not self.base_ring() == QQ: # this comes from the method gens_form
if not self.base_ring() == QQ: # this comes from the method gens_form
raise NotImplementedError("conversion from polynomial is not implemented if the base ring is not Q")
if not isinstance(polynomial, MPolynomial):
raise TypeError('`polynomial` must be a multivariate polynomial')
Expand Down Expand Up @@ -615,7 +617,7 @@ def _coerce_map_from_(self, M):
return True
return self.base_ring().has_coerce_map_from(M)

def __richcmp__(self, other, op):
def __richcmp__(self, other, op) -> bool:
r"""
Compare ``self`` to ``other``.

Expand All @@ -636,7 +638,7 @@ def __richcmp__(self, other, op):
return richcmp((self.group(), self.base_ring()),
(other.group(), other.base_ring()), op)

def _repr_(self):
def _repr_(self) -> str:
r"""
Return the string representation of ``self``.

Expand Down Expand Up @@ -664,9 +666,10 @@ def modular_forms_of_weight(self, weight):
"""
return ModularForms(self.group(), weight)

def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2):
def generators(self, maxweight=8, prec=10, start_gens=[],
start_weight=2) -> list:
r"""
Return a list of generator of this ring as a list of pairs
Return a list of generators of this ring as a list of pairs
`(k, f)` where `k` is an integer and `f` is a univariate power
series in `q` corresponding to the `q`-expansion of a modular
form of weight `k`.
Expand Down Expand Up @@ -811,15 +814,17 @@ def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2):
if len(x) == 2:
if x[1].prec() < prec:
raise ValueError("Requested precision cannot be higher"
" than precision of approximate starting generators!")
" than precision of approximate starting "
"generators!")
sgs.append((x[0], x[1], None))
else:
sgs.append(x)

G = self._find_generators(maxweight, tuple(sgs), start_weight)

ret = []
# Returned generators may be a funny mixture of precisions if start_gens has been used.
# Returned generators may be a funny mixture of precisions if
# start_gens has been used.
for k, f, F in G:
if f.prec() < prec:
f = F.qexp(prec).change_ring(self.base_ring())
Expand All @@ -829,7 +834,7 @@ def generators(self, maxweight=8, prec=10, start_gens=[], start_weight=2):

return ret

def gen_forms(self, maxweight=8, start_gens=[], start_weight=2):
def gen_forms(self, maxweight=8, start_gens=[], start_weight=2) -> list:
r"""
Return a list of modular forms generating this ring (as an algebra
over the appropriate base ring).
Expand Down Expand Up @@ -872,9 +877,9 @@ def gen_forms(self, maxweight=8, start_gens=[], start_weight=2):

gens = gen_forms

def _find_generators(self, maxweight, start_gens, start_weight):
def _find_generators(self, maxweight, start_gens, start_weight) -> list:
r"""
Returns a list of triples `(k, f, F)` where `F` is a modular
Return a list of triples `(k, f, F)` where `F` is a modular
form of weight `k` and `f` is its `q`-expansion coerced into the
base ring of self.

Expand Down Expand Up @@ -982,7 +987,7 @@ def _find_generators(self, maxweight, start_gens, start_weight):
except AttributeError:
# work around a silly free module bug
qc = V.coordinates(q.lift())
qcZZ = [ZZ(_) for _ in qc] # lift to ZZ so we can define F
qcZZ = [ZZ(_) for _ in qc] # lift to ZZ so we can define F
f = sum([B[i] * qcZZ[i] for i in range(len(B))])
F = M(f)
G.append((k, f.change_ring(self.base_ring()), F))
Expand Down Expand Up @@ -1125,7 +1130,7 @@ def cuspidal_ideal_generators(self, maxweight=8, prec=None):
except AttributeError:
# work around a silly free module bug
qc = V.coordinates(q.lift())
qcZZ = [ZZ(_) for _ in qc] # lift to ZZ so we can define F
qcZZ = [ZZ(_) for _ in qc] # lift to ZZ so we can define F
f = sum([B[i] * qcZZ[i] for i in range(len(B))])
F = S(f)
G.append((k, f.change_ring(self.base_ring()), F))
Expand Down Expand Up @@ -1241,14 +1246,10 @@ def _to_matrix(self, gens=None, prec=None):
gens = self.gen_forms()

if prec is None:
# we don't default to prec=6 because this is an internal function
# and is usually used to write other forms as a linear combination
# of generators, in which case using the Sturm bound is more reasonable
# we do not default to prec=6 because this is an internal
# function and is usually used to write other forms as a
# linear combination of generators, in which case using
# the Sturm bound is more reasonable
prec = max(gen.group().sturm_bound(gen.weight()) for gen in gens)

return Matrix(gen.coefficients(range(prec + 1)) for gen in gens)


# Deprecated functions
find_generators = deprecated_function_alias(31559, ModularFormsRing.generators)
basis_for_modform_space = deprecated_function_alias(31559, ModularFormsRing.q_expansion_basis)
Loading