Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/hecke/algebra.py
4069 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}_{\verb|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
"""
521
try:
522
return self.__disc
523
except AttributeError:
524
pass
525
basis = self.basis()
526
d = len(basis)
527
if d <= 1:
528
self.__disc = ZZ(1)
529
return self.__disc
530
trace_matrix = matrix(ZZ, d)
531
for i in range(d):
532
for j in range(i+1):
533
trace_matrix[i,j] = trace_matrix[j,i] = basis[i].matrix().trace_of_product(basis[j].matrix())
534
self.__disc = trace_matrix.det()
535
return self.__disc
536
537
def gens(self):
538
r"""
539
Return a generator over all Hecke operator `T_n` for
540
`n = 1, 2, 3, \ldots`. This is infinite.
541
542
EXAMPLES::
543
544
sage: T = ModularSymbols(1,12).hecke_algebra()
545
sage: g = T.gens()
546
sage: g.next()
547
Hecke operator T_1 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
548
sage: g.next()
549
Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
550
"""
551
n = 1
552
while True:
553
yield self.hecke_operator(n)
554
n += 1
555
556
def hecke_operator(self, n):
557
"""
558
Return the `n`-th Hecke operator `T_n`.
559
560
EXAMPLES::
561
562
sage: T = ModularSymbols(1,12).hecke_algebra()
563
sage: T.hecke_operator(2)
564
Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
565
"""
566
try:
567
return self.__hecke_operator[n]
568
except AttributeError:
569
self.__hecke_operator = {}
570
except KeyError:
571
pass
572
n = int(n)
573
T = self.__M._hecke_operator_class()(self, n)
574
self.__hecke_operator[n] = T
575
return T
576
577
def hecke_matrix(self, n, *args, **kwds):
578
"""
579
Return the matrix of the n-th Hecke operator `T_n`.
580
581
EXAMPLES::
582
583
sage: T = ModularSymbols(1,12).hecke_algebra()
584
sage: T.hecke_matrix(2)
585
[ -24 0 0]
586
[ 0 -24 0]
587
[4860 0 2049]
588
"""
589
return self.__M.hecke_matrix(n, *args, **kwds)
590
591
def diamond_bracket_matrix(self, d):
592
r"""
593
Return the matrix of the diamond bracket operator `\langle d \rangle`.
594
595
EXAMPLE::
596
597
sage: T = ModularSymbols(Gamma1(7), 4).hecke_algebra()
598
sage: T.diamond_bracket_matrix(3)
599
[ 0 0 1 0 0 0 0 0 0 0 0 0]
600
[ 1 0 0 0 0 0 0 0 0 0 0 0]
601
[ 0 1 0 0 0 0 0 0 0 0 0 0]
602
[ 0 0 0 -11/9 -4/9 1 2/3 7/9 2/9 7/9 -5/9 -2/9]
603
[ 0 0 0 58/9 17/9 -5 -10/3 4/9 5/9 -50/9 37/9 13/9]
604
[ 0 0 0 -22/9 -8/9 2 4/3 5/9 4/9 14/9 -10/9 -4/9]
605
[ 0 0 0 44/9 16/9 -4 -8/3 8/9 1/9 -28/9 20/9 8/9]
606
[ 0 0 0 0 0 0 0 0 0 0 1 0]
607
[ 0 0 0 0 0 0 0 0 0 0 0 1]
608
[ 0 0 0 1 0 0 0 0 0 0 0 0]
609
[ 0 0 0 2 0 -1 0 0 0 0 0 0]
610
[ 0 0 0 -4 0 4 1 0 0 0 0 0]
611
612
"""
613
return self.__M.diamond_bracket_matrix(d)
614
615
def diamond_bracket_operator(self, d):
616
r"""
617
Return the diamond bracket operator `\langle d \rangle`.
618
619
EXAMPLE::
620
621
sage: T = ModularSymbols(Gamma1(7), 4).hecke_algebra()
622
sage: T.diamond_bracket_operator(3)
623
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
624
"""
625
d = int(d) % self.__M.level()
626
try:
627
return self.__diamond_operator[d]
628
except AttributeError:
629
self.__diamond_operator = {}
630
except KeyError:
631
pass
632
D = self.__M._diamond_operator_class()(self, d)
633
self.__diamond_operator[d] = D
634
return D
635
636
class HeckeAlgebra_full(HeckeAlgebra_base):
637
r"""
638
A full Hecke algebra (including the operators `T_n` where `n` is not
639
assumed to be coprime to the level).
640
"""
641
def _repr_(self):
642
r"""
643
String representation of self.
644
645
EXAMPLE::
646
647
sage: ModularForms(37).hecke_algebra()._repr_()
648
'Full Hecke algebra acting on Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(37) of weight 2 over Rational Field'
649
"""
650
return "Full Hecke algebra acting on %s"%self.module()
651
652
def __cmp__(self, other):
653
r"""
654
Compare self to other.
655
656
EXAMPLES::
657
658
sage: A = ModularForms(37).hecke_algebra()
659
sage: A == QQ
660
False
661
sage: A == ModularForms(37).anemic_hecke_algebra()
662
False
663
sage: A == A
664
True
665
"""
666
if not isinstance(other, HeckeAlgebra_full):
667
return -1
668
return cmp(self.module(), other.module())
669
670
def is_anemic(self):
671
"""
672
Return False, since this the full Hecke algebra.
673
674
EXAMPLES::
675
676
sage: H = CuspForms(3, 12).hecke_algebra()
677
sage: H.is_anemic()
678
False
679
"""
680
return False
681
682
def anemic_subalgebra(self):
683
r"""
684
The subalgebra of self generated by the Hecke operators of
685
index coprime to the level.
686
687
EXAMPLE::
688
689
sage: H = CuspForms(3, 12).hecke_algebra()
690
sage: H.anemic_subalgebra()
691
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
692
"""
693
return self.module().anemic_hecke_algebra()
694
695
696
class HeckeAlgebra_anemic(HeckeAlgebra_base):
697
r"""
698
An anemic Hecke algebra, generated by Hecke operators with index coprime to the level.
699
"""
700
def _repr_(self):
701
r"""
702
EXAMPLE::
703
704
sage: H = CuspForms(3, 12).anemic_hecke_algebra()._repr_()
705
"""
706
return "Anemic Hecke algebra acting on %s"%self.module()
707
708
def __cmp__(self, other):
709
r"""
710
Compare self to other.
711
712
EXAMPLES::
713
714
sage: A = ModularForms(23).anemic_hecke_algebra()
715
sage: A == QQ
716
False
717
sage: A == ModularForms(23).hecke_algebra()
718
False
719
sage: A == A
720
True
721
722
"""
723
if not isinstance(other, HeckeAlgebra_anemic):
724
return -1
725
return cmp(self.module(), other.module())
726
727
def hecke_operator(self, n):
728
"""
729
Return the `n`-th Hecke operator, for `n` any
730
positive integer coprime to the level.
731
732
EXAMPLES::
733
734
sage: T = ModularSymbols(Gamma1(5),3).anemic_hecke_algebra()
735
sage: T.hecke_operator(2)
736
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
737
sage: T.hecke_operator(5)
738
Traceback (most recent call last):
739
...
740
IndexError: Hecke operator T_5 not defined in the anemic Hecke algebra
741
"""
742
n = int(n)
743
if arith.gcd(self.module().level(), n) != 1:
744
raise IndexError, "Hecke operator T_%s not defined in the anemic Hecke algebra"%n
745
return self.module()._hecke_operator_class()(self, n)
746
747
def is_anemic(self):
748
"""
749
Return True, since this the anemic Hecke algebra.
750
751
EXAMPLES::
752
753
sage: H = CuspForms(3, 12).anemic_hecke_algebra()
754
sage: H.is_anemic()
755
True
756
"""
757
return True
758
759
def gens(self):
760
"""
761
Return a generator over all Hecke operator `T_n` for
762
`n = 1, 2, 3, \ldots`, with `n` coprime to the
763
level. This is an infinite sequence.
764
765
EXAMPLES::
766
767
sage: T = ModularSymbols(12,2).anemic_hecke_algebra()
768
sage: g = T.gens()
769
sage: g.next()
770
Hecke operator T_1 on Modular Symbols space of dimension 5 for Gamma_0(12) of weight 2 with sign 0 over Rational Field
771
sage: g.next()
772
Hecke operator T_5 on Modular Symbols space of dimension 5 for Gamma_0(12) of weight 2 with sign 0 over Rational Field
773
"""
774
level = self.level()
775
n = 1
776
while True:
777
if arith.gcd(n, level) == 1:
778
yield self.hecke_operator(n)
779
n += 1
780
781
782
783
784
785