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