Skip to content

Commit

Permalink
sagemathgh-39611: remove unused import + pep8 cleanup in modform/element
Browse files Browse the repository at this point in the history
full pep8 cleanup in the modified file

### 📝 Checklist

- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.

URL: sagemath#39611
Reported by: Frédéric Chapoton
Reviewer(s): David Coudert
  • Loading branch information
Release Manager committed Mar 1, 2025
2 parents ea71572 + dd3e94c commit 0b9512b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 64 deletions.
4 changes: 2 additions & 2 deletions build/pkgs/configure/checksums.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
tarball=configure-VERSION.tar.gz
sha1=e093bc99c7c72359d0ea6afd49046133607fe391
sha256=2d5d04f26068b2c8aafd1e3b69e23ae2788390846f779e5714df6856ce89cde1
sha1=503dae4c3c6942acac45ff1123aa0ce4977e4faf
sha256=b70de96b09a283dbfb4de5e9ccba3c06930dc73c6bbe8e1c45926361b8e19b90
2 changes: 1 addition & 1 deletion build/pkgs/configure/package-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
77c4e9b745daab99cdc0e2e989515a6f4ec91ed9
81a1239cce3b275c7fcf72d5b2d343d21add05dc
120 changes: 59 additions & 61 deletions src/sage/modular/modform/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@
from sage.structure.element import coercion_model, ModuleElement, Element
from sage.structure.richcmp import richcmp, op_NE, op_EQ

lazy_import('sage.combinat.integer_vector_weighted', 'WeightedIntegerVectors')
lazy_import('sage.rings.number_field.number_field_morphisms', 'NumberFieldEmbedding')

import sage.modular.hecke.element as element
from . import defaults

lazy_import('sage.combinat.integer_vector_weighted', 'WeightedIntegerVectors')
lazy_import('sage.rings.number_field.number_field_morphisms', 'NumberFieldEmbedding')


def is_ModularFormElement(x):
"""
Expand Down Expand Up @@ -337,7 +337,6 @@ def __call__(self, x, prec=None):
sage: f(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36
429.19994832206294278688085399056359632 - 786.15736284188243351153830824852974995*I
"""
from sage.rings.integer import Integer
from sage.misc.functional import log
from sage.structure.element import parent
from sage.rings.complex_mpfr import ComplexNumber
Expand All @@ -357,7 +356,7 @@ def __call__(self, x, prec=None):
if not isinstance(x, (RealNumber, ComplexNumber)):
x = CC(x) # might lose precision if this is done unconditionally (TODO what about interval and ball types?)
if isinstance(x, (RealNumber, ComplexNumber)):
return self.eval_at_tau(log(x)/(2*parent(x)(pi)*I)) # cast to parent(x) to force numerical evaluation of pi
return self.eval_at_tau(log(x) / (2 * parent(x)(pi) * I)) # cast to parent(x) to force numerical evaluation of pi
return self.q_expansion(prec)(x)

def eval_at_tau(self, tau):
Expand Down Expand Up @@ -393,7 +392,6 @@ def eval_at_tau(self, tau):
sage: f.eval_at_tau(ComplexField(128)(1+2*I)/3 + x - x) # rel tol 1e-36
-1.0451570582202060056197878314286036966 + 2.7225112098519803098203933583286590274*I
"""
from sage.libs.pari.convert_sage import gen_to_sage
from sage.libs.pari import pari
from sage.rings.cc import CC
from sage.rings.complex_mpfr import ComplexNumber, ComplexField
Expand Down Expand Up @@ -582,9 +580,9 @@ def __getitem__(self, n):
if n.stop is None:
return self.q_expansion().list()[n]
else:
return self.q_expansion(n.stop+1).list()[n]
return self.q_expansion(n.stop + 1).list()[n]
else:
return self.q_expansion(n+1)[int(n)]
return self.q_expansion(n + 1)[int(n)]

def coefficient(self, n):
r"""
Expand All @@ -610,7 +608,7 @@ def coefficient(self, n):
-1472
"""
n = ZZ(n)
return self.q_expansion(n+1)[n]
return self.q_expansion(n + 1)[n]

def padded_list(self, n):
"""
Expand Down Expand Up @@ -995,11 +993,11 @@ def period(self, M, prec=53):

