Skip to content

Commit 85ce297

Browse files
author
Release Manager
committed
gh-39474: convert gens method in modular to return tuple and add typing annotation to remember that this is done ### 📝 Checklist - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. URL: #39474 Reported by: Frédéric Chapoton Reviewer(s): Vincent Macri
2 parents c732c65 + f910c56 commit 85ce297

File tree

17 files changed

+149
-148
lines changed

17 files changed

+149
-148
lines changed

src/sage/modular/abvar/finite_subgroup.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,13 @@ def order(self):
579579
self.__order = o
580580
return o
581581

582-
def gens(self):
582+
def gens(self) -> Sequence:
583583
"""
584584
Return generators for this finite subgroup.
585585
586-
EXAMPLES: We list generators for several cuspidal subgroups::
586+
EXAMPLES:
587+
588+
We list generators for several cuspidal subgroups::
587589
588590
sage: J0(11).cuspidal_subgroup().gens()
589591
[[(0, 1/5)]]

src/sage/modular/abvar/homspace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def ngens(self):
508508
self.calculate_generators()
509509
return len(self._gens)
510510

511-
def gens(self):
511+
def gens(self) -> tuple:
512512
"""
513513
Return tuple of generators for this endomorphism ring.
514514

src/sage/modular/dirichlet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,7 +3104,7 @@ def gen(self, n=0):
31043104
return g[n]
31053105

31063106
@cached_method
3107-
def gens(self):
3107+
def gens(self) -> tuple:
31083108
"""
31093109
Return generators of ``self``.
31103110
@@ -3117,7 +3117,7 @@ def gens(self):
31173117
g = []
31183118
ord = self.zeta_order()
31193119
M = self._module
3120-
zero = M(0)
3120+
zero = M.zero()
31213121
orders = self.integers_mod().unit_group().gens_orders()
31223122
for i in range(len(self.unit_gens())):
31233123
z = zero.__copy__()

src/sage/modular/drinfeld_modform/ring.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class DrinfeldModularForms(Parent, UniqueRepresentation):
119119
Use the :meth:`gens` method to obtain the generators of the ring::
120120
121121
sage: M.gens()
122-
[g1, g2, g3]
122+
(g1, g2, g3)
123123
sage: M.inject_variables() # assign the variable g1, g2, g3
124124
Defining g1, g2, g3
125125
sage: T*g1*g2 + g3
@@ -130,23 +130,23 @@ class DrinfeldModularForms(Parent, UniqueRepresentation):
130130
131131
sage: M.<F, G, H> = DrinfeldModularForms(K)
132132
sage: M.gens()
133-
[F, G, H]
133+
(F, G, H)
134134
sage: M = DrinfeldModularForms(K, 5, names='f') # must specify the rank
135135
sage: M.gens()
136-
[f1, f2, f3, f4, f5]
136+
(f1, f2, f3, f4, f5)
137137
sage: M = DrinfeldModularForms(K, names='u, v, w, x')
138138
sage: M.gens()
139-
[u, v, w, x]
139+
(u, v, w, x)
140140
sage: M = DrinfeldModularForms(K, names=['F', 'G', 'H'])
141141
sage: M.gens()
142-
[F, G, H]
142+
(F, G, H)
143143
144144
Set the keyword parameter ``has_type`` to ``True`` in order to create
145145
the ring of Drinfeld modular forms of arbitrary type::
146146
147147
sage: M = DrinfeldModularForms(K, 4, has_type=True)
148148
sage: M.gens()
149-
[g1, g2, g3, h4]
149+
(g1, g2, g3, h4)
150150
sage: h4 = M.3
151151
sage: h4.type()
152152
1
@@ -618,18 +618,18 @@ def gen(self, n):
618618
"""
619619
return self(self._poly_ring.gen(n))
620620

621-
def gens(self):
621+
def gens(self) -> tuple:
622622
r"""
623-
Return a list of generators of this ring.
623+
Return a tuple of generators of this ring.
624624
625625
EXAMPLES::
626626
627627
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
628628
sage: M = DrinfeldModularForms(K, 5)
629629
sage: M.gens()
630-
[g1, g2, g3, g4, g5]
630+
(g1, g2, g3, g4, g5)
631631
"""
632-
return [self(g) for g in self._poly_ring.gens()]
632+
return tuple(self(g) for g in self._poly_ring.gens())
633633

