Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modular/hecke/algebra.py
8820 views
1
"""
2
Hecke algebras
3
4
In Sage a "Hecke algebra" always refers to an algebra of endomorphisms of some
5
explicit module, rather than the abstract Hecke algebra of double cosets
6
attached to a subgroup of the modular group.
7
8
We distinguish between "anemic Hecke algebras", which are algebras of Hecke
9
operators whose indices do not divide some integer N (the level), and "full
10
Hecke algebras", which include Hecke operators coprime to the level. Morphisms
11
in the category of Hecke modules are not required to commute with the action of
12
the full Hecke algebra, only with the anemic algebra.
13
"""
14
15
#*****************************************************************************
16
# Copyright (C) 2004 William Stein <[email protected]>
17
#
18
# Distributed under the terms of the GNU General Public License (GPL)
19
#
20
# This code is distributed in the hope that it will be useful,
21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
# General Public License for more details.
24
#
25
# The full text of the GPL is available at:
26
#
27
# http://www.gnu.org/licenses/
28
#*****************************************************************************
29
30
31
import weakref
32
33
import sage.rings.arith as arith
34
import sage.rings.infinity
35
import sage.misc.latex as latex
36
import module
37
import hecke_operator
38
import sage.rings.commutative_algebra
39
from sage.matrix.constructor import matrix
40
from sage.rings.arith import lcm
41
from sage.matrix.matrix_space import MatrixSpace
42
from sage.rings.all import ZZ, QQ
43
from sage.structure.element import Element
44
45
def is_HeckeAlgebra(x):
46
r"""
47
Return True if x is of type HeckeAlgebra.
48
49
EXAMPLES::
50
51
sage: from sage.modular.hecke.algebra import is_HeckeAlgebra
52
sage: is_HeckeAlgebra(CuspForms(1, 12).anemic_hecke_algebra())
53
True
54
sage: is_HeckeAlgebra(ZZ)
55
False
56
"""
57
return isinstance(x, HeckeAlgebra_base)
58
59
# The basis_matrix stuff here is a workaround for a subtle bug discovered by
60
# me (David Loeffler) 2009-04-13. The problem is that if one creates two
61
# subspaces of a Hecke module which are equal as subspaces but have different
62
# bases, then the caching machinery needs to distinguish between them.
63
64
# The AttributeError occurs in two distinct ways: if M is not a free module
65
# over its base ring, it might not have a basis_matrix method; and for
66
# SupersingularModule objects, the basis_matrix method exists but raises an
67
# error -- this is a known bug (#4306).
68
69
# See the doctest for the __call__ method below, which tests that this caching
70
# is working as it should.
71
72
_anemic_cache = {}
73
def AnemicHeckeAlgebra(M):
74
r"""
75
Return the anemic Hecke algebra associated to the Hecke module
76
M. This checks whether or not the object already exists in memory,
77
and if so, returns the existing object rather than a new one.
78
79
EXAMPLES::
80
81
sage: CuspForms(1, 12).anemic_hecke_algebra() # indirect doctest
82
Anemic Hecke algebra acting on Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
83
84
We test uniqueness::
85
86
sage: CuspForms(1, 12).anemic_hecke_algebra() is CuspForms(1, 12).anemic_hecke_algebra()
87
True
88
89
We can't ensure uniqueness when loading and saving objects from files, but we can ensure equality::
90
91
sage: CuspForms(1, 12).anemic_hecke_algebra() is loads(dumps(CuspForms(1, 12).anemic_hecke_algebra()))
92
False
93
sage: CuspForms(1, 12).anemic_hecke_algebra() == loads(dumps(CuspForms(1, 12).anemic_hecke_algebra()))
94
True
95
"""
96
97
try:
98
k = (M, M.basis_matrix())
99
except AttributeError:
100
k = M
101
if _anemic_cache.has_key(k):
102
T = _anemic_cache[k]()
103
if not (T is None):
104
return T
105
T = HeckeAlgebra_anemic(M)
106
_anemic_cache[k] = weakref.ref(T)
107
return T
108
109
_cache = {}
110
def HeckeAlgebra(M):
111
"""
112
Return the full Hecke algebra associated to the Hecke module
113
M. This checks whether or not the object already exists in memory,
114
and if so, returns the existing object rather than a new one.
115
116
EXAMPLES::
117
118
sage: CuspForms(1, 12).hecke_algebra() # indirect doctest
119
Full Hecke algebra acting on Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
120
121
We test uniqueness::
122
123
sage: CuspForms(1, 12).hecke_algebra() is CuspForms(1, 12).hecke_algebra()
124
True
125
126
We can't ensure uniqueness when loading and saving objects from files, but we can ensure equality::
127
128
sage: CuspForms(1, 12).hecke_algebra() is loads(dumps(CuspForms(1, 12).hecke_algebra()))
129
False
130
sage: CuspForms(1, 12).hecke_algebra() == loads(dumps(CuspForms(1, 12).hecke_algebra()))
131
True
132
"""
133
try:
134
k = (M, M.basis_matrix())
135
except AttributeError:
136
k = M
137
if _cache.has_key(k):
138
T = _cache[k]()
139
if not (T is None):
140
return T
141
T = HeckeAlgebra_full(M)
142
_cache[k] = weakref.ref(T)
143
return T
144
145
146
def _heckebasis(M):
147
r"""
148
Gives a basis of the hecke algebra of M as a ZZ-module
149
150
INPUT:
151
152
- ``M`` - a hecke module
153
154
OUTPUT:
155
156
- a list of hecke algebra elements represented as matrices
157
158
EXAMPLES::
159
160
sage: M = ModularSymbols(11,2,1)
161
sage: sage.modular.hecke.algebra._heckebasis(M)
162
[Hecke operator on Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field defined by:
163
[1 0]
164
[0 1],
165
Hecke operator on Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field defined by:
166
[0 1]
167
[0 5]]
168
"""
169
d = M.rank()
170
VV = QQ**(d**2)
171
WW = ZZ**(d**2)
172
MM = MatrixSpace(QQ,d)
173
MMZ = MatrixSpace(ZZ,d)
174
S = []; Denom = []; B = []; B1 = []
175
for i in xrange(1, M.hecke_bound() + 1):
176
v = M.hecke_operator(i).matrix()
177
den = v.denominator()
178
Denom.append(den)
179
S.append(v)
180
den = lcm(Denom)
181
for m in S:
182
B.append(WW((den*m).list()))
183
UU = WW.submodule(B)
184
B = UU.basis()
185
for u in B:
186
u1 = u.list()
187
m1 = M.hecke_algebra()(MM(u1), check=False)
188
#m1 = MM(u1)
189
B1.append((1/den)*m1)
190
return B1
191
192
193
class HeckeAlgebra_base(sage.rings.commutative_algebra.CommutativeAlgebra):
194
"""
195
Base class for algebras of Hecke operators on a fixed Hecke module.
196
"""
197
def __init__(self, M):
198
"""
199
INPUT:
200
201
- ``M`` - a Hecke module
202
203
EXAMPLE::
204
205
sage: CuspForms(1, 12).hecke_algebra() # indirect doctest
206
Full Hecke algebra acting on Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
207
"""
208
if not module.is_HeckeModule(M):
209
raise TypeError, "M (=%s) must be a HeckeModule"%M
210
self.__M = M
211
sage.rings.commutative_algebra.CommutativeAlgebra.__init__(self, M.base_ring())
212
213
def _an_element_impl(self):
214
r"""
215
Return an element of this algebra. Used by the coercion machinery.
216
217
EXAMPLE::
218
219
sage: CuspForms(1, 12).hecke_algebra().an_element() # indirect doctest
220
Hecke operator T_2 on Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Modular Group SL(2,Z) of weight 12 over Rational Field
221
"""
222
return self.hecke_operator(self.level() + 1)
223
224
def __call__(self, x, check=True):
225
r"""
226
Convert x into an element of this Hecke algebra. Here x is either:
227
228
- an element of a Hecke algebra equal to this one
229
230
- an element of the corresponding anemic Hecke algebra, if x is a full
231
Hecke algebra
232
233
- an element of the corresponding full Hecke algebra of the
234
form `T_i` where i is coprime to ``self.level()``, if self
235
is an anemic Hecke algebra
236
237
- something that can be converted into an element of the
238
underlying matrix space.
239
240
In the last case, the parameter ``check'' controls whether or
241
not to check that this element really does lie in the
242
appropriate algebra. At present, setting ``check=True'' raises
243
a NotImplementedError unless x is a scalar (or a diagonal
244
matrix).
245
246
EXAMPLES::
247
248
sage: T = ModularSymbols(11).hecke_algebra()
249
sage: T.gen(2) in T
250
True
251
sage: 5 in T
252
True
253
sage: T.gen(2).matrix() in T
254
Traceback (most recent call last):
255
...
256
NotImplementedError: Membership testing for '...' not implemented
257
sage: T(T.gen(2).matrix(), check=False)
258
Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field defined by:
259
[ 3 0 -1]
260
[ 0 -2 0]
261
[ 0 0 -2]
262
sage: A = ModularSymbols(11).anemic_hecke_algebra()
263
sage: A(T.gen(3))
264
Hecke operator T_3 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
265
sage: A(T.gen(11))
266
Traceback (most recent call last):
267
...
268
TypeError: Don't know how to construct an element of Anemic Hecke algebra acting on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field from Hecke operator T_11 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
269
270
TESTS:
271
272
We test that coercion is OK between the Hecke algebras associated to two submodules which are equal but have different bases::
273
274
sage: M = CuspForms(Gamma0(57))
275
sage: f1,f2,f3 = M.newforms()
276
sage: N1 = M.submodule(M.free_module().submodule_with_basis([f1.element().element(), f2.element().element()]))
277
sage: N2 = M.submodule(M.free_module().submodule_with_basis([f1.element().element(), (f1.element() + f2.element()).element()]))
278
sage: N1.hecke_operator(5).matrix_form()
279
Hecke operator on Modular Forms subspace of dimension 2 of ... defined by:
280
[-3 0]
281
[ 0 1]
282
sage: N2.hecke_operator(5).matrix_form()
283
Hecke operator on Modular Forms subspace of dimension 2 of ... defined by:
284
[-3 0]
285
[-4 1]
286
sage: N1.hecke_algebra()(N2.hecke_operator(5)).matrix_form()
287
Hecke operator on Modular Forms subspace of dimension 2 of ... defined by:
288
[-3 0]
289
[ 0 1]
290
sage: N1.hecke_algebra()(N2.hecke_operator(5).matrix_form())
291
Hecke operator on Modular Forms subspace of dimension 2 of ... defined by:
292
[-3 0]
293
[ 0 1]
294
"""
295
try:
296
if not isinstance(x, Element):
297
x = self.base_ring()(x)
298
if x.parent() is self:
299
return x
300
elif hecke_operator.is_HeckeOperator(x):
301
if x.parent() == self \
302
or (self.is_anemic() == False and x.parent() == self.anemic_subalgebra()) \
303
or (self.is_anemic() == True and x.parent().anemic_subalgebra() == self and arith.gcd(x.index(), self.level()) == 1):
304
return hecke_operator.HeckeOperator(self, x.index())
305
else:
306
raise TypeError
307
elif hecke_operator.is_HeckeAlgebraElement(x):
308
if x.parent() == self or (self.is_anemic() == False and x.parent() == self.anemic_subalgebra()):
309
if x.parent().module().basis_matrix() == self.module().basis_matrix():
310
return hecke_operator.HeckeAlgebraElement_matrix(self, x.matrix())
311
else:
312
A = matrix([self.module().coordinate_vector(x.parent().module().gen(i)) \
313
for i in xrange(x.parent().module().rank())])
314
return hecke_operator.HeckeAlgebraElement_matrix(self, ~A * x.matrix() * A)
315
elif x.parent() == self.anemic_subalgebra():
316
pass
317
318
else:
319
raise TypeError
320
else:
321
A = self.matrix_space()(x)
322
if check:
323
if not A.is_scalar():
324
raise NotImplementedError, "Membership testing for '%s' not implemented" % self
325
return hecke_operator.HeckeAlgebraElement_matrix(self, A)
326
327
except TypeError:
328
raise TypeError, "Don't know how to construct an element of %s from %s" % (self, x)
329
330
def _coerce_impl(self, x):
331
r"""
332
Implicit coercion of x into this Hecke algebra. The only things that
333
coerce implicitly into self are: elements of Hecke algebras which are
334
equal to self, or to the anemic subalgebra of self if self is not
335
anemic; and elements that coerce into the base ring of self. Bare
336
matrices do *not* coerce implicitly into self.
337
338
EXAMPLE::
339
340
sage: C = CuspForms(3, 12)
341
sage: A = C.anemic_hecke_algebra()
342
sage: F = C.hecke_algebra()
343
sage: F.coerce(A.2) # indirect doctest
344
Hecke operator T_2 on Cuspidal subspace of dimension 3 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(3) of weight 12 over Rational Field
345
"""
346
if x.parent() == self or (self.is_anemic() == False and x.parent() == self.anemic_subalgebra()):
347
return self(x)
348
else:
349
return self(self.matrix_space()(1) * self.base_ring().coerce(x))
350
#return self._coerce_try(x, self.matrix_space())
351
352
def gen(self, n):
353
"""
354
Return the `n`-th Hecke operator.
355
356
EXAMPLES::
357
358
sage: T = ModularSymbols(11).hecke_algebra()
359
sage: T.gen(2)
360
Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
361
"""
362
return self.hecke_operator(n)
363
364
def ngens(self):
365
r"""
366
The size of the set of generators returned by gens(), which is clearly
367
infinity. (This is not necessarily a minimal set of generators.)
368
369
EXAMPLES::
370
371
sage: CuspForms(1, 12).anemic_hecke_algebra().ngens()
372
+Infinity
373
"""
374
return sage.rings.infinity.infinity
375
376
def is_noetherian(self):
377
"""
378
Return True if this Hecke algebra is Noetherian as a ring. This is true
379
if and only if the base ring is Noetherian.
380
381
EXAMPLES::
382
383
sage: CuspForms(1, 12).anemic_hecke_algebra().is_noetherian()
384
True
385
"""
386
return self.base_ring().is_noetherian()
387
388
def matrix_space(self):
389
r"""
390
Return the underlying matrix space of this module.
391
392
EXAMPLES::
393
394
sage: CuspForms(3, 24, base_ring=Qp(5)).anemic_hecke_algebra().matrix_space()
395
Full MatrixSpace of 7 by 7 dense matrices over 5-adic Field with capped relative precision 20
396
"""
397
try:
398
return self.__matrix_space_cache
399
except AttributeError:
400
self.__matrix_space_cache = sage.matrix.matrix_space.MatrixSpace(
401
self.base_ring(), self.module().rank())
402
return self.__matrix_space_cache
403
404
def _latex_(self):
405
r"""
406
LaTeX representation of self.
407
408
EXAMPLES::
409
410
sage: latex(CuspForms(3, 24).hecke_algebra()) # indirect doctest
411
\mathbf{T}_{\text{\texttt{Cuspidal...Gamma0(3)...24...}
412
"""
413
from sage.misc.latex import latex
414
return "\\mathbf{T}_{%s}" % latex(self.__M)
415
416
def level(self):
417
r"""
418
Return the level of this Hecke algebra, which is (by definition) the
419
level of the Hecke module on which it acts.
420
421
EXAMPLE::
422
423
sage: ModularSymbols(37).hecke_algebra().level()
424
37
425
"""
426
return self.module().level()
427
428
def module(self):
429
"""
430
The Hecke module on which this algebra is acting.
431
432
EXAMPLES::
433
434
sage: T = ModularSymbols(1,12).hecke_algebra()
435
sage: T.module()
436
Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
437
"""
438
return self.__M
439
440
def rank(self):
441
r"""
442
The rank of this Hecke algebra as a module over its base
443
ring. Not implemented at present.
444
445
EXAMPLE::
446
447
sage: ModularSymbols(Gamma1(3), 3).hecke_algebra().rank()
448
Traceback (most recent call last):
449
...
450
NotImplementedError
451
"""
452
raise NotImplementedError
453
454
def basis(self):
455
r"""
456
Return a basis for this Hecke algebra as a free module over
457
its base ring.
458
459
EXAMPLE::
460
461
sage: ModularSymbols(Gamma1(3), 3).hecke_algebra().basis()
462
[Hecke operator on Modular Symbols space of dimension 2 for Gamma_1(3) of weight 3 with sign 0 and over Rational Field defined by:
463
[1 0]
464
[0 1],
465
Hecke operator on Modular Symbols space of dimension 2 for Gamma_1(3) of weight 3 with sign 0 and over Rational Field defined by:
466
[0 0]
467
[0 2]]
468
"""
469
try:
470
return self.__basis_cache
471
except AttributeError:
472
pass
473
level = self.level()
474
bound = self.__M.hecke_bound()
475
dim = self.__M.rank()
476
if dim == 0:
477
basis = []
478
elif dim == 1:
479
basis = [self.hecke_operator(1)]
480
else:
481
span = [self.hecke_operator(n) for n in range(1, bound+1) if not self.is_anemic() or gcd(n, level) == 1]
482
rand_max = 5
483
while True:
484
# Project the full Hecke module to a random submodule to ease the HNF reduction.
485
v = (ZZ**dim).random_element(x=rand_max)
486
proj_span = matrix([T.matrix()*v for T in span])._clear_denom()[0]
487
proj_basis = proj_span.hermite_form()
488
if proj_basis[dim-1] == 0:
489
# We got unlucky, choose another projection.
490
rand_max *= 2
491
continue
492
# Lift the projected basis to a basis in the Hecke algebra.
493
trans = proj_span.solve_left(proj_basis)
494
basis = [sum(c*T for c,T in zip(row,span) if c != 0) for row in trans[:dim]]
495
break
496
497
self.__basis_cache = tuple(basis)
498
return basis
499
500
def discriminant(self):
501
r"""
502
Return the discriminant of this Hecke algebra, i.e. the
503
determinant of the matrix `{\rm Tr}(x_i x_j)` where `x_1,
504
\dots,x_d` is a basis for self, and `{\rm Tr}(x)` signifies
505
the trace (in the sense of linear algebra) of left
506
multiplication by `x` on the algebra (*not* the trace of the
507
operator `x` acting on the underlying Hecke module!). For
508
further discussion and conjectures see Calegari + Stein,
509
*Conjectures about discriminants of Hecke algebras of prime
510
level*, Springer LNCS 3076.
511
512
EXAMPLE::
513
514
sage: BrandtModule(3, 4).hecke_algebra().discriminant()
515
1
516
sage: ModularSymbols(65, sign=1).cuspidal_submodule().hecke_algebra().discriminant()
517
6144
518
sage: ModularSymbols(1,4,sign=1).cuspidal_submodule().hecke_algebra().discriminant()
519
1
520
sage: H = CuspForms(1, 24).hecke_algebra()
521
sage: H.discriminant()
522
83041344
523
"""
524
try:
525
return self.__disc
526
except AttributeError:
527
pass
528
basis = self.basis()
529
d = len(basis)
530
if d <= 1:
531
self.__disc = ZZ(1)
532
return self.__disc
533
trace_matrix = matrix(ZZ, d)
534
for i in range(d):
535
for j in range(i+1):
536
trace_matrix[i,j] = trace_matrix[j,i] = basis[i].matrix().trace_of_product(basis[j].matrix())
537
self.__disc = trace_matrix.det()
538
return self.__disc
539
540
def gens(self):
541
r"""
542
Return a generator over all Hecke operator `T_n` for
543
`n = 1, 2, 3, \ldots`. This is infinite.
544
545
EXAMPLES::
546
547
sage: T = ModularSymbols(1,12).hecke_algebra()
548
sage: g = T.gens()
549
sage: g.next()
550
Hecke operator T_1 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
551
sage: g.next()
552
Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
553
"""
554
n = 1
555
while True:
556
yield self.hecke_operator(n)
557
n += 1
558
559
def hecke_operator(self, n):
560
"""
561
Return the `n`-th Hecke operator `T_n`.
562
563
EXAMPLES::
564
565
sage: T = ModularSymbols(1,12).hecke_algebra()
566
sage: T.hecke_operator(2)
567
Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
568
"""
569
try:
570
return self.__hecke_operator[n]
571
except AttributeError:
572
self.__hecke_operator = {}
573
except KeyError:
574
pass
575
n = int(n)
576
T = self.__M._hecke_operator_class()(self, n)
577
self.__hecke_operator[n] = T
578
return T
579
580
def hecke_matrix(self, n, *args, **kwds):
581
"""
582
Return the matrix of the n-th Hecke operator `T_n`.
583
584
EXAMPLES::
585
586
sage: T = ModularSymbols(1,12).hecke_algebra()
587
sage: T.hecke_matrix(2)
588
[ -24 0 0]
589
[ 0 -24 0]
590
[4860 0 2049]
591
"""
592
return self.__M.hecke_matrix(n, *args, **kwds)
593
594
def diamond_bracket_matrix(self, d):
595
r"""
596
Return the matrix of the diamond bracket operator `\langle d \rangle`.
597
598
EXAMPLE::
599
600
sage: T = ModularSymbols(Gamma1(7), 4).hecke_algebra()
601
sage: T.diamond_bracket_matrix(3)
602
[ 0 0 1 0 0 0 0 0 0 0 0 0]
603
[ 1 0 0 0 0 0 0 0 0 0 0 0]
604
[ 0 1 0 0 0 0 0 0 0 0 0 0]
605
[ 0 0 0 -11/9 -4/9 1 2/3 7/9 2/9 7/9 -5/9 -2/9]
606
[ 0 0 0 58/9 17/9 -5 -10/3 4/9 5/9 -50/9 37/9 13/9]
607
[ 0 0 0 -22/9 -8/9 2 4/3 5/9 4/9 14/9 -10/9 -4/9]
608
[ 0 0 0 44/9 16/9 -4 -8/3 8/9 1/9 -28/9 20/9 8/9]
609
[ 0 0 0 0 0 0 0 0 0 0 1 0]
610
[ 0 0 0 0 0 0 0 0 0 0 0 1]
611
[ 0 0 0 1 0 0 0 0 0 0 0 0]
612
[ 0 0 0 2 0 -1 0 0 0 0 0 0]
613
[ 0 0 0 -4 0 4 1 0 0 0 0 0]
614
615
"""
616
return self.__M.diamond_bracket_matrix(d)
617
618
def diamond_bracket_operator(self, d):
619
r"""
620
Return the diamond bracket operator `\langle d \rangle`.
621
622
EXAMPLE::
623
624
sage: T = ModularSymbols(Gamma1(7), 4).hecke_algebra()
625
sage: T.diamond_bracket_operator(3)
626
Diamond bracket operator <3> on Modular Symbols space of dimension 12 for Gamma_1(7) of weight 4 with sign 0 and over Rational Field
627
"""
628
d = int(d) % self.__M.level()
629
try:
630
return self.__diamond_operator[d]
631
except AttributeError:
632
self.__diamond_operator = {}
633
except KeyError:
634
pass
635
D = self.__M._diamond_operator_class()(self, d)
636
self.__diamond_operator[d] = D
637
return D
638
639
class HeckeAlgebra_full(HeckeAlgebra_base):
640
r"""
641
A full Hecke algebra (including the operators `T_n` where `n` is not
642
assumed to be coprime to the level).
643
"""
644
def _repr_(self):
645
r"""
646
String representation of self.
647
648
EXAMPLE::
649
650
sage: ModularForms(37).hecke_algebra()._repr_()
651
'Full Hecke algebra acting on Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(37) of weight 2 over Rational Field'
652
"""
653
return "Full Hecke algebra acting on %s"%self.module()
654
655
def __cmp__(self, other):
656
r"""
657
Compare self to other.
658
659
EXAMPLES::
660
661
sage: A = ModularForms(37).hecke_algebra()
662
sage: A == QQ
663
False
664
sage: A == ModularForms(37).anemic_hecke_algebra()
665
False
666
sage: A == A
667
True
668
"""
669
if not isinstance(other, HeckeAlgebra_full):
670
return -1
671
return cmp(self.module(), other.module())
672
673
def is_anemic(self):
674
"""
675
Return False, since this the full Hecke algebra.
676
677
EXAMPLES::
678
679
sage: H = CuspForms(3, 12).hecke_algebra()
680
sage: H.is_anemic()
681
False
682
"""
683
return False
684
685
def anemic_subalgebra(self):
686
r"""
687
The subalgebra of self generated by the Hecke operators of
688
index coprime to the level.
689
690
EXAMPLE::
691
692
sage: H = CuspForms(3, 12).hecke_algebra()
693
sage: H.anemic_subalgebra()
694
Anemic Hecke algebra acting on Cuspidal subspace of dimension 3 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(3) of weight 12 over Rational Field
695
"""
696
return self.module().anemic_hecke_algebra()
697
698
699
class HeckeAlgebra_anemic(HeckeAlgebra_base):
700
r"""
701
An anemic Hecke algebra, generated by Hecke operators with index coprime to the level.
702
"""
703
def _repr_(self):
704
r"""
705
EXAMPLE::
706
707
sage: H = CuspForms(3, 12).anemic_hecke_algebra()._repr_()
708
"""
709
return "Anemic Hecke algebra acting on %s"%self.module()
710
711
def __cmp__(self, other):
712
r"""
713
Compare self to other.
714
715
EXAMPLES::
716
717
sage: A = ModularForms(23).anemic_hecke_algebra()
718
sage: A == QQ
719
False
720
sage: A == ModularForms(23).hecke_algebra()
721
False
722
sage: A == A
723
True
724
725
"""
726
if not isinstance(other, HeckeAlgebra_anemic):
727
return -1
728
return cmp(self.module(), other.module())
729
730
def hecke_operator(self, n):
731
"""
732
Return the `n`-th Hecke operator, for `n` any
733
positive integer coprime to the level.
734
735
EXAMPLES::
736
737
sage: T = ModularSymbols(Gamma1(5),3).anemic_hecke_algebra()
738
sage: T.hecke_operator(2)
739
Hecke operator T_2 on Modular Symbols space of dimension 4 for Gamma_1(5) of weight 3 with sign 0 and over Rational Field
740
sage: T.hecke_operator(5)
741
Traceback (most recent call last):
742
...
743
IndexError: Hecke operator T_5 not defined in the anemic Hecke algebra
744
"""
745
n = int(n)
746
if arith.gcd(self.module().level(), n) != 1:
747
raise IndexError, "Hecke operator T_%s not defined in the anemic Hecke algebra"%n
748
return self.module()._hecke_operator_class()(self, n)
749
750
def is_anemic(self):
751
"""
752
Return True, since this the anemic Hecke algebra.
753
754
EXAMPLES::
755
756
sage: H = CuspForms(3, 12).anemic_hecke_algebra()
757
sage: H.is_anemic()
758
True
759
"""
760
return True
761
762
def gens(self):
763
"""
764
Return a generator over all Hecke operator `T_n` for
765
`n = 1, 2, 3, \ldots`, with `n` coprime to the
766
level. This is an infinite sequence.
767
768
EXAMPLES::
769
770
sage: T = ModularSymbols(12,2).anemic_hecke_algebra()
771
sage: g = T.gens()
772
sage: g.next()
773
Hecke operator T_1 on Modular Symbols space of dimension 5 for Gamma_0(12) of weight 2 with sign 0 over Rational Field
774
sage: g.next()
775
Hecke operator T_5 on Modular Symbols space of dimension 5 for Gamma_0(12) of weight 2 with sign 0 over Rational Field
776
"""
777
level = self.level()
778
n = 1
779
while True:
780
if arith.gcd(n, level) == 1:
781
yield self.hecke_operator(n)
782
n += 1
783
784
785
786
787
788