M = self.group()(M)
# coefficients of the matrix M
(b, c, d) = (M.b(), M.c() / N, M.d())
b, c, d = (M.b(), M.c() / N, M.d())
if d == 0:
return R.zero()
if d < 0:
(b, c, d) = (-b, -c, -d)
b, c, d = (-b, -c, -d)

twopi = 2 * R.pi()
I = R.complex_field().gen()
Expand Down Expand Up @@ -1191,13 +1189,13 @@ def lseries(self, embedding=0, prec=53, max_imaginary_part=0,
# Find out how many coefficients of the Dirichlet series are needed
# in order to compute to the required precision
num_coeffs = L.num_coeffs()
coeffs = self.q_expansion(num_coeffs+1).padded_list()[1:]
coeffs = self.q_expansion(num_coeffs + 1).padded_list()[1:]

# renormalize so that coefficient of q is 1
b = coeffs[0]
if b != 1:
invb = 1/b
coeffs = (invb*c for c in coeffs)
invb = 1 / b
coeffs = (invb * c for c in coeffs)

v = [emb(c) for c in coeffs]
w = [c.conjugate() for c in v]
Expand Down Expand Up @@ -1308,7 +1306,7 @@ def symsquare_lseries(self, chi=None, embedding=0, prec=53):

# utility function for Dirichlet convolution of series
def dirichlet_convolution(A, B):
return [sum(A[d-1] * B[n/d - 1] for d in divisors(n))
return [sum(A[d - 1] * B[n // d - 1] for d in divisors(n))
for n in range(1, 1 + min(len(A), len(B)))]

# The Dirichlet series for \zeta(2 s - 2 k + 2)
Expand Down Expand Up @@ -1387,7 +1385,7 @@ def petersson_norm(self, embedding=0, prec=53):
pi = RealField(prec).pi()
L = self.symsquare_lseries(prec=prec, embedding=embedding)
k = self.weight()
return (ZZ(k - 1).factorial() / 2**(2*k - 1) / pi**(k+1)) * L(k).real_part()
return (ZZ(k - 1).factorial() / 2**(2 * k - 1) / pi**(k + 1)) * L(k).real_part()

def _q_expansion_bound(self, eps):
r"""
Expand Down Expand Up @@ -1435,7 +1433,7 @@ def _q_expansion_bound(self, eps):
chi.conductor() * eps.conductor()])
y = QQ(self.weight()) / QQ(12) * M
for p in M.prime_divisors():
y *= (1 + 1/QQ(p))
y *= (1 + 1 / QQ(p))
return y.ceil()

@cached_method
Expand Down Expand Up @@ -1973,12 +1971,12 @@ def _atkin_lehner_eigenvalue_from_qexp(self, Q):
a2
"""
if Q == 1:
return ZZ(1)
return ZZ.one()
a_Q = self[Q]
if not a_Q:
raise ValueError("a_Q must be nonzero")

l = ZZ(1)
l = ZZ.one()
M = self.character().conductor()
for p, e in Q.factor():
if p.divides(M): # principal series at p
Expand Down Expand Up @@ -2013,7 +2011,7 @@ def _atkin_lehner_eigenvalue_from_modsym(self, Q):
True
"""
if Q == 1:
return ZZ(1)
return ZZ.one()

S = self._defining_modular_symbols()
A = S.ambient()
Expand All @@ -2031,16 +2029,16 @@ def _atkin_lehner_eigenvalue_from_modsym(self, Q):
continue
aa = crt(a, 1, Q, N.prime_to_m_part(Q))
diam = matrix(ZZ, 2, lift_to_sl2z(0, aa, N))
L.append((W * diam * matrix(QQ, 2, [1, a/Q0, 0, 1])).change_ring(ZZ))
L.append((W * diam * matrix(QQ, 2, [1, a / Q0, 0, 1])).change_ring(ZZ))

W = A._matrix_of_operator_on_modular_symbols(A, [x.list() for x in L])
e = S.dual_eigenvector(names=self._name())
i = e.nonzero_positions()[0]
w = (W*e)[i]/e[i]
w = (W * e)[i] / e[i]
if W * e != w * e:
raise ArithmeticError("Bug in Atkin--Lehner computation: eigenspace not invariant")
sign = prod([eps(-1) for eps in self.character().decomposition() if eps.conductor().divides(Q)])
return w / Q0 / sign * self.character()(crt(1, Q//Q0, Q, N//Q))
return w / Q0 / sign * self.character()(crt(1, Q // Q0, Q, N // Q))

def atkin_lehner_action(self, d=None, normalization='analytic', embedding=None):
r"""
Expand Down Expand Up @@ -2303,7 +2301,7 @@ def atkin_lehner_eigenvalue(self, d=None, normalization='analytic', embedding=No
w3a = self._atkin_lehner_eigenvalue_from_modsym(d3)
w3b = self._atkin_lehner_eigenvalue_from_qexp(d3)
assert w3a == w3b
w = w1*w2*w3a
w = w1 * w2 * w3a

if embedding is None:
R = self.hecke_eigenvalue_field()
Expand All @@ -2328,9 +2326,9 @@ def atkin_lehner_eigenvalue(self, d=None, normalization='analytic', embedding=No
raise ValueError("Unable to compute Gauss sum. Try specifying an embedding into a larger ring")
else:
G = R(1)
if not R(d**(self.weight()-2)).is_square():
if not R(d**(self.weight() - 2)).is_square():
raise ValueError("Unable to compute square root. Try specifying an embedding into a larger ring")
ratio = R(d**(self.weight()-2)).sqrt() * embedding(self.character()(crt(1, d//d0, d, N//d))) / G
ratio = R(d**(self.weight() - 2)).sqrt() * embedding(self.character()(crt(1, d // d0, d, N // d))) / G
return embedding(w) / ratio

def twist(self, chi, level=None, check=True):
Expand Down Expand Up @@ -2441,8 +2439,8 @@ def twist(self, chi, level=None, check=True):
alpha = N_epsilon.valuation(q)
beta = N_chi.valuation(q)
gamma = N.valuation(q)
delta = max(alpha + beta, 2*beta, gamma)
if delta == gamma and max(alpha + beta, 2*beta) < gamma:
delta = max(alpha + beta, 2 * beta, gamma)
if delta == gamma and max(alpha + beta, 2 * beta) < gamma:
continue
if delta > gamma and N_epsilon_chi.valuation(q) == max(alpha, beta):
continue
Expand All @@ -2462,7 +2460,7 @@ def twist(self, chi, level=None, check=True):
for p in prime_range(500):
if p.divides(chi.level()):
continue
D = (D.hecke_operator(p) - self[p]*chi(p)).kernel()
D = (D.hecke_operator(p) - self[p] * chi(p)).kernel()
if D.rank() == 1:
break
if D.is_zero():
Expand Down Expand Up @@ -2502,11 +2500,11 @@ def minimal_twist(self, p=None):
if p is None:
# test local minimality at all primes
for p in self.level().prime_divisors():
(g, chi) = self.minimal_twist(p)
g, chi = self.minimal_twist(p)
if g.level() < self.level():
h, tau = g.minimal_twist(p=None)
M = chi.modulus().lcm(tau.modulus())
return (h, chi.extend(M)*tau.extend(M))
return (h, chi.extend(M) * tau.extend(M))
# f locally minimal at all p, hence globally minimal
return (self, DirichletGroup(1, self.base_ring())(1))

Expand All @@ -2520,27 +2518,27 @@ def minimal_twist(self, p=None):
if (r == c) or (r == 1 and c == 0):
# easy cases
return (self, DirichletGroup(1, self.base_ring())(1))
elif r < 2*c:
elif r < 2 * c:
# In this case we know that there is a unique chi of conductor p^u
# such that self x chi has level N/p^u, where u = r-c, and this
# twist is minimal.
candidates = []
for chi in DirichletGroup(p**(r-c), self.base_ring()):
for chi in DirichletGroup(p**(r - c), self.base_ring()):
if not chi.is_primitive():
continue
try:
g = self.twist(chi, level=N//p**(r-c))
g = self.twist(chi, level=N // p**(r - c))
candidates.append((g, chi))
except ValueError:
continue

l = ZZ(1)
l = ZZ.one()
while len(candidates) > 1:
l = l.next_prime()
if l == p:
continue
candidates = [(h, chi) for (h, chi) in candidates if h[l] == chi(l)*self[l]]
if l > 10000 or len(candidates) == 0:
candidates = [(h, chi) for (h, chi) in candidates if h[l] == chi(l) * self[l]]
if l > 10000 or not candidates:
raise RuntimeError("bug finding minimal twist")
return candidates[0]
else:
Expand All @@ -2552,27 +2550,27 @@ def minimal_twist(self, p=None):
T = TypeSpace(self, p)
if T.is_minimal():
return (self, DirichletGroup(1, self.base_ring())(1))

g = T.minimal_twist()
epsg = g.character().extend(N)
chisq = (epsg / self.character()).restrict(p**(r // 2))
K = coercion_model.common_parent(self.base_ring(), g.base_ring())
chis = [chi for chi in DirichletGroup(p**(r // 2), K) if chi**2 == chisq]

if g.has_cm() and g.cm_discriminant().prime_divisors() == [p]:
# Quicker to test g than self, because g has smaller level.
t = 2
else:
g = T.minimal_twist()
epsg = g.character().extend(N)
chisq = (epsg / self.character()).restrict(p**(r//2))
K = coercion_model.common_parent(self.base_ring(), g.base_ring())
chis = [chi for chi in DirichletGroup(p**(r//2), K) if chi**2 == chisq]

if g.has_cm() and g.cm_discriminant().prime_divisors() == [p]:
# Quicker to test g than self, because g has smaller level.
t = 2
else:
t = 1
l = ZZ(1)
while len(chis) > t:
l = l.next_prime()
if l == p:
continue
chis = [chi for chi in chis if g[l] == chi(l) * self[l] ]
if l > 10000 or len(chis) == 0:
raise RuntimeError("bug finding minimal twist")
return (g, chis[0])
t = 1
l = ZZ.one()
while len(chis) > t:
l = l.next_prime()
if l == p:
continue
chis = [chi for chi in chis if g[l] == chi(l) * self[l]]
if l > 10000 or not chis:
raise RuntimeError("bug finding minimal twist")
return (g, chis[0])

def local_component(self, p, twist_factor=None):
"""
Expand Down Expand Up @@ -3498,7 +3496,7 @@ def __init__(self, parent, forms_datum):
else:
raise ValueError('the group and/or the base ring of at least one modular form (%s) is not consistant with the base space' % (f))
else:
forms_dictionary[ZZ(0)] = parent.base_ring().coerce(f)
forms_dictionary[ZZ.zero()] = parent.base_ring().coerce(f)
else:
raise TypeError('the defining data structure should be a list or a dictionary')
self._forms_dictionary = {k: f for k, f in forms_dictionary.items() if not f.is_zero()} # remove the zero values
Expand Down Expand Up @@ -3840,7 +3838,7 @@ def _lmul_(self, c):
"""
GM = self.__class__
f_self = self._forms_dictionary
f_mul = {k: c*f for k, f in f_self.items()}
f_mul = {k: c * f for k, f in f_self.items()}
return GM(self.parent(), f_mul)

def _richcmp_(self, other, op):
Expand Down Expand Up @@ -3898,7 +3896,7 @@ def weight(self):
"""
if self.is_homogeneous():
if self.is_zero():
return ZZ(0)
return ZZ.zero()
return next(iter(self._forms_dictionary))
else:
raise ValueError("the given graded form is not homogeneous (not a modular form)")
Expand All @@ -3920,7 +3918,7 @@ def weights_list(self):
[0]
"""
if self.is_zero():
return [ZZ(0)]
return [ZZ.zero()]
return sorted(self._forms_dictionary)

def is_homogeneous(self):
Expand Down

0 comments on commit 0b9512b

Please sign in to comment.