Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/modform/space.py
4045 views
1
r"""
2
Generic spaces of modular forms
3
4
EXAMPLES (computation of base ring): Return the base ring of this
5
space of modular forms.
6
7
EXAMPLES: For spaces of modular forms for `\Gamma_0(N)` or
8
`\Gamma_1(N)`, the default base ring is
9
`\QQ`::
10
11
sage: ModularForms(11,2).base_ring()
12
Rational Field
13
sage: ModularForms(1,12).base_ring()
14
Rational Field
15
sage: CuspForms(Gamma1(13),3).base_ring()
16
Rational Field
17
18
The base ring can be explicitly specified in the constructor
19
function.
20
21
::
22
23
sage: ModularForms(11,2,base_ring=GF(13)).base_ring()
24
Finite Field of size 13
25
26
For modular forms with character the default base ring is the field
27
generated by the image of the character.
28
29
::
30
31
sage: ModularForms(DirichletGroup(13).0,3).base_ring()
32
Cyclotomic Field of order 12 and degree 4
33
34
For example, if the character is quadratic then the field is
35
`\QQ` (if the characteristic is `0`).
36
37
::
38
39
sage: ModularForms(DirichletGroup(13).0^6,3).base_ring()
40
Rational Field
41
42
An example in characteristic `7`::
43
44
sage: ModularForms(13,3,base_ring=GF(7)).base_ring()
45
Finite Field of size 7
46
"""
47
48
#########################################################################
49
# Copyright (C) 2004--2006 William Stein <[email protected]>
50
#
51
# Distributed under the terms of the GNU General Public License (GPL)
52
#
53
# http://www.gnu.org/licenses/
54
#########################################################################
55
56
from sage.structure.all import Sequence
57
58
import sage.modular.hecke.all as hecke
59
import sage.modular.arithgroup.all as arithgroup
60
import sage.modular.dirichlet as dirichlet
61
62
import sage.rings.all as rings
63
64
import defaults
65
import element
66
import hecke_operator_on_qexp
67
import submodule
68
69
import sage.modular.modform.constructor
70
71
from sage.matrix.constructor import zero_matrix
72
from sage.rings.arith import gcd
73
74
WARN=False
75
76
def is_ModularFormsSpace(x):
77
r"""
78
Return True if x is a ```ModularFormsSpace```.
79
80
EXAMPLES::
81
82
sage: from sage.modular.modform.space import is_ModularFormsSpace
83
sage: is_ModularFormsSpace(ModularForms(11,2))
84
True
85
sage: is_ModularFormsSpace(CuspForms(11,2))
86
True
87
sage: is_ModularFormsSpace(3)
88
False
89
"""
90
return isinstance(x, ModularFormsSpace)
91
92
class ModularFormsSpace(hecke.HeckeModule_generic):
93
"""
94
A generic space of modular forms.
95
"""
96
def __init__(self, group, weight, character, base_ring):
97
r"""
98
Generic spaces of modular forms. For spaces of modular forms for
99
`\Gamma_0(N)` or `\Gamma_1(N)`, the default base
100
ring is `\QQ`.
101
102
EXAMPLES::
103
104
sage: ModularForms(11,2)
105
Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
106
107
::
108
109
sage: ModularForms(11,2,base_ring=GF(13))
110
Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Finite Field of size 13
111
112
::
113
114
sage: ModularForms(DirichletGroup(13).0,3)
115
Modular Forms space of dimension 3, character [zeta12] and weight 3 over Cyclotomic Field of order 12 and degree 4
116
117
::
118
119
sage: M = ModularForms(11,2)
120
sage: M == loads(dumps(M))
121
True
122
"""
123
global WARN
124
if WARN:
125
print "Modular forms -- under development -- do not trust yet."
126
WARN=False
127
if not arithgroup.is_CongruenceSubgroup(group):
128
raise TypeError, "group (=%s) must be a congruence subgroup"%group
129
weight = int(weight)
130
#if not isinstance(weight, int):
131
# raise TypeError, "weight must be an int"
132
if not ((character is None) or isinstance(character, dirichlet.DirichletCharacter)):
133
raise TypeError, "character must be a Dirichlet character"
134
if not isinstance(base_ring, rings.Ring):
135
raise TypeError, "base_ring must be a ring"
136
self.__sturm_bound = None
137
self.__weight, self.__group, self.__character = weight, group, character
138
hecke.HeckeModule_generic.__init__(self, base_ring, group.level())
139
140
def prec(self, new_prec=None):
141
"""
142
Return or set the default precision used for displaying
143
`q`-expansions of elements of this space.
144
145
INPUT:
146
147
148
- ``new_prec`` - positive integer (default: None)
149
150
151
OUTPUT: if new_prec is None, returns the current precision.
152
153
EXAMPLES::
154
155
sage: M = ModularForms(1,12)
156
sage: S = M.cuspidal_subspace()
157
sage: S.prec()
158
6
159
sage: S.basis()
160
[
161
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
162
]
163
sage: S.prec(8)
164
8
165
sage: S.basis()
166
[
167
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 - 6048*q^6 - 16744*q^7 + O(q^8)
168
]
169
"""
170
return self.ambient().prec(new_prec)
171
172
def set_precision(self, new_prec):
173
"""
174
Set the default precision used for displaying
175
`q`-expansions.
176
177
INPUT:
178
179
180
- ``new_prec`` - positive integer
181
182
183
EXAMPLES::
184
185
sage: M = ModularForms(Gamma0(37),2)
186
sage: M.set_precision(10)
187
sage: S = M.cuspidal_subspace()
188
sage: S.basis()
189
[
190
q + q^3 - 2*q^4 - q^7 - 2*q^9 + O(q^10),
191
q^2 + 2*q^3 - 2*q^4 + q^5 - 3*q^6 - 4*q^9 + O(q^10)
192
]
193
194
::
195
196
sage: S.set_precision(0)
197
sage: S.basis()
198
[
199
O(q^0),
200
O(q^0)
201
]
202
203
The precision of subspaces is the same as the precision of the
204
ambient space.
205
206
::
207
208
sage: S.set_precision(2)
209
sage: M.basis()
210
[
211
q + O(q^2),
212
O(q^2),
213
1 + 2/3*q + O(q^2)
214
]
215
216
The precision must be nonnegative::
217
218
sage: S.set_precision(-1)
219
Traceback (most recent call last):
220
...
221
ValueError: n (=-1) must be >= 0
222
223
We do another example with nontrivial character.
224
225
::
226
227
sage: M = ModularForms(DirichletGroup(13).0^2)
228
sage: M.set_precision(10)
229
sage: M.cuspidal_subspace().0
230
q + (-zeta6 - 1)*q^2 + (2*zeta6 - 2)*q^3 + zeta6*q^4 + (-2*zeta6 + 1)*q^5 + (-2*zeta6 + 4)*q^6 + (2*zeta6 - 1)*q^8 - zeta6*q^9 + O(q^10)
231
"""
232
self.ambient().set_precision(new_prec)
233
234
def change_ring(self, R):
235
"""
236
Change the base ring of this space of modular forms. To be implemented in derived classes.
237
238
EXAMPLES::
239
240
sage: sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,QQ).change_ring(GF(7))
241
Traceback (most recent call last):
242
...
243
NotImplementedError: This function has not yet been implemented.
244
"""
245
raise NotImplementedError, "This function has not yet been implemented."
246
247
def weight(self):
248
"""
249
Return the weight of this space of modular forms.
250
251
EXAMPLES::
252
253
sage: M = ModularForms(Gamma1(13),11)
254
sage: M.weight()
255
11
256
257
::
258
259
sage: M = ModularForms(Gamma0(997),100)
260
sage: M.weight()
261
100
262
263
::
264
265
sage: M = ModularForms(Gamma0(97),4)
266
sage: M.weight()
267
4
268
sage: M.eisenstein_submodule().weight()
269
4
270
"""
271
return self.__weight
272
273
def group(self):
274
r"""
275
Return the congruence subgroup associated to this space of modular
276
forms.
277
278
EXAMPLES::
279
280
sage: ModularForms(Gamma0(12),4).group()
281
Congruence Subgroup Gamma0(12)
282
283
::
284
285
sage: CuspForms(Gamma1(113),2).group()
286
Congruence Subgroup Gamma1(113)
287
288
Note that `\Gamma_1(1)` and `\Gamma_0(1)` are replaced by
289
`\mathrm{SL}_2(\ZZ)`.
290
291
::
292
293
sage: CuspForms(Gamma1(1),12).group()
294
Modular Group SL(2,Z)
295
sage: CuspForms(SL2Z,12).group()
296
Modular Group SL(2,Z)
297
"""
298
return self.__group
299
300
def character(self):
301
"""
302
Return the Dirichlet character corresponding to this space of
303
modular forms. Returns None if there is no specific character
304
corresponding to this space, e.g., if this is a space of modular
305
forms on `\Gamma_1(N)` with `N>1`.
306
307
EXAMPLES: The trivial character::
308
309
sage: ModularForms(Gamma0(11),2).character()
310
Dirichlet character modulo 11 of conductor 1 mapping 2 |--> 1
311
312
A space of forms with nontrivial character::
313
314
sage: ModularForms(DirichletGroup(20).0,3).character()
315
Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1
316
317
A space of forms with no particular character (hence None is
318
returned)::
319
320
sage: print ModularForms(Gamma1(11),2).character()
321
None
322
323
If the level is one then the character is trivial.
324
325
::
326
327
sage: ModularForms(Gamma1(1),12).character()
328
Dirichlet character modulo 1 of conductor 1 mapping 0 |--> 1
329
"""
330
return self.__character
331
332
def has_character(self):
333
"""
334
Return True if this space of modular forms has a specific
335
character.
336
337
This is True exactly when the character() function does not return
338
None.
339
340
EXAMPLES: A space for `\Gamma_0(N)` has trivial character,
341
hence has a character.
342
343
::
344
345
sage: CuspForms(Gamma0(11),2).has_character()
346
True
347
348
A space for `\Gamma_1(N)` (for `N\geq 2`) never
349
has a specific character.
350
351
::
352
353
sage: CuspForms(Gamma1(11),2).has_character()
354
False
355
sage: CuspForms(DirichletGroup(11).0,3).has_character()
356
True
357
"""
358
return not self.character() is None
359
360
def is_ambient(self):
361
"""
362
Return True if this an ambient space of modular forms.
363
364
EXAMPLES::
365
366
sage: M = ModularForms(Gamma1(4),4)
367
sage: M.is_ambient()
368
True
369
370
::
371
372
sage: E = M.eisenstein_subspace()
373
sage: E.is_ambient()
374
False
375
"""
376
return False # returning True is defined in the derived AmbientSpace class.
377
378
def __normalize_prec(self, prec):
379
"""
380
If prec=None, return self.prec(). Otherwise, make sure prec is a
381
sensible choice of precision and return it.
382
383
EXAMPLES::
384
385
sage: N = ModularForms(6,4)
386
sage: N._ModularFormsSpace__normalize_prec(int(3))
387
3
388
389
::
390
391
sage: type(N._ModularFormsSpace__normalize_prec(int(3)))
392
<type 'sage.rings.integer.Integer'>
393
"""
394
if prec is None:
395
prec = self.prec()
396
else:
397
prec = rings.Integer(prec)
398
if prec < 0:
399
raise ValueError, "prec (=%s) must be at least 0"%prec
400
return prec
401
402
def base_extend(self, base_ring):
403
"""
404
Return the base extension of self to base_ring. This first checks
405
whether there is a canonical coercion defined, and if so it calls the
406
change_ring method.
407
408
EXAMPLE::
409
410
sage: N = ModularForms(6, 4)
411
sage: N.base_extend(CyclotomicField(7))
412
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Cyclotomic Field of order 7 and degree 6
413
414
sage: m = ModularForms(DirichletGroup(13).0^2,2); m
415
Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2
416
sage: m.base_extend(CyclotomicField(12))
417
Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 12 and degree 4
418
419
sage: chi = DirichletGroup(109, CyclotomicField(3)).0
420
sage: S3 = CuspForms(chi, 2)
421
sage: S9 = S3.base_extend(CyclotomicField(9))
422
sage: S9
423
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
424
sage: S9.has_coerce_map_from(S3) # not implemented
425
True
426
sage: S9.base_extend(CyclotomicField(3))
427
Traceback (most recent call last):
428
...
429
ValueError: No coercion defined
430
"""
431
if not base_ring.has_coerce_map_from(self.base_ring()):
432
raise ValueError, "No coercion defined"
433
else:
434
return self.change_ring(base_ring)
435
436
def echelon_form(self):
437
r"""
438
Return a space of modular forms isomorphic to self but with basis
439
of `q`-expansions in reduced echelon form.
440
441
This is useful, e.g., the default basis for spaces of modular forms
442
is rarely in echelon form, but echelon form is useful for quickly
443
recognizing whether a `q`-expansion is in the space.
444
445
EXAMPLES: We first illustrate two ambient spaces and their echelon
446
forms.
447
448
::
449
450
sage: M = ModularForms(11)
451
sage: M.basis()
452
[
453
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
454
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)
455
]
456
sage: M.echelon_form().basis()
457
[
458
1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6),
459
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
460
]
461
462
::
463
464
sage: M = ModularForms(Gamma1(6),4)
465
sage: M.basis()
466
[
467
q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
468
1 + O(q^6),
469
q - 8*q^4 + 126*q^5 + O(q^6),
470
q^2 + 9*q^4 + O(q^6),
471
q^3 + O(q^6)
472
]
473
sage: M.echelon_form().basis()
474
[
475
1 + O(q^6),
476
q + 94*q^5 + O(q^6),
477
q^2 + 36*q^5 + O(q^6),
478
q^3 + O(q^6),
479
q^4 - 4*q^5 + O(q^6)
480
]
481
482
We create a space with a funny basis then compute the corresponding
483
echelon form.
484
485
::
486
487
sage: M = ModularForms(11,4)
488
sage: M.basis()
489
[
490
q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6),
491
q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6),
492
1 + O(q^6),
493
q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)
494
]
495
sage: F = M.span_of_basis([M.0 + 1/3*M.1, M.2 + M.3]); F.basis()
496
[
497
q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6),
498
1 + q + 9*q^2 + 28*q^3 + 73*q^4 + 126*q^5 + O(q^6)
499
]
500
sage: E = F.echelon_form(); E.basis()
501
[
502
1 + 26/3*q^2 + 79/3*q^3 + 235/3*q^4 + 391/3*q^5 + O(q^6),
503
q + 1/3*q^2 + 5/3*q^3 - 16/3*q^4 - 13/3*q^5 + O(q^6)
504
]
505
"""
506
try:
507
return self.__echelon_form
508
except AttributeError:
509
E = self.span_of_basis(self.echelon_basis())
510
self.__echelon_form = E
511
return E
512
513
def echelon_basis(self):
514
"""
515
Return a basis for self in reduced echelon form. This means that if
516
we view the `q`-expansions of the basis as defining rows of
517
a matrix (with infinitely many columns), then this matrix is in
518
reduced echelon form.
519
520
EXAMPLES::
521
522
sage: M = ModularForms(Gamma0(11),4)
523
sage: M.echelon_basis()
524
[
525
1 + O(q^6),
526
q - 9*q^4 - 10*q^5 + O(q^6),
527
q^2 + 6*q^4 + 12*q^5 + O(q^6),
528
q^3 + q^4 + q^5 + O(q^6)
529
]
530
sage: M.cuspidal_subspace().echelon_basis()
531
[
532
q + 3*q^3 - 6*q^4 - 7*q^5 + O(q^6),
533
q^2 - 4*q^3 + 2*q^4 + 8*q^5 + O(q^6)
534
]
535
536
::
537
538
sage: M = ModularForms(SL2Z, 12)
539
sage: M.echelon_basis()
540
[
541
1 + 196560*q^2 + 16773120*q^3 + 398034000*q^4 + 4629381120*q^5 + O(q^6),
542
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
543
]
544
545
::
546
547
sage: M = CuspForms(Gamma0(17),4, prec=10)
548
sage: M.echelon_basis()
549
[
550
q + 2*q^5 - 8*q^7 - 8*q^8 + 7*q^9 + O(q^10),
551
q^2 - 3/2*q^5 - 7/2*q^6 + 9/2*q^7 + q^8 - 4*q^9 + O(q^10),
552
q^3 - 2*q^6 + q^7 - 4*q^8 - 2*q^9 + O(q^10),
553
q^4 - 1/2*q^5 - 5/2*q^6 + 3/2*q^7 + 2*q^9 + O(q^10)
554
]
555
"""
556
try:
557
return self.__echelon_basis
558
except AttributeError:
559
F = self.free_module()
560
W = self._q_expansion_module()
561
pr = W.degree()
562
B = self.q_echelon_basis(pr)
563
E = [self(F.linear_combination_of_basis(W.coordinates(f.padded_list(pr)))) \
564
for f in B]
565
E = Sequence(E, cr=True, immutable=True)
566
self.__echelon_basis = E
567
return E
568
569
def integral_basis(self):
570
"""
571
Return an integral basis for this space of modular forms.
572
573
EXAMPLES: In this example the integral and echelon bases are
574
different.
575
576
::
577
578
sage: m = ModularForms(97,2,prec=10)
579
sage: s = m.cuspidal_subspace()
580
sage: s.integral_basis()
581
[
582
q + 2*q^7 + 4*q^8 - 2*q^9 + O(q^10),
583
q^2 + q^4 + q^7 + 3*q^8 - 3*q^9 + O(q^10),
584
q^3 + q^4 - 3*q^8 + q^9 + O(q^10),
585
2*q^4 - 2*q^8 + O(q^10),
586
q^5 - 2*q^8 + 2*q^9 + O(q^10),
587
q^6 + 2*q^7 + 5*q^8 - 5*q^9 + O(q^10),
588
3*q^7 + 6*q^8 - 4*q^9 + O(q^10)
589
]
590
sage: s.echelon_basis()
591
[
592
q + 2/3*q^9 + O(q^10),
593
q^2 + 2*q^8 - 5/3*q^9 + O(q^10),
594
q^3 - 2*q^8 + q^9 + O(q^10),
595
q^4 - q^8 + O(q^10),
596
q^5 - 2*q^8 + 2*q^9 + O(q^10),
597
q^6 + q^8 - 7/3*q^9 + O(q^10),
598
q^7 + 2*q^8 - 4/3*q^9 + O(q^10)
599
]
600
601
Here's another example where there is a big gap in the valuations::
602
603
sage: m = CuspForms(64,2)
604
sage: m.integral_basis()
605
[
606
q + O(q^6),
607
q^2 + O(q^6),
608
q^5 + O(q^6)
609
]
610
611
TESTS::
612
613
sage: m = CuspForms(11*2^4,2, prec=13); m
614
Cuspidal subspace of dimension 19 of Modular Forms space of dimension 30 for Congruence Subgroup Gamma0(176) of weight 2 over Rational Field
615
sage: m.integral_basis() # takes a long time (3 or 4 seconds)
616
[
617
q + O(q^13),
618
q^2 + O(q^13),
619
q^3 + O(q^13),
620
q^4 + O(q^13),
621
q^5 + O(q^13),
622
q^6 + O(q^13),
623
q^7 + O(q^13),
624
q^8 + O(q^13),
625
q^9 + O(q^13),
626
q^10 + O(q^13),
627
q^11 + O(q^13),
628
q^12 + O(q^13),
629
O(q^13),
630
O(q^13),
631
O(q^13),
632
O(q^13),
633
O(q^13),
634
O(q^13),
635
O(q^13)
636
]
637
"""
638
try:
639
return self.__integral_basis
640
except AttributeError:
641
W = self._q_expansion_module()
642
pr = W.degree()
643
B = self.q_integral_basis(pr)
644
I = [self.linear_combination_of_basis(
645
W.coordinates(f.padded_list(pr))) for f in B]
646
I = Sequence(I, cr=True, immutable=True)
647
self.__integral_basis = I
648
return I
649
650
def _q_expansion_module(self):
651
"""
652
Return module spanned by coefficients of q-expansions to sufficient
653
precision to determine elements of this space.
654
655
EXAMPLES::
656
657
sage: M = ModularForms(11,2)
658
sage: M._q_expansion_module()
659
Vector space of degree 3 and dimension 2 over Rational Field
660
User basis matrix:
661
[ 0 1 -2]
662
[ 1 12/5 36/5]
663
sage: CuspForms(1,12)._q_expansion_module()
664
Vector space of degree 2 and dimension 1 over Rational Field
665
User basis matrix:
666
[0 1]
667
"""
668
try:
669
return self.__q_expansion_module
670
except AttributeError:
671
pass
672
673
prec = self.sturm_bound()
674
C = self.q_expansion_basis(prec)
675
V = self.base_ring()**prec
676
W = V.span_of_basis([f.padded_list(prec) for f in C])
677
self.__q_expansion_module = W
678
return W
679
680
def q_expansion_basis(self, prec=None):
681
"""
682
Return a sequence of q-expansions for the basis of this space
683
computed to the given input precision.
684
685
INPUT:
686
687
688
- ``prec`` - integer (=0) or None
689
690
691
If prec is None, the prec is computed to be *at least* large
692
enough so that each q-expansion determines the form as an element
693
of this space.
694
695
.. note::
696
697
In fact, the q-expansion basis is always computed to
698
*at least* ``self.prec()``.
699
700
EXAMPLES::
701
702
sage: S = ModularForms(11,2).cuspidal_submodule()
703
sage: S.q_expansion_basis()
704
[
705
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
706
]
707
sage: S.q_expansion_basis(5)
708
[
709
q - 2*q^2 - q^3 + 2*q^4 + O(q^5)
710
]
711
sage: S = ModularForms(1,24).cuspidal_submodule()
712
sage: S.q_expansion_basis(8)
713
[
714
q + 195660*q^3 + 12080128*q^4 + 44656110*q^5 - 982499328*q^6 - 147247240*q^7 + O(q^8),
715
q^2 - 48*q^3 + 1080*q^4 - 15040*q^5 + 143820*q^6 - 985824*q^7 + O(q^8)
716
]
717
"""
718
if prec is None:
719
try: # don't care about precision -- just must be big enough to determine forms
720
return self.__q_expansion_basis[1]
721
except AttributeError:
722
pass
723
prec = -1 # big enough to determine forms
724
else:
725
prec = rings.Integer(self.__normalize_prec(prec))
726
727
if prec == 0:
728
z = self._q_expansion_ring()(0,prec)
729
return Sequence([z]*int(self.dimension()), immutable=True, cr=True)
730
elif prec != -1:
731
try:
732
current_prec, B = self.__q_expansion_basis
733
if current_prec == prec:
734
return B
735
elif current_prec > prec:
736
return Sequence([f.add_bigoh(prec) for f in B], immutable=True, cr=True)
737
except AttributeError:
738
pass
739
740
d = self.dimension()
741
current_prec = max(prec, self.prec(), int(1.2*d) + 3) # +3 for luck.
742
if prec == -1:
743
prec = current_prec
744
tries = 0
745
while True:
746
B = self._compute_q_expansion_basis(current_prec)
747
if len(B) == d:
748
break
749
else:
750
tries += 1
751
current_prec += d
752
if tries > 5:
753
print "WARNING: possible bug in q_expansion_basis for modular forms space %s"%self
754
B = Sequence(B, immutable=True, cr=True)
755
self.__q_expansion_basis = (current_prec, B)
756
if current_prec == prec:
757
return B
758
return Sequence([f.add_bigoh(prec) for f in B], immutable=True, cr=True)
759
760
def _compute_q_expansion_basis(self, prec):
761
"""
762
EXAMPLES::
763
764
sage: sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,QQ)._compute_q_expansion_basis(5)
765
Traceback (most recent call last):
766
...
767
NotImplementedError: this must be implemented in the derived class
768
"""
769
raise NotImplementedError, "this must be implemented in the derived class"
770
771
def q_echelon_basis(self, prec=None):
772
r"""
773
Return the echelon form of the basis of `q`-expansions of
774
self up to precision prec.
775
776
The `q`-expansions are power series (not actual modular
777
forms). The number of `q`-expansions returned equals the
778
dimension.
779
780
EXAMPLES::
781
782
sage: M = ModularForms(11,2)
783
sage: M.q_expansion_basis()
784
[
785
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
786
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)
787
]
788
789
::
790
791
sage: M.q_echelon_basis()
792
[
793
1 + 12*q^2 + 12*q^3 + 12*q^4 + 12*q^5 + O(q^6),
794
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
795
]
796
"""
797
prec = self.__normalize_prec(prec)
798
if prec == 0:
799
z = self._q_expansion_ring()(0,0)
800
return Sequence([z]*int(self.dimension()), cr=True)
801
try:
802
current_prec, B = self.__q_echelon_basis
803
except AttributeError:
804
current_prec, B = -1, []
805
if current_prec == prec:
806
return B
807
elif current_prec > prec:
808
return Sequence([f.add_bigoh(prec) for f in B], cr=True)
809
810
B = self.q_expansion_basis(prec)
811
R = self.base_ring()
812
A = R**prec
813
gens = [f.padded_list(prec) for f in B]
814
C = A.span(gens)
815
816
T = self._q_expansion_ring()
817
S = [T(f.list(), prec) for f in C.basis()]
818
for _ in range(self.dimension() - len(S)):
819
S.append(T(0,prec))
820
S = Sequence(S, immutable=True, cr=True)
821
self.__q_echelon_basis = (prec, S)
822
return S
823
824
def q_integral_basis(self, prec=None):
825
r"""
826
Return a `\ZZ`-reduced echelon basis of
827
`q`-expansions for self.
828
829
The `q`-expansions are power series with coefficients in
830
`\ZZ`; they are *not* actual modular forms.
831
832
The base ring of self must be `\QQ`. The number of
833
`q`-expansions returned equals the dimension.
834
835
EXAMPLES::
836
837
sage: S = CuspForms(11,2)
838
sage: S.q_integral_basis(5)
839
[
840
q - 2*q^2 - q^3 + 2*q^4 + O(q^5)
841
]
842
"""
843
if not self.base_ring() == rings.QQ:
844
raise TypeError, "the base ring must be Q"
845
prec = self.__normalize_prec(prec)
846
R = rings.PowerSeriesRing(rings.ZZ, name=defaults.DEFAULT_VARIABLE)
847
if prec == 0:
848
z = R(0,prec)
849
return Sequence([z]*int(self.dimension()), cr=True)
850
try:
851
current_prec, B = self.__q_integral_basis
852
except AttributeError:
853
current_prec, B = -1, Sequence([], cr=True, immutable=True)
854
855
if current_prec == prec:
856
return B
857
elif current_prec > prec:
858
return Sequence([f.add_bigoh(prec) for f in B], cr=True)
859
860
B = self.q_expansion_basis(prec)
861
862
# It's over Q; we just need to intersect it with ZZ^n.
863
A = rings.ZZ**prec
864
zero = rings.ZZ(0)
865
gens = [f.padded_list(prec) for f in B]
866
C = A.span(gens)
867
D = C.saturation()
868
S = [R(f.list(),prec) for f in D.basis()]
869
for _ in range(self.dimension() - len(S)):
870
S.append(R(0,prec))
871
S = Sequence(S, immutable=True, cr=True)
872
self.__q_integral_basis = (prec, S)
873
return S
874
875
def _q_expansion_ring(self):
876
"""
877
Returns the parent for q-expansions of modular forms in self.
878
879
EXAMPLES::
880
881
sage: M = ModularForms(11,2)
882
sage: M._q_expansion_ring()
883
Power Series Ring in q over Rational Field
884
"""
885
try:
886
return self.__q_expansion_ring
887
except AttributeError:
888
R = rings.PowerSeriesRing(self.base_ring(), name=defaults.DEFAULT_VARIABLE)
889
self.__q_expansion_ring = R
890
return R
891
892
def _q_expansion_zero(self):
893
"""
894
Returns the q-expansion of the modular form 0.
895
896
EXAMPLES::
897
898
sage: M = ModularForms(11,2)
899
sage: M._q_expansion_zero()
900
0
901
sage: M._q_expansion_zero() == M._q_expansion_ring()(0)
902
True
903
"""
904
try:
905
return self.__q_expansion_zero
906
except AttributeError:
907
f = self._q_expansion_ring()(0)
908
self.__q_expansion_zero = f
909
return f
910
911
def _q_expansion(self, element, prec):
912
"""
913
Take an element of self (specified as a list, tuple, or vector),
914
and return the corresponding q-expansion.
915
916
EXAMPLES::
917
918
sage: m = ModularForms(Gamma0(23),2); m
919
Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Rational Field
920
sage: m.basis()
921
[
922
q - q^3 - q^4 + O(q^6),
923
q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6),
924
1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6)
925
]
926
sage: m._q_expansion([1,2,0], 5)
927
q + 2*q^2 - 5*q^3 - 3*q^4 + O(q^5)
928
"""
929
return self.ambient_module()._q_expansion(element, prec)
930
931
def __add__(self, right):
932
"""
933
If self and right live inside the same ambient module, return the
934
sum of the two spaces (as modules).
935
936
EXAMPLES::
937
938
sage: N = CuspForms(44,2) ; ls = [N.submodule([N(u) for u in x.q_expansion_basis(20)]) for x in N.modular_symbols().decomposition()]; ls
939
[Modular Forms subspace of dimension 1 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field,
940
Modular Forms subspace of dimension 3 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field]
941
942
::
943
944
sage: N1 = ls[0] ; N2 = ls[1]
945
sage: N1 + N2 # indirect doctest
946
Modular Forms subspace of dimension 4 of Modular Forms space of dimension 9 for Congruence Subgroup Gamma0(44) of weight 2 over Rational Field
947
"""
948
from sage.modular.modform.submodule import ModularFormsSubmodule
949
if self.ambient_module() != right.ambient_module():
950
raise ArithmeticError, ("Sum of %s and %s not defined because " + \
951
"they do not lie in a common ambient space.")%\
952
(self, right)
953
if self.is_ambient(): return self
954
if right.is_ambient(): return right
955
V = self.free_module() + right.free_module()
956
return ModularFormsSubmodule(self.ambient_module(), V)
957
958
def _has_natural_inclusion_map_to(self, right):
959
"""
960
Return true if there is a natural inclusion map from modular forms
961
in self to modular forms in right.
962
963
INPUT:
964
965
966
- ``self, right`` - spaces of modular forms
967
968
969
OUTPUT: True if self embeds in right, and False otherwise.
970
971
TODO: Barring a few trivial cases, this only works in the case that
972
right.is_ambient() returns True.
973
974
EXAMPLES::
975
976
sage: N = ModularForms(6,4) ; S = N.cuspidal_subspace()
977
978
::
979
980
sage: N._has_natural_inclusion_map_to(S)
981
Traceback (most recent call last):
982
...
983
NotImplementedError
984
985
::
986
987
sage: S._has_natural_inclusion_map_to(N)
988
True
989
990
::
991
992
sage: M = ModularForms(11,2)
993
sage: N._has_natural_inclusion_map_to(M)
994
False
995
"""
996
if not right.group().is_subgroup(self.group()):
997
return False
998
if right.character() is None:
999
# It's the full Gamma_1(N).
1000
return True
1001
if right.is_ambient():
1002
e = self.character()
1003
f = right.character()
1004
return f.parent()(e) == f
1005
raise NotImplementedError
1006
1007
def has_coerce_map_from_impl(self, from_par):
1008
"""
1009
Code to make ModularFormsSpace work well with coercion framework.
1010
1011
EXAMPLES::
1012
1013
sage: M = ModularForms(22,2)
1014
sage: M.has_coerce_map_from_impl(M.cuspidal_subspace())
1015
True
1016
sage: M.has_coerce_map_from(ModularForms(22,4))
1017
False
1018
"""
1019
if isinstance(from_par, ModularFormsSpace):
1020
if from_par.ambient() == self:
1021
return True
1022
elif self.is_ambient() and self.group().is_subgroup(from_par.group()) and self.weight() == from_par.weight():
1023
return True
1024
1025
return False
1026
1027
def _coerce_impl(self, x):
1028
"""
1029
Code to coerce an element into self.
1030
1031
EXAMPLES::
1032
1033
sage: M = ModularForms(22,2) ; S = CuspForms(22,2)
1034
sage: sum(S.basis())
1035
q + q^2 - q^3 - 4*q^4 + q^5 + O(q^6)
1036
sage: sum(S.basis() + M.basis())
1037
1 + 3*q + 3*q^2 + 2*q^3 - 7*q^4 + 8*q^5 + O(q^6)
1038
sage: M._coerce_impl(S.basis()[0])
1039
q - q^3 - 2*q^4 + q^5 + O(q^6)
1040
1041
::
1042
1043
sage: M = ModularForms(Gamma0(22)) ; N = ModularForms(Gamma0(44))
1044
sage: M.basis()[0]
1045
q - q^3 - 2*q^4 + q^5 + O(q^6)
1046
sage: N(M.basis()[0])
1047
q - q^3 - 2*q^4 + q^5 + O(q^6)
1048
"""
1049
if isinstance(x, element.ModularFormElement):
1050
if x.parent().ambient() == self:
1051
return self(x.element())
1052
elif self.group().is_subgroup(x.parent().group()):
1053
## This is a coercion M_k(Gamma) --> M_k(Gamma'),
1054
## where Gamma' is contained in Gamma.
1055
return self(x.q_expansion(self._q_expansion_module().degree()))
1056
1057
raise TypeError, "no known coercion to modular form"
1058
1059
def __call__(self, x, check=True):
1060
"""
1061
Try to coerce x into self. If x is a vector of length
1062
self.dimension(), interpret it as a list of coefficients for
1063
self.basis() and return that linear combination. If x is a power
1064
series, it tries to determine whether or not x lives in self. If
1065
so, it returns x as an element of M, and throws an error if not.
1066
1067
EXAMPLES::
1068
1069
sage: M = ModularForms(13,4)
1070
sage: M.dimension()
1071
5
1072
1073
::
1074
1075
sage: M([1,2,3,4,5])
1076
4 + 6*q + 47*q^2 + 143*q^3 + 358*q^4 + 630*q^5 + O(q^6)
1077
1078
::
1079
1080
sage: M([1,3])
1081
Traceback (most recent call last):
1082
...
1083
TypeError: entries must be a list of length 5
1084
1085
::
1086
1087
sage: R = M._q_expansion_ring()
1088
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(9))
1089
q - 2*q^5 + O(q^6)
1090
1091
::
1092
1093
sage: M.set_precision(9)
1094
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(9))
1095
q - 2*q^5 - 4*q^6 - 2*q^7 - 12*q^8 + O(q^9)
1096
1097
Note that one only needs coefficients up to self.sturm_bound() to
1098
determine the form::
1099
1100
sage: M(R([0,1,0,0,0,-2,-4,-2,-12]).add_bigoh(8))
1101
q - 2*q^5 - 4*q^6 - 2*q^7 - 12*q^8 + O(q^9)
1102
1103
::
1104
1105
sage: M(R([0,1,1,0,0,0,-4,-2,-12]).add_bigoh(9))
1106
Traceback (most recent call last):
1107
...
1108
ValueError: q-expansion does not correspond to a form in self
1109
1110
::
1111
1112
sage: S = CuspForms(1,12) ; R = PowerSeriesRing(QQ,'q') ; q = R.0
1113
sage: f = q+O(q^2) ; S(f)
1114
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
1115
sage: f = q+2*q^2+O(q^3) ; S(f)
1116
Traceback (most recent call last):
1117
...
1118
ValueError: q-expansion does not correspond to a form in self
1119
sage: f = q-24*q^2+O(q^3) ; S(f)
1120
q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
1121
"""
1122
if isinstance(x, element.ModularFormElement):
1123
if x.parent() is self:
1124
return x
1125
1126
if not check:
1127
from copy import copy
1128
f = copy(x)
1129
f._set_parent(self)
1130
return f
1131
1132
try:
1133
if x.parent()._has_natural_inclusion_map_to(self.ambient()):
1134
W = self._q_expansion_module()
1135
return self(x.q_expansion(W.degree()))
1136
except NotImplementedError:
1137
pass
1138
raise TypeError, "unable to coerce x (= %s) into %s"%(x, self)
1139
1140
elif rings.is_PowerSeries(x):
1141
W = self._q_expansion_module()
1142
if W.degree() <= x.prec():
1143
try:
1144
x_potential = W.coordinates(x.padded_list(W.degree()))
1145
except ArithmeticError:
1146
raise ValueError, "q-expansion does not correspond to a form in self"
1147
x_potential = self.free_module().linear_combination_of_basis(x_potential)
1148
x_potential = element.ModularFormElement(self, x_potential)
1149
for i in range(int(W.degree()), x.prec()):
1150
if x_potential[i] != x[i]:
1151
raise ValueError, "q-expansion does not correspond to a form in self"
1152
return x_potential
1153
else:
1154
raise TypeError, "q-expansion needed to at least precision %s"%W.degree()
1155
return element.ModularFormElement(self, self.free_module()(x,check))
1156
1157
def __cmp__(self, x):
1158
"""
1159
Compare self and x.
1160
1161
For spaces of modular forms, we order first by signature, then by
1162
dimension, and then by the ordering on the underlying free
1163
modules.
1164
1165
EXAMPLES::
1166
1167
sage: N = ModularForms(6,4) ; S = N.cuspidal_subspace()
1168
sage: S.__cmp__(N)
1169
-1
1170
sage: N.__cmp__(S)
1171
1
1172
sage: N.__cmp__(N)
1173
0
1174
sage: M = ModularForms(11,2)
1175
sage: N.__cmp__(M)
1176
-1
1177
sage: M.__cmp__(N)
1178
-1
1179
"""
1180
from sage.modular.modform.constructor import canonical_parameters as params
1181
1182
if self is x:
1183
return 0
1184
if not isinstance(x, ModularFormsSpace):
1185
return cmp( type(self), type(x) )
1186
1187
left_ambient = self.ambient()
1188
right_ambient = x.ambient()
1189
if params(left_ambient.character(), left_ambient.level(),
1190
left_ambient.weight(), left_ambient.base_ring()) != \
1191
params(right_ambient.character(), right_ambient.level(),
1192
right_ambient.weight(), right_ambient.base_ring()):
1193
return -1
1194
if self.is_ambient() or x.is_ambient():
1195
return cmp(self.dimension(), x.dimension())
1196
else:
1197
return cmp(self.free_module(), x.free_module())
1198
1199
def span_of_basis(self, B):
1200
"""
1201
Take a set B of forms, and return the subspace of self with B as a
1202
basis.
1203
1204
EXAMPLES::
1205
1206
sage: N = ModularForms(6,4) ; N
1207
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1208
1209
::
1210
1211
sage: N.span_of_basis([N.basis()[0]])
1212
Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1213
1214
::
1215
1216
sage: N.span_of_basis([N.basis()[0], N.basis()[1]])
1217
Modular Forms subspace of dimension 2 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1218
1219
::
1220
1221
sage: N.span_of_basis( N.basis() )
1222
Modular Forms subspace of dimension 5 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1223
"""
1224
W = self._q_expansion_module()
1225
F = self.free_module()
1226
prec = W.degree()
1227
C = [F.linear_combination_of_basis(W.coordinates(f.padded_list(prec))) for f in B]
1228
S = F.span_of_basis(C)
1229
return submodule.ModularFormsSubmoduleWithBasis(self.ambient(), S)
1230
1231
span = span_of_basis
1232
1233
def __submodule_from_subset_of_basis(self, x):
1234
"""
1235
Return the submodule of self generated by the elements of x.
1236
1237
EXAMPLES::
1238
1239
sage: N = ModularForms(6,4)
1240
sage: N._ModularFormsSpace__submodule_from_subset_of_basis( [0,2] )
1241
Vector space of degree 5 and dimension 2 over Rational Field
1242
Basis matrix:
1243
[1 0 0 0 0]
1244
[0 0 1 0 0]
1245
"""
1246
V = self.free_module()
1247
return V.submodule([V.gen(i) for i in x], check=False)
1248
1249
def _compute_hecke_matrix_prime(self, p, prec=None):
1250
"""
1251
Compute the matrix of the Hecke operator T_p acting on self.
1252
1253
EXAMPLES::
1254
1255
sage: M = ModularForms(11,2)
1256
sage: M._compute_hecke_matrix_prime(2)
1257
[-2 0]
1258
[ 0 3]
1259
1260
::
1261
1262
sage: M = ModularForms(11,2)
1263
sage: M2 = M.span([M.0 + M.1])
1264
sage: M2.hecke_matrix(2)
1265
Traceback (most recent call last):
1266
...
1267
ArithmeticError: vector is not in free module
1268
"""
1269
if prec is None:
1270
# Initial guess -- will increase if need be.
1271
# We add on a few dimensions, so we are likely to
1272
# detect non-invariant subspaces (if they accidentally occur).
1273
prec = p*self.dimension() + 8
1274
try:
1275
cur, _ = self.__q_expansion_basis
1276
except AttributeError:
1277
pass
1278
else:
1279
if prec < cur:
1280
prec = cur
1281
B = self.q_expansion_basis(prec)
1282
eps = self.character()
1283
if eps is None:
1284
raise NotImplementedError
1285
try:
1286
return hecke_operator_on_qexp.hecke_operator_on_basis(B, p,
1287
self.weight(), eps, already_echelonized=False)
1288
except ValueError:
1289
# Double the precision.
1290
return self._compute_hecke_matrix_prime(p, prec = 2*prec+1)
1291
1292
def _compute_hecke_matrix(self, n):
1293
"""
1294
Compute the matrix of the Hecke operator T_n acting on self.
1295
1296
EXAMPLES::
1297
1298
sage: M = ModularForms(11,2)
1299
sage: M._compute_hecke_matrix(6)
1300
[ 2 0]
1301
[ 0 12]
1302
1303
::
1304
1305
sage: M = ModularForms(11,2)
1306
sage: M2 = M.span([M.0 + M.1])
1307
sage: M2.hecke_matrix(2)
1308
Traceback (most recent call last):
1309
...
1310
ArithmeticError: vector is not in free module
1311
1312
We check that #10450 is fixed::
1313
1314
sage: M = CuspForms(Gamma1(22), 2).new_submodule() # long time (3s on sage.math, 2011)
1315
sage: M.hecke_matrix(3) # long time
1316
[ 0 -2 3 0]
1317
[ 0 -3 5 -1]
1318
[ 1 -1 0 -1]
1319
[ 0 -2 3 -1]
1320
sage: M.hecke_matrix(9) # long time
1321
[ 3 3 -4 -4]
1322
[ 2 6 -9 -4]
1323
[ 0 3 -2 -1]
1324
[ 3 2 -7 0]
1325
"""
1326
# For spaces with character, we calculate a basis of q-expansions and
1327
# use that. For Gamma1 and GammaH spaces, we would need to compute
1328
# diamond operators, which is quite slow; so we just compute on the
1329
# whole space and restrict.
1330
1331
# TODO: If we know the subspace of the modular *symbols* space to which
1332
# this modular forms space corresponds, then that might give a quicker
1333
# way of doing this step.
1334
1335
if hasattr(self, '_compute_q_expansion_basis') and self.character() is not None:
1336
return hecke.HeckeModule_generic._compute_hecke_matrix(self, n)
1337
1338
else:
1339
# Try to avoid doing unnecessary computations where possible.
1340
if self.is_cuspidal():
1341
M = self.ambient().cuspidal_submodule().hecke_matrix(n).block_sum(zero_matrix(self.base_ring(), self.ambient().eisenstein_submodule().rank()))
1342
elif self.is_eisenstein():
1343
M = zero_matrix(self.base_ring(), self.ambient().cuspidal_submodule().rank()).block_sum(self.ambient().eisenstein_submodule().hecke_matrix(n))
1344
else:
1345
M = self.ambient().hecke_matrix(n)
1346
return M.restrict(self.free_module(), check=(gcd(n, self.level()) > 1))
1347
1348
def basis(self):
1349
"""
1350
Return a basis for self.
1351
1352
EXAMPLES::
1353
1354
sage: MM = ModularForms(11,2)
1355
sage: MM.basis()
1356
[
1357
q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6),
1358
1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + O(q^6)
1359
]
1360
"""
1361
try:
1362
return self.__basis
1363
except AttributeError:
1364
self.__basis = Sequence([element.ModularFormElement(self, x) for \
1365
x in self.free_module().basis()], immutable=True,
1366
cr = True)
1367
return self.__basis
1368
1369
def gen(self, n):
1370
"""
1371
Return the nth generator of self.
1372
1373
EXAMPLES::
1374
1375
sage: N = ModularForms(6,4)
1376
sage: N.basis()
1377
[
1378
q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
1379
1 + O(q^6),
1380
q - 8*q^4 + 126*q^5 + O(q^6),
1381
q^2 + 9*q^4 + O(q^6),
1382
q^3 + O(q^6)
1383
]
1384
1385
::
1386
1387
sage: N.gen(0)
1388
q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6)
1389
1390
::
1391
1392
sage: N.gen(4)
1393
q^3 + O(q^6)
1394
1395
::
1396
1397
sage: N.gen(5)
1398
Traceback (most recent call last):
1399
...
1400
ValueError: Generator 5 not defined
1401
"""
1402
try:
1403
return self.basis()[int(n)]
1404
except IndexError:
1405
raise ValueError, "Generator %s not defined"%n
1406
1407
def gens(self):
1408
"""
1409
Return a complete set of generators for self.
1410
1411
EXAMPLES::
1412
1413
sage: N = ModularForms(6,4)
1414
sage: N.gens()
1415
[
1416
q - 2*q^2 - 3*q^3 + 4*q^4 + 6*q^5 + O(q^6),
1417
1 + O(q^6),
1418
q - 8*q^4 + 126*q^5 + O(q^6),
1419
q^2 + 9*q^4 + O(q^6),
1420
q^3 + O(q^6)
1421
]
1422
"""
1423
return self.basis()
1424
1425
def sturm_bound(self, M=None):
1426
r"""
1427
For a space M of modular forms, this function returns an integer B
1428
such that two modular forms in either self or M are equal if and
1429
only if their q-expansions are equal to precision B (note that this
1430
is 1+ the usual Sturm bound, since `O(q^\mathrm{prec})` has
1431
precision prec). If M is none, then M is set equal to self.
1432
1433
EXAMPLES::
1434
1435
sage: S37=CuspForms(37,2)
1436
sage: S37.sturm_bound()
1437
8
1438
sage: M = ModularForms(11,2)
1439
sage: M.sturm_bound()
1440
3
1441
sage: ModularForms(Gamma1(15),2).sturm_bound()
1442
33
1443
1444
sage: CuspForms(Gamma1(144), 3).sturm_bound()
1445
3457
1446
sage: CuspForms(DirichletGroup(144).1^2, 3).sturm_bound()
1447
73
1448
sage: CuspForms(Gamma0(144), 3).sturm_bound()
1449
73
1450
1451
REFERENCE:
1452
1453
- [Sturm] J. Sturm, On the congruence of modular forms, Number theory
1454
(New York, 1984-1985), Springer, Berlin, 1987, pp. 275-280.
1455
1456
NOTE:
1457
1458
Kevin Buzzard pointed out to me (William Stein) in Fall 2002 that
1459
the above bound is fine for Gamma1 with character, as one sees by
1460
taking a power of `f`. More precisely, if
1461
`f\cong 0\pmod{p}` for first `s` coefficients, then
1462
`f^r = 0 \pmod{p}` for first `s r` coefficients.
1463
Since the weight of `f^r` is
1464
`r \text{weight}(f)`, it follows that if
1465
`s \geq` the Sturm bound for `\Gamma_0` at
1466
weight(f), then `f^r` has valuation large enough to be
1467
forced to be `0` at `r\cdot` weight(f) by Sturm
1468
bound (which is valid if we choose `r` right). Thus
1469
`f \cong 0 \pmod{p}`. Conclusion: For `\Gamma_1`
1470
with fixed character, the Sturm bound is *exactly* the same as for
1471
`\Gamma_0`. A key point is that we are finding
1472
`\ZZ[\varepsilon]` generators for the Hecke algebra
1473
here, not `\ZZ`-generators. So if one wants
1474
generators for the Hecke algebra over `\ZZ`, this
1475
bound is wrong.
1476
1477
This bound works over any base, even a finite field. There might be
1478
much better bounds over `\QQ`, or for comparing two
1479
eigenforms.
1480
"""
1481
if M is not None:
1482
raise NotImplementedError
1483
if self.__sturm_bound is None:
1484
G = self.group()
1485
from sage.modular.arithgroup.all import is_Gamma1
1486
if is_Gamma1(G) and self.character() is not None:
1487
from sage.modular.arithgroup.all import Gamma0
1488
G = Gamma0(self.level())
1489
# the +1 below is because O(q^prec) has precision prec.
1490
self.__sturm_bound = G.sturm_bound(self.weight())+1
1491
return self.__sturm_bound
1492
1493
def character(self):
1494
"""
1495
Return the Dirichlet character of this space.
1496
1497
EXAMPLES::
1498
1499
sage: M = ModularForms(DirichletGroup(11).0, 3)
1500
sage: M.character()
1501
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
1502
sage: s = M.cuspidal_submodule()
1503
sage: s.character()
1504
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
1505
sage: CuspForms(DirichletGroup(11).0,3).character()
1506
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta10
1507
"""
1508
return self.__character
1509
1510
def cuspidal_submodule(self):
1511
"""
1512
Return the cuspidal submodule of self.
1513
1514
EXAMPLES::
1515
1516
sage: N = ModularForms(6,4) ; N
1517
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1518
sage: N.eisenstein_subspace().dimension()
1519
4
1520
1521
::
1522
1523
sage: N.cuspidal_submodule()
1524
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1525
1526
::
1527
1528
sage: N.cuspidal_submodule().dimension()
1529
1
1530
1531
We check that a bug noticed on trac #10450 is fixed::
1532
1533
sage: M = ModularForms(6, 10)
1534
sage: W = M.span_of_basis(M.basis()[0:2])
1535
sage: W.cuspidal_submodule()
1536
Modular Forms subspace of dimension 2 of Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(6) of weight 10 over Rational Field
1537
"""
1538
try:
1539
if self.__is_cuspidal == True:
1540
return self
1541
if self.__cuspidal_submodule != None:
1542
return self.__cuspidal_submodule
1543
except AttributeError:
1544
pass
1545
if self.is_ambient():
1546
# By definition the cuspidal submodule of the ambient space
1547
# is spanned by the first n standard basis vectors, where
1548
# n is the dimension of the cuspidal submodule.
1549
n = self.__ambient_cusp_dimension()
1550
W = self.__submodule_from_subset_of_basis(range(n))
1551
S = ModularForms(self, W)
1552
S.__is_cuspidal = True
1553
S.__is_eisenstein = (n==0)
1554
self.__cuspidal_submodule = S
1555
return S
1556
C = self.ambient_module().cuspidal_submodule()
1557
S = self.intersection(C)
1558
if S.dimension() < self.dimension():
1559
self.__is_cuspidal = False
1560
self.__cuspidal_submodule = S
1561
else:
1562
assert S.dimension() == self.dimension()
1563
self.__is_cuspidal = True
1564
S.__is_eisenstein = (S.dimension()==0)
1565
return S
1566
1567
def cuspidal_subspace(self):
1568
"""
1569
Synonym for cuspidal_submodule.
1570
1571
EXAMPLES::
1572
1573
sage: N = ModularForms(6,4) ; N
1574
Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1575
sage: N.eisenstein_subspace().dimension()
1576
4
1577
1578
::
1579
1580
sage: N.cuspidal_subspace()
1581
Cuspidal subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1582
1583
::
1584
1585
sage: N.cuspidal_submodule().dimension()
1586
1
1587
"""
1588
return self.cuspidal_submodule()
1589
1590
def is_cuspidal(self):
1591
r"""
1592
Return True if this space is cuspidal.
1593
1594
EXAMPLE::
1595
1596
sage: M = ModularForms(Gamma0(11), 2).new_submodule()
1597
sage: M.is_cuspidal()
1598
False
1599
sage: M.cuspidal_submodule().is_cuspidal()
1600
True
1601
"""
1602
return (self.cuspidal_submodule() == self)
1603
1604
def is_eisenstein(self):
1605
r"""
1606
Return True if this space is Eisenstein.
1607
1608
EXAMPLE::
1609
1610
sage: M = ModularForms(Gamma0(11), 2).new_submodule()
1611
sage: M.is_eisenstein()
1612
False
1613
sage: M.eisenstein_submodule().is_eisenstein()
1614
True
1615
"""
1616
return (self.eisenstein_submodule() == self)
1617
1618
def new_submodule(self, p=None):
1619
"""
1620
Return the new submodule of self. If p is specified, return the
1621
p-new submodule of self.
1622
1623
.. note::
1624
1625
This function should be overridden by all derived classes.
1626
1627
EXAMPLES::
1628
1629
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,base_ring=QQ) ; M.new_submodule()
1630
Traceback (most recent call last):
1631
...
1632
NotImplementedError: computation of new submodule not yet implemented
1633
"""
1634
raise NotImplementedError, "computation of new submodule not yet implemented"
1635
1636
def new_subspace(self, p=None):
1637
"""
1638
Synonym for new_submodule.
1639
1640
EXAMPLES::
1641
1642
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,base_ring=QQ) ; M.new_subspace()
1643
Traceback (most recent call last):
1644
...
1645
NotImplementedError: computation of new submodule not yet implemented
1646
"""
1647
return self.new_submodule(p)
1648
1649
def eisenstein_series(self):
1650
"""
1651
Compute the Eisenstein series associated to this space.
1652
1653
.. note::
1654
1655
This function should be overridden by all derived classes.
1656
1657
EXAMPLES::
1658
1659
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,base_ring=QQ) ; M.eisenstein_series()
1660
Traceback (most recent call last):
1661
...
1662
NotImplementedError: computation of Eisenstein series in this space not yet implemented
1663
"""
1664
raise NotImplementedError, "computation of Eisenstein series in this space not yet implemented"
1665
1666
def decomposition(self):
1667
"""
1668
This function returns a list of submodules `V(f_i,t)`
1669
corresponding to newforms `f_i` of some level dividing the
1670
level of self, such that the direct sum of the submodules equals
1671
self, if possible. The space `V(f_i,t)` is the image under
1672
`g(q)` maps to `g(q^t)` of the intersection with
1673
`R[[q]]` of the space spanned by the conjugates of
1674
`f_i`, where `R` is the base ring of self.
1675
1676
TODO: Implement this function.
1677
1678
EXAMPLES::
1679
1680
sage: M = ModularForms(11,2); M.decomposition()
1681
Traceback (most recent call last):
1682
...
1683
NotImplementedError
1684
"""
1685
raise NotImplementedError
1686
1687
def newforms(self, names=None):
1688
"""
1689
Return all newforms in the cuspidal subspace of self.
1690
1691
EXAMPLES::
1692
1693
sage: CuspForms(18,4).newforms()
1694
[q + 2*q^2 + 4*q^4 - 6*q^5 + O(q^6)]
1695
sage: CuspForms(32,4).newforms()
1696
[q - 8*q^3 - 10*q^5 + O(q^6), q + 22*q^5 + O(q^6), q + 8*q^3 - 10*q^5 + O(q^6)]
1697
sage: CuspForms(23).newforms('b')
1698
[q + b0*q^2 + (-2*b0 - 1)*q^3 + (-b0 - 1)*q^4 + 2*b0*q^5 + O(q^6)]
1699
sage: CuspForms(23).newforms()
1700
Traceback (most recent call last):
1701
...
1702
ValueError: Please specify a name to be used when generating names for generators of Hecke eigenvalue fields corresponding to the newforms.
1703
"""
1704
M = self.modular_symbols(sign=1)
1705
factors = M.cuspidal_subspace().new_subspace().decomposition()
1706
large_dims = [ X.dimension() for X in factors if X.dimension() != 1 ]
1707
if len(large_dims) > 0 and names is None:
1708
raise ValueError, "Please specify a name to be used when generating names for generators of Hecke eigenvalue fields corresponding to the newforms."
1709
elif names is None:
1710
# In this case, we don't need a variable name, so insert
1711
# something to get passed along below
1712
names = 'a'
1713
return [ element.Newform(self, factors[i], names=(names+str(i)) )
1714
for i in range(len(factors)) ]
1715
1716
def eisenstein_submodule(self):
1717
"""
1718
Return the Eisenstein submodule for this space of modular forms.
1719
1720
EXAMPLES::
1721
1722
sage: M = ModularForms(11,2)
1723
sage: M.eisenstein_submodule()
1724
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
1725
1726
We check that a bug noticed on trac #10450 is fixed::
1727
1728
sage: M = ModularForms(6, 10)
1729
sage: W = M.span_of_basis(M.basis()[0:2])
1730
sage: W.eisenstein_submodule()
1731
Modular Forms subspace of dimension 0 of Modular Forms space of dimension 11 for Congruence Subgroup Gamma0(6) of weight 10 over Rational Field
1732
"""
1733
try:
1734
if self.__is_eisenstein == True:
1735
return self
1736
except AttributeError:
1737
pass
1738
try:
1739
if self.__eisenstein_submodule != None:
1740
return self.__eisenstein_submodule
1741
except AttributeError:
1742
pass
1743
1744
if self.is_ambient():
1745
# By definition the eisenstein submodule of the ambient space
1746
# is spanned by the n+1 through n+d standard basis vectors, where
1747
# n is the dimension of the cuspidal submodule and d
1748
# is the dimension of the eisenstein submodule (i.e., the
1749
# number of eisenstein series).
1750
n = self.__ambient_cusp_dimension()
1751
d = self.__ambient_eis_dimension()
1752
W = self.__submodule_from_subset_of_basis(range(n,n+d))
1753
E = ModularForms(self, W)
1754
E.__is_eisenstein = True
1755
E.__is_cuspidal = (d==0)
1756
self.__eisenstein_submodule = E
1757
return E
1758
A = self.ambient_module().eisenstein_submodule()
1759
E = self.intersection(A)
1760
if E.dimension() < self.dimension():
1761
self.__is_eisenstein = False
1762
self.__eisenstein_submodule = E
1763
else:
1764
assert E.dimension() == self.dimension()
1765
self.__is_eisenstein = True
1766
E.__is_cuspidal = (E.dimension()==0)
1767
return E
1768
1769
def eisenstein_subspace(self):
1770
"""
1771
Synonym for eisenstein_submodule.
1772
1773
EXAMPLES::
1774
1775
sage: M = ModularForms(11,2)
1776
sage: M.eisenstein_subspace()
1777
Eisenstein subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field
1778
"""
1779
return self.eisenstein_submodule()
1780
1781
def embedded_submodule(self):
1782
"""
1783
Return the underlying module of self.
1784
1785
EXAMPLES::
1786
1787
sage: N = ModularForms(6,4)
1788
sage: N.dimension()
1789
5
1790
1791
::
1792
1793
sage: N.embedded_submodule()
1794
Vector space of dimension 5 over Rational Field
1795
"""
1796
return self.free_module()
1797
1798
# intersect method commented out since it is a duplicate of the intersection method in sage.modular.hecke.submodule
1799
# -- David Loeffler, 2009-04-30
1800
#
1801
# def intersect(self, right):
1802
# """
1803
# If self and right live in the same ambient module, return the
1804
# intersection of self and right (as submodules).
1805
#
1806
# EXAMPLES::
1807
#
1808
# sage: N = ModularForms(6,4); S = N.cuspidal_subspace()
1809
#
1810
# ::
1811
#
1812
# sage: N.intersect(S)
1813
# Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1814
#
1815
# ::
1816
#
1817
# sage: S.intersect(N)
1818
# Modular Forms subspace of dimension 1 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1819
#
1820
# ::
1821
#
1822
# sage: S.intersect(N.eisenstein_subspace())
1823
# Modular Forms subspace of dimension 0 of Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Rational Field
1824
# """
1825
# from sage.modular.modform.all import ModularForms
1826
# if self.ambient_module() != right.ambient_module():
1827
# raise ArithmeticError, "Intersection of %s and %s not defined."%\
1828
# (self, right)
1829
# V = self.embedded_submodule().intersection(right.embedded_submodule())
1830
## return ModularForms(self.ambient_module(),V)
1831
# return self.span([ self(b) for b in V.basis() ])
1832
1833
## def _key(self):
1834
## if self.is_ambient():
1835
## return self.__key
1836
## return self.__ambient
1837
1838
def level(self):
1839
"""
1840
Return the level of self.
1841
1842
EXAMPLES::
1843
1844
sage: M = ModularForms(47,3)
1845
sage: M.level()
1846
47
1847
"""
1848
return self.group().level()
1849
1850
def modular_symbols(self, sign=0):
1851
"""
1852
Return the space of modular symbols corresponding to self with the
1853
given sign.
1854
1855
.. note;:
1856
1857
This function should be overridden by all derived classes.
1858
1859
EXAMPLES::
1860
1861
sage: M = sage.modular.modform.space.ModularFormsSpace(Gamma0(11),2,DirichletGroup(1).0,base_ring=QQ) ; M.modular_symbols()
1862
Traceback (most recent call last):
1863
...
1864
NotImplementedError: computation of associated modular symbols space not yet implemented
1865
"""
1866
raise NotImplementedError, "computation of associated modular symbols space not yet implemented"
1867
1868
def find_in_space(self, f, forms=None, prec=None, indep=True):
1869
"""
1870
INPUT:
1871
1872
1873
- ``f`` - a modular form or power series
1874
1875
- ``forms`` - (default: None) a specific list of
1876
modular forms or q-expansions.
1877
1878
- ``prec`` - if forms are given, compute with them to
1879
the given precision
1880
1881
- ``indep`` - (default: True) whether the given list
1882
of forms are assumed to form a basis.
1883
1884
1885
OUTPUT: A list of numbers that give f as a linear combination of
1886
the basis for this space or of the given forms if
1887
independent=True.
1888
1889
.. note::
1890
1891
If the list of forms is given, they do *not* have to be in
1892
self.
1893
1894
EXAMPLES::
1895
1896
sage: M = ModularForms(11,2)
1897
sage: N = ModularForms(10,2)
1898
sage: M.find_in_space( M.basis()[0] )
1899
[1, 0]
1900
1901
::
1902
1903
sage: M.find_in_space( N.basis()[0], forms=N.basis() )
1904
[1, 0, 0]
1905
1906
::
1907
1908
sage: M.find_in_space( N.basis()[0] )
1909
Traceback (most recent call last):
1910
...
1911
ArithmeticError: vector is not in free module
1912
"""
1913
if forms is None or (forms == []):
1914
B = self._q_expansion_module()
1915
V = B.ambient_module()
1916
n = B.degree()
1917
else:
1918
if not isinstance(forms, (list, tuple)):
1919
raise TypeError, "forms must be a list or tuple"
1920
if prec is None:
1921
n = forms[0].parent().prec()
1922
else:
1923
n = prec
1924
V = self.base_ring()**n
1925
w = [V(g.padded_list(n)) for g in forms]
1926
if indep:
1927
B = V.span_of_basis(w)
1928
else:
1929
B = V.span(w)
1930
if rings.is_PowerSeries(f) and f.prec() < n:
1931
raise ValueError, "you need at least %s terms of precision"%n
1932
x = V(f.padded_list(n))
1933
return B.coordinates(x)
1934
1935
1936
def contains_each(V, B):
1937
"""
1938
Determine whether or not V contains every element of B. Used here
1939
for linear algebra, but works very generally.
1940
1941
EXAMPLES::
1942
1943
sage: contains_each = sage.modular.modform.space.contains_each
1944
sage: contains_each( range(20), prime_range(20) )
1945
True
1946
sage: contains_each( range(20), range(30) )
1947
False
1948
"""
1949
for b in B:
1950
if not (b in V):
1951
return False
1952
return True
1953
1954