CoCalc Public Fileswww / tables / magma_src / ModFrm / q-expansions.mOpen with one click!
Author: William A. Stein
1
freeze;
2
3
/****-*-magma-* EXPORT DATE: 2004-11-23 ************************************
4
5
MODFORM: Modular Forms in MAGMA
6
7
William A. Stein
8
9
FILE: q-expansions.m
10
11
08/15/03: (WAS) Added intrinsic CyclotomicEmbedding as requested by Kevin Buzzard.
12
13
08/15/03: (WAS) Fixed significant bug found by Kevin Buzzard in
14
MoveIntoPowerSeriesRingOverANumberField
15
that would have caused incorrect q-expansions
16
for modular forms in some cases.
17
18
04/05/03: (WAS) fixed bug in qExpansionOfModularFormsBasis:
19
When level 1 one and base ring wasn't Z it would
20
not coerce the basis correctly.
21
22
------------- old RCS comments ------------
23
24
Revision 1.13 2002/09/11 17:36:40 was
25
Nothing.
26
27
Revision 1.12 2002/05/30 09:42:09 was
28
Made default for PrecisionBound Exact := false, since this speeds up lots of other code.
29
30
Revision 1.11 2002/05/22 21:34:56 was
31
Added Bound parameter to CoefficientRing.
32
33
Revision 1.10 2001/12/07 01:12:47 was
34
fixed little bug in Coefficient.
35
36
Revision 1.9 2001/12/05 22:11:51 was
37
Added CoefficientRing and CoefficientField.
38
39
Revision 1.8 2001/11/22 17:54:18 was
40
Added a Coefficient intrinsic.
41
42
Revision 1.7 2001/11/10 18:48:19 was
43
Changed from SeqEnum to List in an assertion to ApplyMapsTo_qExpansion.
44
45
Revision 1.6 2001/11/10 18:34:11 was
46
Fixed serious bug in Reductions.
47
48
Revision 1.5 2001/10/25 02:53:17 was
49
??
50
51
Revision 1.4 2001/07/26 19:23:10 was
52
Added some more verbosity.
53
54
Revision 1.3 2001/05/30 18:56:42 was
55
Created.
56
57
Revision 1.2 2001/05/16 04:11:23 was
58
*** empty log message ***
59
60
Revision 1.1 2001/05/16 03:52:09 was
61
Initial revision
62
63
64
***************************************************************************/
65
66
import "level1.m": Level1Basis;
67
68
import "eisenstein.m" : BasisOfEisensteinSeries;
69
70
import "misc.m" : EchelonPowerSeriesSequence;
71
import "misc.m" : SaturatePowerSeriesSequence;
72
import "misc.m" : CoercePowerSeries;
73
import "misc.m" : ToLowerCaseLetter;
74
75
import "modular_symbols.m" : MF_ModularSymbols;
76
77
import "newforms.m" : ComputeEisensteinNewforms;
78
79
import "predicates.m": CoercionMap;
80
import "predicates.m": AssociatedSpaceOverZ;
81
import "predicates.m": SpaceType;
82
83
import "qexp_mappings.m" : ModpReductionMaps;
84
import "qexp_mappings.m" : pAdicEmbeddingMaps;
85
import "qexp_mappings.m" : ComplexEmbeddingMaps;
86
87
forward BasisOfHalfIntegralWeightForms,
88
ClearDenominators,
89
ClearDenominatorsAndSaturate,
90
CoercePowerSeriesElement,
91
Compute_ith_Conjugate,
92
Compute_qExpansionsOfForm,
93
qExpansionOfModularFormsBasis,
94
RestrictionOfScalarsToQ;
95
96
function ExactPrecisionBound(M)
97
assert Type(M) eq ModFrm;
98
b := Dimension(M);
99
q := PowerSeriesRing(BaseRing(M)).1;
100
f := M.Dimension(M);
101
while PowerSeries(f,b) eq O(q^b) do
102
b +:= 1;
103
end while;
104
return b;
105
end function;
106
107
function ApproximatePrecisionBound(M)
108
assert Type(M) eq ModFrm;
109
N := Level(M);
110
k := Weight(M);
111
es := Dimension(EisensteinSubspace(M));
112
function idxG0(n)
113
return &*[Integers()| t[1]^t[2] + t[1]^(t[2]-1) : t in Factorization(n)];
114
end function;
115
function idxG1(n)
116
return EulerPhi(n)*idxG0(n);
117
end function;
118
if IsGamma0(M) then
119
return Ceiling(idxG0(N)*(k/12))+1 + es;
120
else
121
return Ceiling(idxG1(N)*(k/12))+1 + es;
122
end if;
123
end function;
124
125
intrinsic PrecisionBound(M::ModFrm : Exact := false) -> RngIntElt
126
{Some integer b such that f + O(q^b) determines
127
any modular form f in M. If the optional paramater Exact
128
is set to true then the smallest integer b such that f+O(q^b) determines
129
any modular form f in M is returned.}
130
if IsRingOfAllModularForms(M) then
131
return Infinity();
132
end if;
133
if not assigned M`precision_bound then
134
if Exact then
135
M`precision_bound := ExactPrecisionBound(M);
136
else
137
return ApproximatePrecisionBound(M);
138
end if;
139
end if;
140
return M`precision_bound;
141
end intrinsic;
142
143
/*function ExactNewformPrecisionBound(M)
144
error "Not written";
145
end function;
146
147
function ApproximateNewformPrecisionBound(M)
148
return PrecisionBound(M : Exact := false); // very bad!!
149
end function;
150
151
intrinsic NewformPrecisionBound(M::ModFrm : Exact := true) -> RngIntElt
152
{The smallest integer b such that f + O(q^b) determines
153
any newform f in M. If the optional paramater Exact
154
is set to false than some integer b such that f+O(q^b) determines
155
any modular form f in M is returned, but b need not be minimal.}
156
if IsRingOfAllModularForms(M) then
157
return Infinity();
158
end if;
159
if not assigned M`newform_precision_bound then
160
if Exact then
161
M`newform_precision_bound := ExactNewformPrecisionBound(M);
162
else
163
return ApproximateNewformPrecisionBound(M);
164
end if;
165
end if;
166
return M`newform_precision_bound;
167
end intrinsic;
168
*/
169
170
function idxG0(n)
171
return
172
&*[Integers()| t[1]^t[2] + t[1]^(t[2]-1) : t in Factorization(n)];
173
end function;
174
175
function idxG1(n)
176
return EulerPhi(n)*idxG0(n);
177
end function;
178
179
intrinsic CoefficientRing(f::ModFrmElt : Bound := -1) -> Rng
180
{A ring that contains the coefficients of f. If IsNewform(f) is true, then
181
this is the ring generated by the Fourier coefficients. The optional
182
paramater Bound can be used to obtain the ring generated by the coefficients
183
a_n with n <= Bound.}
184
if IsNewform(f) then
185
if Bound eq -1 then
186
if IsGamma0(Parent(f)) then
187
bnd := Ceiling(Weight(f) * idxG0(Level(f)) / 12);
188
else
189
bnd := Ceiling(Weight(f) * idxG1(Level(f)) / 12);
190
end if;
191
else
192
bnd := Max(Bound,1);
193
end if;
194
qexp := PowerSeries(f,bnd+1);
195
return Order([Coefficient(qexp,n) : n in [2..bnd]]);
196
else
197
return Parent(Coefficient(f,1));
198
end if;
199
end intrinsic;
200
201
intrinsic CoefficientField(f::ModFrmElt) -> Fld
202
{The field in the which the Fourier coefficients lie.}
203
return FieldOfFractions(Parent(Coefficient(f,1)));
204
end intrinsic;
205
206
intrinsic Coefficient(f::ModFrmElt, n::RngIntElt) -> RngElt
207
{The nth Fourier coefficient of f.}
208
requirege n, 0;
209
return Coefficient(PowerSeries(f,n+1),n);
210
end intrinsic;
211
212
intrinsic qExpansion(f::ModFrmElt) -> RngSerPowElt
213
{}
214
return PowerSeries(f);
215
end intrinsic;
216
217
intrinsic PowerSeries(f::ModFrmElt) -> RngSerPowElt
218
{}
219
return PowerSeries(f,Precision(Parent(f)));
220
end intrinsic;
221
222
intrinsic qExpansion(f::ModFrmElt, prec::RngIntElt) -> RngSerPowElt
223
{}
224
return PowerSeries(f,prec);
225
end intrinsic;
226
227
intrinsic PowerSeries(f::ModFrmElt, prec::RngIntElt) -> RngSerPowElt
228
{The q-expansion of the modular form f to absolute precision prec.}
229
if not assigned f`q_expansion or
230
AbsolutePrecision(f`q_expansion) lt prec then
231
f`q_expansion := Compute_qExpansionsOfForm(f,"normal", 0, prec)[1][1];
232
end if;
233
R := Parent(f`q_expansion);
234
if assigned Parent(f)`q_name then
235
name := Parent(f)`q_name;
236
else
237
name := "q";
238
end if;
239
AssignNames(~R,[name]);
240
return f`q_expansion + O(R.1^prec);
241
end intrinsic;
242
243
function Turn_qExpansionsIntoModularForms(f, expansions)
244
ans := [* *];
245
for orb in expansions do
246
mf_orb := [* *];
247
for g in orb do
248
M := BaseExtend(Parent(f),BaseRing(Parent(g)));
249
Append(~mf_orb, M!g);
250
mf_orb[#mf_orb]`degree := #orb;
251
end for;
252
Append(~ans, mf_orb);
253
end for;
254
return ans;
255
end function;
256
257
intrinsic Reductions(f::ModFrmElt, p::RngIntElt) -> List
258
{The mod p reductions of the modular form f. Because of denominators,
259
the list of reductions can be empty.}
260
require IsPrime(p) and p gt 0 : "Argument 2 must be prime.";
261
require Type(BaseRing(Parent(f))) in
262
{FldRat, RngInt, FldCyc, FldNum} :
263
"The base ring of the parent of argument 1 must be a number field or Z.";
264
265
if not assigned f`modp_reductions then
266
f`modp_reductions := []; // sequence of pairs <p,fbar>
267
end if;
268
if exists(i) { i : i in [1..#f`modp_reductions]
269
| f`modp_reductions[i][1] eq p } then
270
return f`modp_reductions[i][2];
271
end if;
272
prec := PrecisionBound(AmbientSpace(Parent(f)));
273
if IsEisensteinSeries(f) then
274
c0 := Coefficient(PowerSeries(f,1),0);
275
if Type(Parent(c0)) eq FldRat then
276
denom := Denominator(c0);
277
else
278
denom := LCM([Denominator(b) : b in Eltseq(c0)]);
279
end if;
280
if denom mod p eq 0 then
281
return [* *];
282
end if;
283
end if;
284
expansions := Compute_qExpansionsOfForm(f,"modp", p, prec);
285
modp_forms := Turn_qExpansionsIntoModularForms(f, expansions);
286
Append(~f`modp_reductions, <p, modp_forms>);
287
288
return (f`modp_reductions[#f`modp_reductions])[2];
289
end intrinsic;
290
291
intrinsic pAdicEmbeddings(f::ModFrmElt, p::RngIntElt) -> List
292
{The p-adic embeddings of f.}
293
require IsPrime(p) and p gt 0 : "Argument 2 must be prime.";
294
require Type(BaseRing(Parent(f))) in
295
{FldRat, RngInt, FldCyc, FldNum} :
296
"The base ring of the parent of argument 1 must be a number field or Z.";
297
/*
298
if not assigned f`padic_embeddings then
299
f`padic_embeddings := []; // sequence of pairs <p,fbar>
300
end if;
301
if exists(i) { i : i in [1..#f`padic_embeddings]
302
| f`padic_embeddings[i][1] eq p } then
303
return f`padic_embeddings[i][2];
304
end if;
305
*/
306
307
prec := PrecisionBound(Parent(f));
308
expansions := Compute_qExpansionsOfForm(f,"padic", p, prec);
309
padic_forms := Turn_qExpansionsIntoModularForms(f, expansions);
310
return padic_forms;
311
312
/*
313
Append(~f`padic_embeddings, <p, padic_forms>);
314
315
return (f`padic_embeddings[#f`padic_embeddings])[2];
316
*/
317
end intrinsic;
318
319
intrinsic ComplexEmbeddings(f::ModFrmElt) -> List
320
{The complex embeddings of f.}
321
prec := PrecisionBound(Parent(f));
322
expansions := Compute_qExpansionsOfForm(f,"complex", 0, prec);
323
complex_forms := Turn_qExpansionsIntoModularForms(f, expansions);
324
return complex_forms;
325
end intrinsic;
326
327
/*
328
GeneralizedBernoulli:
329
k : RngIntElt, nonnegative integer weight
330
eps : GrpDrchElt, a Dirichlet character (not necessarily primitive)
331
332
Compute the generalized Bernoulli numbers B_{k,eps}, as defined
333
on page 44 of Diamond-Im:
334
335
sum_{a=1}^{N} eps(a) t*e^(at)/(e^(N*t)-1)
336
337
= sum_{k=0}^{\infty} B_{k,eps}/{k!}*t^k.
338
339
where N is the modulus of eps.
340
*/
341
342
function GeneralizedBernoulli(k, eps)
343
assert Type(k) eq RngIntElt and k ge 0;
344
assert Type(eps) eq GrpDrchElt;
345
assert Evaluate(eps,-1) eq (-1)^k;
346
347
N := Modulus(eps);
348
K := BaseRing(eps);
349
R<t> := LaurentSeriesRing(K);
350
prec := k+5;
351
F := &+[Evaluate(eps,a)*t*Exp(a*t+O(t^prec))/(Exp(N*t+O(t^prec)) -1)
352
: a in [1..N]];
353
Bk := Coefficient(F,k)*Factorial(k);
354
return Bk;
355
end function;
356
357
358
function qExpansion_EisensteinSeries(f,prec)
359
assert Type(f) eq ModFrmElt;
360
assert Type(prec) eq RngIntElt;
361
assert assigned f`eisenstein;
362
/*
363
364
chi is a primitive character of conductor L
365
psi is a primitive character of conductor M
366
MLt divides N
367
368
E_k(chi,psi,t) is
369
c_0 + sum_{m \geq 1}[sum_{n|m}psi(n)n^{k-1}chi(m/n)] q^{mt}
370
c_0=0 if L>1
371
and
372
c_0=L(1-k,psi)/2 if L=1 (that second L is an L-function L)
373
374
*/
375
376
chi, psi, t := Explode(EisensteinData(f));
377
L := Conductor(chi);
378
M := Conductor(psi);
379
mstop := (prec div t) + 1;
380
381
m := LCM(CyclotomicOrder(BaseRing(chi)), CyclotomicOrder(BaseRing(psi)));
382
R := PowerSeriesRing(m le 2 select RationalField() else CyclotomicField(m));
383
q := R.1;
384
k := Weight(f);
385
if L eq 1 then
386
c_0 := -GeneralizedBernoulli(k,psi)/(2*k);
387
else
388
c_0 := 0;
389
end if;
390
391
if k eq 2 and IsTrivial(chi) and IsTrivial(psi) then
392
assert t gt 1;
393
E2 := PrimitiveEisensteinSeries(2,prec);
394
q := Parent(E2).1;
395
qexp := E2 - t*Evaluate(E2,q^t);
396
else
397
qexp := c_0 + &+[
398
&+[Evaluate(psi,n)*n^(k-1)*Evaluate(chi,m div n) :
399
n in Divisors(m)]*q^(m*t) :
400
m in [1..mstop]];
401
end if;
402
403
/*
404
a := Coefficient(qexp,0);
405
if Type(Parent(a)) eq FldRat then
406
denom := Denominator(a);
407
else
408
denom := LCM([Denominator(b) : b in Eltseq(a)]);
409
end if;
410
*/
411
412
return qexp + O(q^prec);
413
end function;
414
415
function qExpansion_CreatedFrom(f,prec)
416
assert Type(f) eq ModFrmElt;
417
assert Type(prec) eq RngIntElt;
418
assert assigned f`created_from;
419
420
op, g, h := Explode(f`created_from);
421
case op:
422
when "*":
423
return PowerSeries(g,prec)*PowerSeries(h,prec);
424
when "+":
425
return PowerSeries(g,prec)+PowerSeries(h,prec);
426
when "-":
427
return PowerSeries(g,prec)-PowerSeries(h,prec);
428
when "scalar":
429
return g*PowerSeries(h,prec);
430
else:
431
error "Invalid created_from attribute.";
432
end case;
433
434
end function;
435
436
function qExpansion_Theta(f,prec)
437
assert Type(f) eq ModFrmElt;
438
assert Type(prec) eq RngIntElt;
439
assert assigned f`theta;
440
441
error "qExpansion_Theta -- not programmed";
442
443
end function;
444
445
function qExpansion_Gadget(f,prec)
446
assert Type(f) eq ModFrmElt;
447
assert Type(prec) eq RngIntElt;
448
assert assigned f`gadget;
449
450
return f`gadget(prec);
451
end function;
452
453
function qExpansion_EllipticCurve(f,prec)
454
assert Type(f) eq ModFrmElt;
455
assert Type(prec) eq RngIntElt;
456
assert assigned f`elliptic_curve;
457
458
return qEigenform(f`elliptic_curve, prec);
459
end function;
460
461
462
function Compute_ith_Conjugate(F, g, i)
463
assert Type(F) in {FldPad, FldRat, FldFin};
464
assert Type(g) eq RngSerPowElt;
465
assert Type(i) in RngIntElt;
466
assert i ge 1;
467
468
error "Compute_ith_Conjugate -- not yet written.";
469
end function;
470
471
function CreateNumberFieldFromCyclotomicField(K)
472
assert Type(K) eq FldCyc;
473
f := DefiningPolynomial(K);
474
F := NumberField(f);
475
phi := hom<K -> F | F.1>;
476
return F, phi;
477
end function;
478
479
function MoveIntoPowerSeriesRingOverANumberField(f, qexp)
480
assert Type(f) eq ModFrmElt;
481
assert Type(qexp) eq RngSerPowElt;
482
R := BaseRing(Parent(qexp));
483
if Type(R) eq FldRat then // it already is where we want it
484
if not assigned f`number_field_coercion_map then
485
f`number_field_coercion_map := hom<RationalField() -> RationalField() | x :-> x>;
486
f`cyclotomic_embedding_map := f`number_field_coercion_map;
487
end if;
488
return qexp;
489
end if;
490
491
if not assigned f`number_field_coercion_map then
492
if Type(R) eq RngUPolRes then
493
h := Modulus(R);
494
K := NumberField(h);
495
L := AbsoluteField(K);
496
poly_ring := Parent(h);
497
f`number_field_coercion_map := hom<poly_ring -> L | L!K.1>;
498
f`cyclotomic_embedding_map := hom<BaseRing(h) -> L | x :-> L!(K!x)>;
499
elif Type(R) eq FldCyc then
500
_,f`number_field_coercion_map := CreateNumberFieldFromCyclotomicField(R);
501
f`cyclotomic_embedding_map := f`number_field_coercion_map;
502
else
503
error "Bug in q-expansions.m";
504
end if;
505
end if;
506
prec := AbsolutePrecision(qexp);
507
S := PowerSeriesRing(Codomain(f`number_field_coercion_map));
508
phi := f`number_field_coercion_map;
509
return &+[phi(Coefficient(qexp,n))*S.1^n : n in [0..prec-1]] + O(S.1^prec);
510
end function;
511
512
intrinsic CyclotomicEmbedding(f::ModFrmElt) -> Map
513
{The canonical map from the field Q(eps) generated by the
514
values of eps into the field K_f generated by the Fourier
515
coefficients of f. We assume that f is a newform
516
with Dirichlet character eps.}
517
if not assigned f`cyclotomic_embedding_map then
518
dummy := PowerSeries(f,2);
519
end if;
520
return f`cyclotomic_embedding_map;
521
end intrinsic;
522
523
function qExpansion_ModularSymbols(f,prec)
524
assert Type(f) eq ModFrmElt;
525
assert Type(prec) eq RngIntElt;
526
assert assigned f`mf_modular_symbols;
527
528
vprintf ModularForms, 2:
529
"Computing q-expansion using %o\n", f`mf_modular_symbols;
530
eig := qEigenform(f`mf_modular_symbols,prec);
531
g := MoveIntoPowerSeriesRingOverANumberField(f, eig);
532
533
R := BaseRing(Parent(g));
534
if assigned f`which_conjugate and Type(R) ne FldRat then
535
AssignNames(~R,[ToLowerCaseLetter(f`which_conjugate)]);
536
end if;
537
538
return g + O(Parent(g).1^prec);
539
end function;
540
541
542
function qExpansion_Element(f, prec)
543
assert Type(f) eq ModFrmElt;
544
assert assigned f`element;
545
assert Type(prec) eq RngIntElt;
546
assert assigned f`element;
547
548
e := Eltseq(f`element);
549
M := Parent(f);
550
551
B := qExpansionOfModularFormsBasis(M,prec);
552
v := PowerSeriesRing(BaseRing(M))!0;
553
for i in [j : j in [1..#e] | e[j] ne 0] do
554
v +:= e[i]*B[i];
555
end for;
556
return v + O(Parent(v).1^prec);
557
end function;
558
559
560
function ApplyMapTo_qExpansion(f, psi)
561
assert Type(f) eq RngSerPowElt;
562
assert Type(psi) eq Map;
563
R := Parent(f);
564
S<q> := PowerSeriesRing(Codomain(psi));
565
prec := AbsolutePrecision(f);
566
K := Parent(Coefficient(f,0));
567
R := Domain(psi);
568
assert R eq K;
569
return &+[psi(Coefficient(f,n))*S.1^n : n in [0..prec-1]] + O(S.1^prec);
570
end function;
571
572
function ApplyMapsTo_qExpansion(f, phi)
573
assert Type(f) eq RngSerPowElt;
574
assert Type(phi) eq List;
575
assert #phi gt 0;
576
ans := [* *];
577
for i in [1..#phi] do
578
orbit_of_maps := phi[i];
579
orbit := [* *];
580
for psi in orbit_of_maps do
581
Append(~orbit, ApplyMapTo_qExpansion(f,psi));
582
end for;
583
Append(~ans, orbit);
584
end for;
585
return ans;
586
end function;
587
588
589
// The q-expansion of the modular form f to absolute precision prec.
590
function Compute_qExpansionsOfForm(f, type, data, prec)
591
assert Type(f) eq ModFrmElt;
592
assert Type(prec) eq RngIntElt;
593
assert Type(data) eq Map or Type(data) eq RngIntElt;
594
vprintf ModularForms, 2 : "Computing q-expansion to precision %o.\n", prec;
595
596
case type:
597
when "normal":
598
if assigned f`created_from then
599
vprint ModularForms, 2: "created from";
600
g := qExpansion_CreatedFrom(f,prec);
601
elif assigned f`eisenstein then
602
vprint ModularForms, 2: "eisenstein";
603
g := qExpansion_EisensteinSeries(f,prec);
604
elif assigned f`theta then
605
vprint ModularForms, 2: "theta";
606
g := qExpansion_Theta(f,prec);
607
elif assigned f`q_expansion_gadget then
608
vprint ModularForms, 2: "gadget";
609
g := qExpansion_Gadget(f,prec);
610
elif assigned f`elliptic_curve then
611
vprint ModularForms, 2: "elliptic curve";
612
g := qExpansion_EllipticCurve(f,prec);
613
elif assigned f`mf_modular_symbols then
614
vprint ModularForms, 2: "modular symbols";
615
g := qExpansion_ModularSymbols(f,prec);
616
elif assigned f`element then
617
vprint ModularForms, 2: "modular element";
618
g := qExpansion_Element(f, prec);
619
else
620
error "Could not figure out how to compute q-expansion of ", f;
621
end if;
622
R := Parent(g);
623
return [* [g] *];
624
when "modp":
625
phi := ModpReductionMaps(f, data);
626
when "padic":
627
phi := pAdicEmbeddingMaps(f, data);
628
when "complex":
629
phi := ComplexEmbeddingMaps(f);
630
when "map":
631
phi := data;
632
else
633
assert false;
634
end case;
635
return ApplyMapsTo_qExpansion(PowerSeries(f,prec), phi);
636
end function;
637
638
639
640
function BasisOfWeightOneCuspForms(M,prec)
641
assert Type(M) eq ModFrm;
642
assert Weight(M) eq 1;
643
assert Type(prec) eq RngIntElt and prec ge 0;
644
assert IsCuspidal(M);
645
646
error "BasisOfWeightOneCuspForms -- not programmed.";
647
end function;
648
649
650
function BasisOfWeightOneForms(M,prec)
651
assert Type(M) eq ModFrm;
652
assert Weight(M) eq 1;
653
assert Type(prec) eq RngIntElt and prec ge 0;
654
655
C := CuspidalSubspace(M);
656
C_basis := BasisOfWeightOneCuspForms(C,prec);
657
658
E := EisensteinSubspace(M);
659
E_basis := qExpansionOfModularFormsBasis(E,prec);
660
661
return EchelonPowerSeriesSequence(C_basis cat E_basis);
662
end function;
663
664
665
function CuspformBasisUsingModularSymbols(M,prec)
666
assert Type(M) eq ModFrm;
667
assert Weight(M) ge 2;
668
assert Type(prec) eq RngIntElt and prec ge 0;
669
assert IsCuspidal(M);
670
assert Type(BaseRing(M)) in {FldRat, RngInt};
671
672
modsym := MF_ModularSymbols(M,+1);
673
674
if Type(modsym) eq SeqEnum then
675
Q := &cat [qExpansionBasis(m,prec) : m in modsym];
676
else
677
Q := qExpansionBasis(modsym,prec);
678
end if;
679
if #Q eq 0 then
680
return Q;
681
end if;
682
F := BaseRing(Parent(Q[1]));
683
if Type(F) eq FldCyc then
684
Q := EchelonPowerSeriesSequence(&cat[
685
RestrictionOfScalarsToQ(f) : f in Q]);
686
end if;
687
return Q;
688
end function;
689
690
691
function BasisUsingBrandtModule(M,prec)
692
assert Type(M) eq ModFrm;
693
assert Weight(M) ge 2;
694
assert Type(prec) eq RngIntElt and prec ge 0;
695
696
error "BasisUsingBrandtModule -- Not programmed.";
697
end function;
698
699
700
function BasisGotByMultiplyingFormsOfLowerWeight(M,prec)
701
assert Type(M) eq ModFrm;
702
assert Weight(M) ge 2;
703
assert Type(prec) eq RngIntElt and prec ge 0;
704
705
error "BasisGotByMultiplyingFormsOfLowerWeight -- Not programmed.";
706
end function;
707
708
709
function BasisOfIntegralWeightAtLeast2Forms(M, prec)
710
assert Type(M) eq ModFrm;
711
assert Weight(M) ge 2;
712
assert Type(prec) eq RngIntElt and prec ge 0;
713
assert not IsEisenstein(M); // or there might be an infinite recursion.
714
715
C := CuspidalSubspace(M);
716
C_basis := CuspformBasisUsingModularSymbols(C,prec);
717
718
E := EisensteinSubspace(M);
719
E_basis := qExpansionOfModularFormsBasis(E,prec);
720
return EchelonPowerSeriesSequence(C_basis cat E_basis);
721
end function;
722
723
724
function MakeRestrictionOfScalars(E)
725
assert Type(E) eq SeqEnum;
726
assert #E ne 0;
727
prec := #E;
728
q := PowerSeriesRing(Parent(E[1][1])).1;
729
return [&+[E[n+1][i]*q^n : n in [0..prec-1]] + O(q^prec) : i in [1..#E[1]]];
730
end function;
731
732
733
function RestrictionOfScalarsFromCycloToQ(f)
734
assert Type(f) eq RngSerPowElt;
735
736
R := BaseRing(Parent(f));
737
assert Type(R) in {FldCyc, FldRat, RngInt};
738
if Type(R) in {FldRat, RngInt} then
739
return [f];
740
end if;
741
742
/* f is a q-expansion over a cyclotomic field.
743
Compute the sequence of restrictions to Q. */
744
prec := AbsolutePrecision(f);
745
R := PowerSeriesRing(Rationals());
746
q := R.1;
747
if prec eq 0 then
748
return [O(q)];
749
end if;
750
E := [Eltseq(Coefficient(f,n)) : n in [0..prec-1]];
751
return MakeRestrictionOfScalars(E);
752
end function;
753
754
function FldEltseq(a, d)
755
e := Eltseq(a);
756
return e cat [0 : i in [#e+1..d]];
757
end function;
758
759
function RestrictionOfScalarsFromPolResToBase(f)
760
assert Type(f) eq RngSerPowElt;
761
d := Degree(Modulus(BaseRing(Parent(f))));
762
prec := AbsolutePrecision(f);
763
E := [FldEltseq(Coefficient(f,n),d) : n in [0..prec-1]];
764
return MakeRestrictionOfScalars(E);
765
/* q := PowerSeriesRing(BaseRing(BaseRing(Parent(f)))).1;
766
return [&+[E[n+1][i]*q^n : n in [0..prec-1]] + O(q^prec) : i in [1..#E[1]]];
767
*/
768
end function;
769
770
function RestrictionOfScalarsFromFldNumToBase(f)
771
assert Type(f) eq RngSerPowElt;
772
prec := AbsolutePrecision(f);
773
E := [Eltseq(Coefficient(f,n)) : n in [0..prec-1]];
774
return MakeRestrictionOfScalars(E);
775
end function;
776
777
function RestrictionOfScalarsToQ(f)
778
assert Type(f) eq RngSerPowElt;
779
780
if Type(BaseRing(Parent(f))) eq RngUPolRes then
781
F := RestrictionOfScalarsFromPolResToBase(f);
782
elif Type(BaseRing(Parent(f))) eq FldNum then
783
F := RestrictionOfScalarsFromFldNumToBase(f);
784
else
785
F := [f];
786
end if;
787
788
return &cat[RestrictionOfScalarsFromCycloToQ(g) : g in F];
789
790
end function;
791
792
793
function BasisOfEisensteinSpace(M, prec)
794
assert Type(M) eq ModFrm;
795
assert Type(prec) eq RngIntElt;
796
assert SpaceType(M) in { "eis", "eis_new" };
797
if SpaceType(M) eq "eis_new" then
798
E := [* *];
799
for f in ComputeEisensteinNewforms(M) do
800
for g in f do
801
Append(~E, g);
802
end for;
803
end for;
804
else
805
E := EisensteinSeries(M);
806
end if;
807
basis := &cat [RestrictionOfScalarsToQ(PowerSeries(f,prec)) : f in E];
808
basis := EchelonPowerSeriesSequence(basis);
809
return basis;
810
end function;
811
812
813
function CoercePowerSeriesElement(R, f)
814
assert Type(R) eq RngSerPow;
815
assert Type(f) eq RngSerPowElt;
816
prec := AbsolutePrecision(f);
817
return &+[(BaseRing(R)!Coefficient(f,n))*R.1^n : n in [0..prec-1]] + O(R.1^prec);
818
end function;
819
820
821
function CoerceAndEchelonBasis(basis, F)
822
assert Type(basis) eq SeqEnum;
823
R := PowerSeriesRing(F);
824
B := [R|CoercePowerSeriesElement(R,f) : f in basis];
825
return EchelonPowerSeriesSequence(B);
826
end function;
827
828
829
function qExpansionOfModularFormsBasis(M, prec)
830
assert Type(M) eq ModFrm;
831
assert Type(prec) eq RngIntElt;
832
prec := Max(prec, ApproximatePrecisionBound(M));
833
834
R := PowerSeriesRing(BaseRing(M));
835
q := R.1;
836
if Dimension(M) eq 0 then
837
return [R|];
838
end if;
839
840
if not assigned M`q_expansion_basis or M`q_expansion_basis[1] lt prec then
841
if assigned M`made_from_newform then
842
f := PowerSeries(M`made_from_newform,prec);
843
basis_Z := ClearDenominatorsAndSaturate(
844
EchelonPowerSeriesSequence(
845
RestrictionOfScalarsToQ(f)));
846
basis := [R!f : f in basis_Z];
847
elif Level(M) eq 1 and not IsEisenstein(M) then
848
basis := Level1Basis(Weight(M), prec);
849
if IsCuspidal(M) then
850
Remove(~basis,1);
851
end if;
852
basis := [R!f : f in basis];
853
elif Type(BaseRing(M)) ne RngInt then
854
assert Dimension(M) eq Dimension(AssociatedSpaceOverZ(M));
855
basis_Z := qExpansionOfModularFormsBasis(
856
AssociatedSpaceOverZ(M),prec); // recursive
857
basis := [R!f : f in basis_Z];
858
else // over Z
859
basis := [R|];
860
if Weight(M) le 0 then
861
// nothing
862
elif IsEisenstein(M) then
863
basis := BasisOfEisensteinSpace(M,prec);
864
elif Weight(M) eq 1 then
865
if IsEven(DirichletCharacters(M)) then
866
// nothing
867
else
868
basis := BasisOfWeightOneForms(M,prec);
869
end if;
870
elif not (Weight(M) in Integers()) and (2*Weight(M) in Integers()) then
871
basis := BasisOfHalfIntegralWeightForms(M,prec);
872
else
873
basis := BasisOfIntegralWeightAtLeast2Forms(M,prec);
874
end if;
875
basis := ClearDenominatorsAndSaturate(basis);
876
end if;
877
M`q_expansion_basis := <prec, basis>;
878
end if;
879
basis := [R|f + O(q^prec) : f in M`q_expansion_basis[2]];
880
basis := basis cat [O(q^prec) : i in [#basis+1..Dimension(M)]];
881
return basis;
882
end function;
883
884
function ClearDenominators(f)
885
assert Type(f) eq RngSerPowElt;
886
if Type(BaseRing(Parent(f))) eq RngInt then
887
return f;
888
end if;
889
assert Type(BaseRing(Parent(f))) eq FldRat;
890
denom := LCM([Denominator(Coefficient(f,n)) : n in [0..AbsolutePrecision(f)-1]]);
891
return denom*f;
892
end function;
893
894
function ClearDenominatorsAndSaturate(rational_basis)
895
assert Type(rational_basis) eq SeqEnum;
896
if #rational_basis eq 0 then
897
return rational_basis;
898
end if;
899
assert Type(BaseRing(Parent(rational_basis[1]))) in {RngInt, FldRat};
900
no_denominators := [ClearDenominators(f) : f in rational_basis];
901
basis := SaturatePowerSeriesSequence(no_denominators);
902
return basis;
903
end function;
904