Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modform/cuspidal_submodule.py
4045 views
1
"""
2
The Cuspidal Subspace
3
4
EXAMPLES::
5
6
sage: S = CuspForms(SL2Z,12); S
7
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for
8
Modular Group SL(2,Z) of weight 12 over Rational Field
9
sage: S.basis()
10
[
11
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
12
]
13
14
sage: S = CuspForms(Gamma0(33),2); S
15
Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for
16
Congruence Subgroup Gamma0(33) of weight 2 over Rational Field
17
sage: S.basis()
18
[
19
q - q^5 + O(q^6),
20
q^2 - q^4 - q^5 + O(q^6),
21
q^3 + O(q^6)
22
]
23
24
sage: S = CuspForms(Gamma1(3),6); S
25
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for
26
Congruence Subgroup Gamma1(3) of weight 6 over Rational Field
27
sage: S.basis()
28
[
29
q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)
30
]
31
"""
32
33
#########################################################################
34
# Copyright (C) 2004--2006 William Stein <[email protected]>
35
#
36
# Distributed under the terms of the GNU General Public License (GPL)
37
#
38
# http://www.gnu.org/licenses/
39
#########################################################################
40
41
from sage.rings.all import Integer
42
from sage.misc.all import verbose
43
from sage.matrix.all import Matrix
44
45
import submodule
46
import vm_basis
47
48
class CuspidalSubmodule(submodule.ModularFormsSubmodule):
49
"""
50
Base class for cuspidal submodules of ambient spaces of modular forms.
51
"""
52
def __init__(self, ambient_space):
53
"""
54
The cuspidal submodule of an ambient space of modular forms.
55
56
EXAMPLES::
57
58
sage: S = CuspForms(SL2Z,12); S
59
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for
60
Modular Group SL(2,Z) of weight 12 over Rational Field
61
sage: S.basis()
62
[
63
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
64
]
65
66
sage: S = CuspForms(Gamma0(33),2); S
67
Cuspidal subspace of dimension 3 of Modular Forms space of dimension 6 for
68
Congruence Subgroup Gamma0(33) of weight 2 over Rational Field
69
sage: S.basis()
70
[
71
q - q^5 + O(q^6),
72
q^2 - q^4 - q^5 + O(q^6),
73
q^3 + O(q^6)
74
]
75
76
sage: S = CuspForms(Gamma1(3),6); S
77
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for
78
Congruence Subgroup Gamma1(3) of weight 6 over Rational Field
79
sage: S.basis()
80
[
81
q - 6*q^2 + 9*q^3 + 4*q^4 + 6*q^5 + O(q^6)
82
]
83
sage: S == loads(dumps(S))
84
True
85
"""
86
verbose('creating cuspidal submodule of %s'%ambient_space)
87
d = ambient_space._dim_cuspidal()
88
V = ambient_space.module()
89
G = [V.gen(i) for i in range(d)]
90
S = V.submodule(G, check=False, already_echelonized=True)
91
submodule.ModularFormsSubmodule.__init__(self, ambient_space, S)
92
93
def _compute_q_expansion_basis(self, prec):
94
r"""
95
Compute a basis of q-expansions of self to the given precision. Not
96
implemented in this abstract base class.
97
98
EXAMPLE::
99
100
sage: M = CuspForms(GammaH(11,[2]), 2)
101
sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule._compute_q_expansion_basis(M, 6)
102
Traceback (most recent call last):
103
...
104
NotImplementedError: q-expansion basis not implemented for "Cuspidal subspace of ..."
105
"""
106
raise NotImplementedError, 'q-expansion basis not implemented for "%s"' % self
107
108
def _repr_(self):
109
"""
110
Return the string representation of self.
111
112
EXAMPLES::
113
114
sage: S = CuspForms(Gamma1(3),6); S._repr_()
115
'Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma1(3) of weight 6 over Rational Field'
116
"""
117
return "Cuspidal subspace of dimension %s of %s"%(self.dimension(), self.ambient_module())
118
119
def is_cuspidal(self):
120
"""
121
Return True since spaces of cusp forms are cuspidal.
122
123
EXAMPLES::
124
125
sage: CuspForms(4,10).is_cuspidal()
126
True
127
"""
128
return True
129
130
def modular_symbols(self, sign=0):
131
"""
132
Return the corresponding space of modular symbols with the given sign.
133
134
EXAMPLES::
135
136
sage: S = ModularForms(11,2).cuspidal_submodule()
137
sage: S.modular_symbols()
138
Modular Symbols subspace of dimension 2 of Modular Symbols space
139
of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
140
141
sage: S.modular_symbols(sign=-1)
142
Modular Symbols subspace of dimension 1 of Modular Symbols space
143
of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Rational Field
144
145
sage: M = S.modular_symbols(sign=1); M
146
Modular Symbols subspace of dimension 1 of Modular Symbols space of
147
dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field
148
sage: M.sign()
149
1
150
151
sage: S = ModularForms(1,12).cuspidal_submodule()
152
sage: S.modular_symbols()
153
Modular Symbols subspace of dimension 2 of Modular Symbols space of
154
dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
155
156
sage: eps = DirichletGroup(13).0
157
sage: S = CuspForms(eps^2, 2)
158
159
sage: S.modular_symbols(sign=0)
160
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2
161
162
sage: S.modular_symbols(sign=1)
163
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 and level 13, weight 2, character [zeta6], sign 1, over Cyclotomic Field of order 6 and degree 2
164
165
sage: S.modular_symbols(sign=-1)
166
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 1 and level 13, weight 2, character [zeta6], sign -1, over Cyclotomic Field of order 6 and degree 2
167
"""
168
try:
169
return self.__modular_symbols[sign]
170
except AttributeError:
171
self.__modular_symbols = {}
172
except KeyError:
173
pass
174
A = self.ambient_module()
175
S = A.modular_symbols(sign).cuspidal_submodule()
176
self.__modular_symbols[sign] = S
177
return S
178
179
180
def change_ring(self, R):
181
r"""
182
Change the base ring of self to R, when this makes sense. This differs
183
from :meth:`~sage.modular.modform.space.ModularFormsSpace.base_extend`
184
in that there may not be a canonical map from self to the new space, as
185
in the first example below. If this space has a character then this may
186
fail when the character cannot be defined over R, as in the second
187
example.
188
189
EXAMPLES::
190
191
sage: chi = DirichletGroup(109, CyclotomicField(3)).0
192
sage: S9 = CuspForms(chi, 2, base_ring = CyclotomicField(9)); S9
193
Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 9 and degree 6
194
sage: S9.change_ring(CyclotomicField(3))
195
Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 3 and degree 2
196
sage: S9.change_ring(QQ)
197
Traceback (most recent call last):
198
...
199
ValueError: Space cannot be defined over Rational Field
200
"""
201
return self.ambient_module().change_ring(R).cuspidal_submodule()
202
203
class CuspidalSubmodule_R(CuspidalSubmodule):
204
"""
205
Cuspidal submodule over a non-minimal base ring.
206
"""
207
def _compute_q_expansion_basis(self, prec):
208
r"""
209
EXAMPLE::
210
211
sage: CuspForms(Gamma1(13), 2, base_ring=QuadraticField(-7, 'a')).q_expansion_basis() # indirect doctest
212
[
213
q - 4*q^3 - q^4 + 3*q^5 + O(q^6),
214
q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)
215
]
216
"""
217
return submodule.ModularFormsSubmodule._compute_q_expansion_basis(self, prec)
218
219
class CuspidalSubmodule_modsym_qexp(CuspidalSubmodule):
220
"""
221
Cuspidal submodule with q-expansions calculated via modular symbols.
222
"""
223
def _compute_q_expansion_basis(self, prec=None):
224
"""
225
Compute q-expansions of a basis for self (via modular symbols).
226
227
EXAMPLES::
228
229
sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_modsym_qexp(ModularForms(11,2))._compute_q_expansion_basis()
230
[
231
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
232
]
233
"""
234
if prec == None:
235
prec = self.prec()
236
else:
237
prec = Integer(prec)
238
if self.dimension() == 0:
239
return []
240
M = self.modular_symbols(sign = 1)
241
return M.q_expansion_basis(prec)
242
243
def new_submodule(self, p=None):
244
r"""
245
Return the new subspace of this space of cusp forms. This is computed
246
using modular symbols.
247
248
EXAMPLE::
249
250
sage: CuspForms(55).new_submodule()
251
Modular Forms subspace of dimension 3 of Modular Forms space of dimension 8 for Congruence Subgroup Gamma0(55) of weight 2 over Rational Field
252
"""
253
symbs = self.modular_symbols(sign=1).new_subspace(p)
254
bas = []
255
for x in symbs.q_expansion_basis(self.sturm_bound()):
256
bas.append(self(x))
257
return self.submodule(bas, check=False)
258
259
class CuspidalSubmodule_level1_Q(CuspidalSubmodule):
260
r"""
261
Space of cusp forms of level 1 over `\QQ`.
262
"""
263
def _compute_q_expansion_basis(self, prec=None):
264
"""
265
Compute q-expansions of a basis for self.
266
267
EXAMPLES::
268
269
sage: sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_level1_Q(ModularForms(1,12))._compute_q_expansion_basis()
270
[
271
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
272
]
273
"""
274
if prec == None:
275
prec = self.prec()
276
else:
277
prec = Integer(prec)
278
return vm_basis.victor_miller_basis(self.weight(), prec,
279
cusp_only=True, var='q')
280
281
class CuspidalSubmodule_g0_Q(CuspidalSubmodule_modsym_qexp):
282
r"""
283
Space of cusp forms for `\Gamma_0(N)` over `\QQ`.
284
"""
285
286
class CuspidalSubmodule_gH_Q(CuspidalSubmodule_modsym_qexp):
287
r"""
288
Space of cusp forms for `\Gamma_1(N)` over `\QQ`.
289
"""
290
291
def _compute_hecke_matrix(self, n):
292
r"""
293
Compute the matrix of the Hecke operator T_n acting on this space.
294
This is done directly using modular symbols, rather than using
295
q-expansions as for spaces with fixed character.
296
297
EXAMPLE::
298
299
sage: CuspForms(Gamma1(8), 4)._compute_hecke_matrix(2)
300
[ 0 -16 32]
301
[ 1 -10 18]
302
[ 0 -4 8]
303
304
sage: CuspForms(GammaH(15, [4]), 3)._compute_hecke_matrix(17)
305
[ 18 22 -30 -60]
306
[ 4 0 6 -18]
307
[ 6 0 2 -20]
308
[ 6 12 -24 -20]
309
"""
310
symbs = self.modular_symbols(sign=1)
311
return _convert_matrix_from_modsyms(symbs, symbs.hecke_matrix(n))[0]
312
313
def _compute_diamond_matrix(self, d):
314
r"""
315
EXAMPLE::
316
317
sage: CuspForms(Gamma1(5), 6).diamond_bracket_matrix(3) # indirect doctest
318
[ -1 0 0]
319
[ 3 5 -12]
320
[ 1 2 -5]
321
sage: CuspForms(GammaH(15, [4]), 3)._compute_diamond_matrix(7)
322
[ 2 3 -9 -3]
323
[ 0 2 -3 0]
324
[ 0 1 -2 0]
325
[ 1 1 -3 -2]
326
"""
327
symbs = self.modular_symbols(sign=1)
328
return _convert_matrix_from_modsyms(symbs, symbs.diamond_bracket_matrix(d))[0]
329
330
331
class CuspidalSubmodule_g1_Q(CuspidalSubmodule_gH_Q):
332
r"""
333
Space of cusp forms for `\Gamma_1(N)` over `\QQ`.
334
"""
335
336
class CuspidalSubmodule_eps(CuspidalSubmodule_modsym_qexp):
337
"""
338
Space of cusp forms with given Dirichlet character.
339
340
EXAMPLES::
341
342
sage: S = CuspForms(DirichletGroup(5).0,5); S
343
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3, character [zeta4] and weight 5 over Cyclotomic Field of order 4 and degree 2
344
345
sage: S.basis()
346
[
347
q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)
348
]
349
sage: f = S.0
350
sage: f.qexp()
351
q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6)
352
sage: f.qexp(7)
353
q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + 12*q^6 + O(q^7)
354
sage: f.qexp(3)
355
q + (-zeta4 - 1)*q^2 + O(q^3)
356
sage: f.qexp(2)
357
q + O(q^2)
358
sage: f.qexp(1)
359
O(q^1)
360
"""
361
362
#def _repr_(self):
363
# A = self.ambient_module()
364
# return "Cuspidal subspace of dimension %s of Modular Forms space with character %s and weight %s over %s"%(self.dimension(), self.character(), self.weight(), self.base_ring())
365
366
367
368
def _convert_matrix_from_modsyms(symbs, T):
369
r"""
370
Given a space of modular symbols and a matrix T acting on it, calculate the
371
matrix of the corresponding operator on the echelon-form basis of the
372
corresponding space of modular forms.
373
374
The matrix T *must* commute with the Hecke operators! We use this when T is
375
either a Hecke operator, or a diamond operator. This will *not work* for
376
the Atkin-Lehner operators, for instance, when there are oldforms present.
377
378
OUTPUT:
379
A pair `(T_e, ps)` with `T_e` the converted matrix and `ps` a list
380
of pivot elements of the echelon basis.
381
382
EXAMPLE::
383
384
sage: CuspForms(Gamma1(5), 6).diamond_bracket_matrix(3) # indirect doctest
385
[ -1 0 0]
386
[ 3 5 -12]
387
[ 1 2 -5]
388
"""
389
d = symbs.rank()
390
391
# create a vector space of appropriate dimension to
392
# contain our q-expansions
393
A = symbs.base_ring()
394
r = symbs.sturm_bound()
395
X = A**r
396
Y = X.zero_submodule()
397
basis = []
398
basis_images = []
399
400
# we repeatedly use these matrices below, so we store them
401
# once as lists to save time.
402
hecke_matrix_ls = [ symbs.hecke_matrix(m).list() for m in range(1,r+1) ]
403
hecke_image_ls = [ (T*symbs.hecke_matrix(m)).list() for m in range(1,r+1) ]
404
405
# compute the q-expansions of some cusp forms and their
406
# images under T_n
407
for i in xrange(d**2):
408
v = X([ hecke_matrix_ls[m][i] for m in xrange(r) ])
409
Ynew = Y.span(Y.basis() + [v])
410
if Ynew.rank() > Y.rank():
411
basis.append(v)
412
basis_images.append(X([ hecke_image_ls[m][i] for m in xrange(r) ]))
413
Y = Ynew
414
if len(basis) == d: break
415
416
# now we can compute the matrix acting on the echelonized space of mod forms
417
# need to pass A as base ring since otherwise there are problems when the
418
# space has dimension 0
419
bigmat = Matrix(A, basis).augment(Matrix(A, basis_images))
420
bigmat.echelonize()
421
pivs = bigmat.pivots()
422
return bigmat.matrix_from_rows_and_columns(range(d), [ r+x for x in pivs ]), pivs
423
424