634634
def ngens(self):
635635
r"""

src/sage/modular/drinfeld_modform/tutorial.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
214214
sage: M = DrinfeldModularForms(K, 4, has_type=True)
215215
sage: M.gens()
216-
[g1, g2, g3, h4]
216+
(g1, g2, g3, h4)
217217
sage: h4 = M.3
218218
sage: h4.weight()
219219
40

src/sage/modular/hecke/algebra.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,12 @@ def discriminant(self):
518518
trace_matrix[i, j] = trace_matrix[j, i] = basis[i].matrix().trace_of_product(basis[j].matrix())
519519
return trace_matrix.det()
520520

521-
def gens(self):
521+
def gens(self) -> Iterator:
522522
r"""
523-
Return a generator over all Hecke operator `T_n` for
524-
`n = 1, 2, 3, \ldots`. This is infinite.
523+
Return a generator over all Hecke operator `T_n`
524+
for `n = 1, 2, 3, \ldots`.
525+
526+
This is infinite.
525527
526528
EXAMPLES::
527529

src/sage/modular/hecke/module.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ def factor_number(self):
13411341
except AttributeError:
13421342
return -1
13431343

1344-
def gens(self):
1344+
def gens(self) -> tuple:
13451345
"""
13461346
Return a tuple of basis elements of ``self``.
13471347

src/sage/modular/modform/space.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ def gen(self, n):
13581358
except IndexError:
13591359
raise ValueError("Generator %s not defined" % n)
13601360

1361-
def gens(self):
1361+
def gens(self) -> list:
13621362
"""
13631363
Return a complete set of generators for ``self``.
13641364

src/sage/modular/modform_hecketriangle/abstract_space.py

Lines changed: 44 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ def _canonical_min_exp(self, min_exp, order_1):
13521352

13531353
return (min_exp, order_1)
13541354

1355-
def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()):
1355+
def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()) -> tuple:
13561356
r"""
13571357
Return a basis in ``self`` of the subspace of (quasi) weakly
13581358
holomorphic forms which satisfy the specified properties on
@@ -1391,35 +1391,38 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()
13911391
sage: QF = QuasiWeakModularForms(n=8, k=10/3, ep=-1)
13921392
sage: QF.default_prec(1)
13931393
sage: QF.quasi_part_gens(min_exp=-1)
1394-
[q^-1 + O(q), 1 + O(q), q^-1 - 9/(128*d) + O(q), 1 + O(q), q^-1 - 19/(64*d) + O(q), q^-1 + 1/(64*d) + O(q)]
1394+
(q^-1 + O(q), 1 + O(q), q^-1 - 9/(128*d) + O(q),
1395+
1 + O(q), q^-1 - 19/(64*d) + O(q), q^-1 + 1/(64*d) + O(q))
13951396
13961397
sage: QF.quasi_part_gens(min_exp=-1, max_exp=-1)
1397-
[q^-1 + O(q), q^-1 - 9/(128*d) + O(q), q^-1 - 19/(64*d) + O(q), q^-1 + 1/(64*d) + O(q)]
1398+
(q^-1 + O(q), q^-1 - 9/(128*d) + O(q),
1399+
q^-1 - 19/(64*d) + O(q), q^-1 + 1/(64*d) + O(q))
13981400
sage: QF.quasi_part_gens(min_exp=-2, r=1)
1399-
[q^-2 - 9/(128*d)*q^-1 - 261/(131072*d^2) + O(q), q^-1 - 9/(128*d) + O(q), 1 + O(q)]
1401+
(q^-2 - 9/(128*d)*q^-1 - 261/(131072*d^2) + O(q),
1402+
q^-1 - 9/(128*d) + O(q), 1 + O(q))
14001403
14011404
sage: from sage.modular.modform_hecketriangle.space import ModularForms
14021405
sage: MF = ModularForms(k=36)
14031406
sage: MF.quasi_part_gens(min_exp=2)
1404-
[q^2 + 194184*q^4 + O(q^5), q^3 - 72*q^4 + O(q^5)]
1407+
(q^2 + 194184*q^4 + O(q^5), q^3 - 72*q^4 + O(q^5))
14051408
14061409
sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
14071410
sage: MF = QuasiModularForms(n=5, k=6, ep=-1)
14081411
sage: MF.default_prec(2)
14091412
sage: MF.dimension()
14101413
3
14111414
sage: MF.quasi_part_gens(r=0)
1412-
[1 - 37/(200*d)*q + O(q^2)]
1415+
(1 - 37/(200*d)*q + O(q^2),)
14131416
sage: MF.quasi_part_gens(r=0)[0] == MF.E6()
14141417
True
14151418
sage: MF.quasi_part_gens(r=1)
1416-
[1 + 33/(200*d)*q + O(q^2)]
1419+
(1 + 33/(200*d)*q + O(q^2),)
14171420
sage: MF.quasi_part_gens(r=1)[0] == MF.E2()*MF.E4()
14181421
True
14191422
sage: MF.quasi_part_gens(r=2)
1420-
[]
1423+
()
14211424
sage: MF.quasi_part_gens(r=3)
1422-
[1 - 27/(200*d)*q + O(q^2)]
1425+
(1 - 27/(200*d)*q + O(q^2),)
14231426
sage: MF.quasi_part_gens(r=3)[0] == MF.E2()^3
14241427
True
14251428
@@ -1429,18 +1432,18 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()
14291432
sage: MF.dimension()
14301433
8
14311434
sage: MF.quasi_part_gens(r=0)
1432-
[q - 34743/(640000*d^2)*q^3 + O(q^4), q^2 - 69/(200*d)*q^3 + O(q^4)]
1435+
(q - 34743/(640000*d^2)*q^3 + O(q^4), q^2 - 69/(200*d)*q^3 + O(q^4))
14331436
sage: MF.quasi_part_gens(r=1)
1434-
[q - 9/(200*d)*q^2 + 37633/(640000*d^2)*q^3 + O(q^4),
1435-
q^2 + 1/(200*d)*q^3 + O(q^4)]
1437+
(q - 9/(200*d)*q^2 + 37633/(640000*d^2)*q^3 + O(q^4),
1438+
q^2 + 1/(200*d)*q^3 + O(q^4))
14361439
sage: MF.quasi_part_gens(r=2)
1437-
[q - 1/(4*d)*q^2 - 24903/(640000*d^2)*q^3 + O(q^4)]
1440+
(q - 1/(4*d)*q^2 - 24903/(640000*d^2)*q^3 + O(q^4),)
14381441
sage: MF.quasi_part_gens(r=3)
1439-
[q + 1/(10*d)*q^2 - 7263/(640000*d^2)*q^3 + O(q^4)]
1442+
(q + 1/(10*d)*q^2 - 7263/(640000*d^2)*q^3 + O(q^4),)
14401443
sage: MF.quasi_part_gens(r=4)
1441-
[q - 11/(20*d)*q^2 + 53577/(640000*d^2)*q^3 + O(q^4)]
1444+
(q - 11/(20*d)*q^2 + 53577/(640000*d^2)*q^3 + O(q^4),)
14421445
sage: MF.quasi_part_gens(r=5)
1443-
[q - 1/(5*d)*q^2 + 4017/(640000*d^2)*q^3 + O(q^4)]
1446+
(q - 1/(5*d)*q^2 + 4017/(640000*d^2)*q^3 + O(q^4),)
14441447
14451448
sage: MF.quasi_part_gens(r=1)[0] == MF.E2() * CuspForms(n=5, k=16, ep=1).gen(0)
14461449
True
@@ -1453,64 +1456,61 @@ def quasi_part_gens(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()
14531456
sage: MF.quasi_part_gens(r=1, min_exp=-2) == MF.quasi_part_gens(r=1, min_exp=1)
14541457
True
14551458
sage: MF.quasi_part_gens(r=1)
1456-
[q - 8*q^2 - 8*q^3 + 5952*q^4 + O(q^5),
1459+
(q - 8*q^2 - 8*q^3 + 5952*q^4 + O(q^5),
14571460
q^2 - 8*q^3 + 208*q^4 + O(q^5),
1458-
q^3 - 16*q^4 + O(q^5)]
1461+
q^3 - 16*q^4 + O(q^5))
14591462
14601463
sage: MF = QuasiWeakModularForms(n=infinity, k=4, ep=1)
14611464
sage: MF.quasi_part_gens(r=2, min_exp=2, order_1=-2)[0] == MF.E2()^2 * MF.E4()^(-2) * MF.f_inf()^2
14621465
True
14631466
sage: [v.order_at(-1) for v in MF.quasi_part_gens(r=0, min_exp=2, order_1=-2)]
14641467
[-2, -2]
14651468
"""
1466-
1467-
if (not self.is_weakly_holomorphic()):
1469+
if not self.is_weakly_holomorphic():
14681470
from warnings import warn
14691471
warn("This function only determines generators of (quasi) weakly modular forms!")
14701472

1471-
(min_exp, order_1) = self._canonical_min_exp(min_exp, order_1)
1473+
min_exp, order_1 = self._canonical_min_exp(min_exp, order_1)
14721474

14731475
# For modular forms spaces the quasi parts are all zero except for r=0
1474-
if (self.is_modular()):
1476+
if self.is_modular():
14751477
r = ZZ(r)
1476-
if (r != 0):
1477-
return []
1478+
if r:
1479+
return ()
14781480

14791481
# The lower bounds on the powers of f_inf and E4 determine
14801482
# how large powers of E2 we can fit in...
14811483
n = self.hecke_n()
1482-
if (n == infinity):
1484+
if n == infinity:
14831485
max_numerator_weight = self._weight - 4*min_exp - 4*order_1 + 4
14841486
else:
14851487
max_numerator_weight = self._weight - 4*n/(n-2)*min_exp + 4
14861488

14871489
# If r is not specified we gather all generators for all possible r's
14881490
if r is None:
14891491
gens = []
1490-
for rnew in range(QQ(max_numerator_weight/ZZ(2)).floor() + 1):
1491-
gens += self.quasi_part_gens(r=rnew, min_exp=min_exp, max_exp=max_exp, order_1=order_1)
1492-
return gens
1492+
for rnew in range(QQ(max_numerator_weight / ZZ(2)).floor() + 1):
1493+
gens.extend(self.quasi_part_gens(r=rnew, min_exp=min_exp, max_exp=max_exp, order_1=order_1))
1494+
return tuple(gens)
14931495

14941496
r = ZZ(r)
14951497
if r < 0 or 2*r > max_numerator_weight:
1496-
return []
1498+
return ()
14971499

14981500
E2 = self.E2()
1499-
ambient_weak_space = self.graded_ring().reduce_type("weak", degree=(self._weight-QQ(2*r), self._ep*(-1)**r))
1501+
ambient_weak_space = self.graded_ring().reduce_type("weak",
1502+
degree=(self._weight-QQ(2*r), self._ep*(-1)**r))
15001503
order_inf = ambient_weak_space._l1 - order_1
15011504

1502-
if (max_exp == infinity):
1505+
if max_exp == infinity:
15031506
max_exp = order_inf
1504-
elif (max_exp < min_exp):
1505-
return []
1507+
elif max_exp < min_exp:
1508+
return ()
15061509
else:
15071510
max_exp = min(ZZ(max_exp), order_inf)
15081511

1509-
gens = []
1510-
for m in range(min_exp, max_exp + 1):
1511-
gens += [ self(ambient_weak_space.F_basis(m, order_1=order_1)*E2**r) ]
1512-
1513-
return gens
1512+
return tuple(self(ambient_weak_space.F_basis(m, order_1=order_1) * E2**r)
1513+
for m in range(min_exp, max_exp + 1))
15141514

15151515
def quasi_part_dimension(self, r=None, min_exp=0, max_exp=infinity, order_1=ZZ.zero()):
15161516
r"""
@@ -2096,7 +2096,7 @@ def q_basis(self, m=None, min_exp=0, order_1=ZZ.zero()):
20962096
q^-1 + O(q^5)
20972097
20982098
sage: MF = ModularForms(k=36)
2099-
sage: MF.q_basis() == MF.gens()
2099+
sage: MF.q_basis() == list(MF.gens())
21002100
True
21012101
21022102
sage: QF = QuasiModularForms(k=6)
@@ -2490,11 +2490,11 @@ def ambient_coordinate_vector(self, v):
24902490

24912491
return self.module()(self.ambient_space().coordinate_vector(v))
24922492

2493-
def gens(self):
2493+
def gens(self) -> tuple:
24942494
r"""
24952495
This method should be overloaded by subclasses.
24962496
2497-
Return a basis of ``self``.
2497+
Return a basis of ``self`` as a tuple.
24982498
24992499
Note that the coordinate vector of elements of ``self``
25002500
are with respect to this basis.
@@ -2503,11 +2503,10 @@ def gens(self):
25032503
25042504
sage: from sage.modular.modform_hecketriangle.space import ModularForms
25052505
sage: ModularForms(k=12).gens() # defined in space.py
2506-
[1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + O(q^5),
2507-
q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)]
2506+
(1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + O(q^5),
2507+
q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5))
25082508
"""
2509-
2510-
raise NotImplementedError("No generators are implemented yet for {}!".format(self))
2509+
raise NotImplementedError(f"No generators are implemented yet for {self}!")
25112510

25122511
def gen(self, k=0):
25132512
r"""

src/sage/modular/modform_hecketriangle/readme.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,12 +1015,12 @@
10151015
sage: QF = QuasiWeakModularForms(n=8, k=10/3, ep=-1)
10161016
sage: QF.default_prec(1)
10171017
sage: QF.quasi_part_gens(min_exp=-1)
1018-
[q^-1 + O(q),
1018+
(q^-1 + O(q),
10191019
1 + O(q),
10201020
q^-1 - 9/(128*d) + O(q),
10211021
1 + O(q),
10221022
q^-1 - 19/(64*d) + O(q),
1023-
q^-1 + 1/(64*d) + O(q)]
1023+
q^-1 + 1/(64*d) + O(q))
10241024
sage: QF.default_prec(QF.required_laurent_prec(min_exp=-1))
10251025
sage: QF.q_basis(min_exp=-1) # long time
10261026
[q^-1 + O(q^5),
@@ -1042,9 +1042,9 @@
10421042
3
10431043
sage: MF.default_prec(2)
10441044
sage: MF.gens()
1045-
[1 - 37/(200*d)*q + O(q^2),
1045+
(1 - 37/(200*d)*q + O(q^2),
10461046
1 + 33/(200*d)*q + O(q^2),
1047-
1 - 27/(200*d)*q + O(q^2)]
1047+
1 - 27/(200*d)*q + O(q^2))
10481048
10491049
10501050
- **Coordinate vectors for (quasi) holomorphic modular forms and (quasi) cusp forms:**
@@ -1135,16 +1135,16 @@
11351135
sage: MF.dimension()
11361136
2
11371137
sage: MF.gens()
1138-
[1 + 240*q^2 + 2160*q^4 + O(q^5), q - 8*q^2 + 28*q^3 - 64*q^4 + O(q^5)]
1138+
(1 + 240*q^2 + 2160*q^4 + O(q^5), q - 8*q^2 + 28*q^3 - 64*q^4 + O(q^5))
11391139
sage: E4(i)
11401140
1.941017189...
11411141
sage: E4.order_at(-1)
11421142
1
11431143
11441144
sage: MF = (E2/E4).reduced_parent()
11451145
sage: MF.quasi_part_gens(order_1=-1)
1146-
[1 - 40*q + 552*q^2 - 4896*q^3 + 33320*q^4 + O(q^5),
1147-
1 - 24*q + 264*q^2 - 2016*q^3 + 12264*q^4 + O(q^5)]
1146+
(1 - 40*q + 552*q^2 - 4896*q^3 + 33320*q^4 + O(q^5),
1147+
1 - 24*q + 264*q^2 - 2016*q^3 + 12264*q^4 + O(q^5))
11481148
sage: prec = MF.required_laurent_prec(order_1=-1)
11491149
sage: qexp = (E2/E4).q_expansion(prec=prec)
11501150
sage: qexp

0 commit comments

Comments
 (0)