CoCalc Public Fileswww / tables / magma_src / ModFrm / newforms.mOpen with one click!
Author: William A. Stein
1
freeze;
2
3
/****-*-magma-* EXPORT DATE: 2004-03-08 ************************************
4
5
MODFORM: Modular Forms in MAGMA
6
7
William A. Stein
8
9
FILE: newforms.m
10
11
$Header: /home/was/magma/packages/ModFrm/code/RCS/newforms.m,v 1.12 2002/05/30 10:03:43 was Exp was $
12
13
$Log: newforms.m,v $
14
Revision 1.12 2002/05/30 10:03:43 was
15
..
16
17
Revision 1.11 2002/05/30 09:52:23 was
18
but characteristic p^2 is not so easy...
19
20
Revision 1.10 2002/05/30 09:50:49 was
21
Extended "Newforms" so that it works with spaces in characteristic p. This was dead easy!
22
23
Revision 1.9 2002/05/30 09:36:02 was
24
Newforms can only use elliptic curve database shortcut when N > 450, because
25
Cremona's ordering is not the same as mine! (And I haven't typed in a conversion
26
table between the two orderings.) -- William
27
28
Revision 1.8 2002/05/21 18:30:19 was
29
nothing. (debuging "breakpoints")
30
31
Revision 1.7 2002/05/04 18:33:43 was
32
*** empty log message ***
33
34
Revision 1.6 2002/05/04 17:37:15 was
35
I removed the "bug" from GivenNewformItsParent (which makes things
36
more efficient), because (1) somebody complained, and (2) setting
37
the field correctly should *not* be so inefficient! I think the reason
38
it is must involve IsIrreducible being absurdly slow, which has presumbly
39
been fixed.
40
41
Revision 1.5 2002/03/11 23:19:10 was
42
Working on "Eigenforms" command.
43
44
Revision 1.4 2001/07/26 19:26:58 was
45
Changed "GiveNewformItsParent" so the parent has the "wrong" base field.
46
It's EXTREMELY time consuming, in some cases, to compute the right parent,
47
and their is no benefit at all to having the right parent.
48
49
Revision 1.3 2001/06/30 03:12:13 was
50
Fixed a small bug in GiveNewformItsParent.
51
52
Revision 1.2 2001/05/30 18:56:09 was
53
Created.
54
55
Revision 1.1 2001/05/16 03:52:02 was
56
Initial revision
57
58
59
***************************************************************************/
60
61
62
// The following group of functions are all for modular forms spaces over Q.
63
64
forward CreateNewformsFromEisensteinSeries,
65
CreateNewformsFromModularSymbolsNewform,
66
CreateNewformsFrom_qExpansion;
67
68
import "misc.m" : IsogenyCodeToInteger;
69
import "creation.m" : CopyOfDefiningModularFormsObject;
70
import "modular_symbols.m" : MF_ModularSymbols;
71
import "predicates.m": SpaceType, AssociatedSpaceOverZ;
72
73
procedure GiveNewformItsParent(f, which_newform)
74
assert Type(f) eq ModFrmElt;
75
76
M := CopyOfDefiningModularFormsObject(Parent(f));
77
M`dimension := Degree(f);
78
if assigned f`mf_modular_symbols then
79
M`mf_modular_symbols := [* false, false, f`mf_modular_symbols *];
80
end if;
81
if IsCuspidalNewform(f) then
82
M`type := "cusp_newform";
83
else
84
M`type := "eis_newform";
85
end if;
86
87
R := BaseRing(Parent(PowerSeries(f,1)));
88
89
MR := BaseExtend(M,R);
90
91
MR`made_from_newform := f;
92
93
MR`ambient_space := BaseExtend(AmbientSpace(Parent(f)), R);
94
// MR`ambient_space := AmbientSpace(Parent(f));
95
96
MR`which_newform := which_newform;
97
f`parent := MR;
98
delete f`element;
99
end procedure;
100
101
procedure GiveAllNewformsTheirParents(new_forms, first)
102
103
which_newform := first;
104
for orb in new_forms do
105
for f in orb do
106
GiveNewformItsParent(f,which_newform);
107
which_newform +:= 1;
108
end for;
109
end for;
110
end procedure;
111
112
function NumberOfGalQbarOverQConjugateNewforms(A)
113
assert Type(A) eq ModSym;
114
assert Type(BaseField(A)) in {FldRat, FldCyc};
115
116
// The formula is simple because the ModularSymbols(ModFrm)
117
// intrinsic is supposed to return a character defined over
118
// a field of minimal degree.
119
assert EulerPhi(Order(DirichletCharacter(A))) eq Degree(BaseField(A));
120
121
return Dimension(A) * Degree(BaseField(A));
122
123
end function;
124
125
126
function NumberOfGalQbarOverQConjugateEisensteinSeries(f)
127
assert Type(f) eq ModFrmElt;
128
assert IsEisensteinSeries(f);
129
130
chi, psi := Explode(EisensteinData(f));
131
m := LCM(CyclotomicOrder(BaseRing(chi)), CyclotomicOrder(BaseRing(psi)));
132
return EulerPhi(m);
133
134
end function;
135
136
137
function CreateNewformsFromModularSymbolsNewform(M, A)
138
assert Type(M) eq ModFrm;
139
assert Type(A) eq ModSym;
140
assert Type(BaseField(A)) in {FldRat, FldCyc};
141
142
ans := [* *];
143
for i in [1..NumberOfGalQbarOverQConjugateNewforms(A)] do
144
f := HackobjCreateRaw(ModFrmElt);
145
f`mf_modular_symbols := A;
146
f`parent := M;
147
f`is_newform := true;
148
f`which_conjugate := i;
149
Append(~ans, f);
150
end for;
151
return ans;
152
153
end function;
154
155
156
function CreateNewformsFrom_qExpansion()
157
// coefficients of the q-exp, got using hecke operators, say; e.g., weight 1.)
158
error "CreateNewformsFrom_qExpansion -- Not programmed.";
159
end function;
160
161
function CreateNewformsFromBrandtModuleData()
162
error "CreateNewformsFromBrandtModuleData -- Not programmed.";
163
end function;
164
165
166
function ComputeCuspidalNewformsUsingModuleOfSupersingularPoints(M)
167
assert Type(M) eq ModFrm;
168
169
error "ComputeCuspidalNewformsUsingModuleOfSupersingularPoints -- Not programmed.";
170
end function;
171
172
function ComputeCuspidalNewformsUsingBrandtModule(M)
173
assert Type(M) eq ModFrm;
174
175
error "ComputeCuspidalNewformsUsingBrandtModule -- Not programmed.";
176
177
end function;
178
179
180
181
182
function ComputeCuspidalNewformsUsingModularSymbols(M, Proof)
183
assert Type(M) eq ModFrm;
184
assert IsCuspidal(M);
185
186
modsym := [NewSubspace(m) : m in MF_ModularSymbols(M,+1)];
187
188
D := &cat [SortDecomposition(NewformDecomposition(m : Proof := Proof)) : m in modsym];
189
ans := [* *];
190
for A in D do
191
Append(~ans, CreateNewformsFromModularSymbolsNewform(M, A));
192
end for;
193
return ans;
194
end function;
195
196
197
198
199
function DivideNewEisensteinSeriesIntoOrbits(E)
200
assert Type(E) eq List;
201
if #E eq 0 then
202
return [* *];
203
end if;
204
assert Type(E[1]) eq ModFrmElt;
205
assert IsEisensteinSeries(E[1]);
206
207
ans := [* *];
208
while #E gt 0 do
209
f := E[1];
210
Remove(~E,1);
211
orbit := [* f *];
212
orbit[1]`which_conjugate := 1;
213
if #E gt 0 then
214
chi, psi, t, chi_big, psi_big := Explode(EisensteinData(f));
215
m := LCM(Order(chi),Order(psi));
216
which_conjugate := 2;
217
for i in [j : j in [2..m-1] | GCD(j,m) eq 1] do
218
chi_i := chi_big^i;
219
psi_i := psi_big^i;
220
pos := 0;
221
for k in [1..#E] do
222
_, _, _, chi_k, psi_k := Explode(EisensteinData(E[k]));
223
if chi_i eq chi_k and psi_i eq psi_k then
224
pos := k;
225
break;
226
end if;
227
end for;
228
assert pos ne 0;
229
Append(~orbit, E[pos]);
230
orbit[#orbit]`which_conjugate := which_conjugate;
231
orbit[#orbit]`first_conjugate := orbit[1];
232
which_conjugate +:= 1;
233
Remove(~E,pos);
234
end for;
235
end if;
236
assert #orbit eq Degree(orbit[1]);
237
Append(~ans, orbit);
238
end while;
239
return ans;
240
end function;
241
242
function ComputeEisensteinNewforms(M)
243
assert Type(M) eq ModFrm;
244
245
// Let E be the collection of new Eisenstein series.
246
E := [* *];
247
for f in EisensteinSeries(AmbientSpace(M)) do
248
chi, psi, t := Explode(EisensteinData(f));
249
if t eq 1 or (Weight(M) eq 2 and IsPrime(t) and t eq Level(M)) then
250
LR := Conductor(chi)*Conductor(psi);
251
if LR eq Level(M) or (Weight(M) eq 2 and LR eq 1) then
252
Append(~E,[* f *]);
253
E[#E][1]`is_newform := true;
254
end if;
255
end if;
256
end for;
257
258
return E;
259
// return DivideNewEisensteinSeriesIntoOrbits(E);
260
end function;
261
262
function ComputeCuspidalNewformsUsingHeckeOperators(M)
263
assert Type(M) eq ModFrm;
264
end function;
265
266
intrinsic NumberOfNewformClasses(M::ModFrm : Proof := true) -> RngIntElt
267
{The number of Galois conjugacy-classes of newforms associated to M.}
268
require Characteristic(BaseRing(M)) eq 0 :
269
"Argument 1 must have characteristic 0.";
270
271
return #Newforms(M : Proof := Proof);
272
end intrinsic;
273
274
intrinsic Newform(M::ModFrm, i::RngIntElt,
275
j::RngIntElt : Proof := true) -> ModFrmElt
276
{The jth Galois-conjugate newform in the ith orbit.}
277
require Characteristic(BaseRing(M)) eq 0 :
278
"Argument 1 must have characteristic 0.";
279
requirege i, 1;
280
requirege j, 1;
281
N := Newforms(M : Proof := Proof);
282
require i le #N : "Argument 2 must be at most", #N;
283
orbit := N[i];
284
require j le #orbit : "Argument 3 must be at most", #orbit;
285
return orbit[j];
286
end intrinsic;
287
288
intrinsic Newform(M::ModFrm, i::RngIntElt : Proof := true) -> ModFrmElt
289
{The first Galois-conjugate newform in the ith orbit.}
290
require Characteristic(BaseRing(M)) eq 0 :
291
"Argument 1 must have characteristic 0.";
292
293
requirege i, 1;
294
N := Newforms(M : Proof := Proof);
295
require i le #N : "Argument 2 must be at most", #N;
296
return N[i][1];
297
end intrinsic;
298
299
intrinsic Newform(E::CrvEll) -> ModFrmElt
300
{}
301
return ModularForm(E);
302
end intrinsic;
303
304
intrinsic Newforms(M::ModFrm : Proof := true) -> List
305
{List of the newforms associated to M, divided up into Galois orbits.}
306
307
/* require Characteristic(BaseRing(M)) eq 0 :
308
"Argument 1 must have characteristic 0.";
309
*/
310
if SpaceType(M) in {"cusp_newform", "eis_newform"} then
311
return M`made_from_newform;
312
end if;
313
314
if not assigned M`newforms then
315
if Characteristic(BaseRing(M)) ne 0 then
316
if not IsPrime(Characteristic(BaseRing(M))) then
317
require false : "The characteristic of the base ring of argument 1 must be 0 or prime.";
318
end if;
319
M0 := AssociatedSpaceOverZ(M);
320
ans := [* *];
321
for i in [1..NumberOfNewformClasses(M0)] do
322
f := Newform(M0,i);
323
fmod := Reductions(f,Characteristic(BaseRing(M)));
324
for g in fmod do
325
Append(~ans,g);
326
end for;
327
end for;
328
M`newforms := ans;
329
return M`newforms;
330
end if;
331
332
if assigned M`dimension and M`dimension eq 0 then
333
M`newforms := [* *];
334
return M`newforms;
335
end if;
336
if not Weight(M) in Integers() or Weight(M) lt 2 then
337
require false : "Newforms does not support weight 1 and half integral weight spaces yet.";
338
end if;
339
if IsCuspidal(M) then
340
new_forms := ComputeCuspidalNewformsUsingModularSymbols(M, Proof);
341
GiveAllNewformsTheirParents(new_forms,1);
342
elif IsEisenstein(M) then
343
new_forms := ComputeEisensteinNewforms(M);
344
first := Dimension(NewSubspace(CuspidalSubspace(AmbientSpace(M)))) + 1;
345
GiveAllNewformsTheirParents(new_forms, first);
346
else
347
new_forms := Newforms(CuspidalSubspace(M) : Proof := Proof)
348
cat
349
Newforms(EisensteinSubspace(M) : Proof := Proof);
350
end if;
351
M`newforms := new_forms;
352
end if;
353
return M`newforms;
354
end intrinsic;
355
356
357
intrinsic Newforms(I::[Tup], M::ModFrm : Proof := true) -> SeqEnum
358
{
359
The newforms associated to M with prespecified eigenvalues.
360
Here I is a sequence
361
[< p_1, f_1(x)>,...,< p_n,f_n(x)>]
362
of pairs. Each pair consists
363
of a prime number that does not divide
364
the level of M and a polynomial.
365
This intrinsic returns the set of
366
newforms sum a_n q^n in M
367
such that f_n(a_\{p_n\})=0.
368
}
369
require Type(BaseRing(M)) in {FldRat, RngInt} :
370
"Argument 1 must be defined over the integer ring or rational field.";
371
require IsCuspidal(M) : "Argument 1 must be cuspidal.";
372
373
ans := [* *];
374
// First find the cuspidal newforms.
375
if Dimension(CuspidalSubspace(M)) gt 0 then
376
S := MF_ModularSymbols(CuspidalSubspace(M),+1);
377
A := [Kernel(I, s) : s in S];
378
D := &cat [SortDecomposition(NewformDecomposition(m :
379
Proof := Proof)) : m in A];
380
for nf in D do
381
Append(~ans, CreateNewformsFromModularSymbolsNewform(M, nf));
382
end for;
383
end if;
384
385
// Second, the Eisenstein newforms.
386
E := EisensteinSubspace(M);
387
if Dimension(E) gt 0 then
388
error "Cutting out eisenstein newforms not yet programmed.";
389
end if;
390
391
return ans;
392
end intrinsic;
393
394
395
function IsNumeric(s)
396
assert Type(s) eq MonStgElt;
397
if #s eq 0 then
398
return false;
399
end if;
400
for i in [1..#s] do
401
if not ( (s[i] ge "0") and (s[i] le "9") ) then
402
return false;
403
end if;
404
end for;
405
return true;
406
end function;
407
408
intrinsic Newform(label::MonStgElt : Proof := true) -> ModFrmElt
409
{}
410
return Newforms(label : Proof := Proof)[1];
411
end intrinsic;
412
413
intrinsic Newforms(label::MonStgElt : Proof := true) -> ModFrmElt
414
{The Galois-conjugacy class(es) of newforms described
415
by the label. See the handbook for a description of the
416
notation used for the label.}
417
require #label gt 0 : "Invalid label.";
418
// defaults
419
group := "G0";
420
k := 2;
421
N := 1;
422
iso := 1;
423
if label[1] eq "G" then
424
require #label ge 2 : "Invalid label.";
425
if label[2] eq "0" then
426
group := "G0";
427
elif label[2] eq "1" then
428
group := "G1";
429
else
430
require false : "Invalid label.";
431
end if;
432
require #label ge 3 and label[3] eq "N" : "Invalid label.";
433
s := &cat[label[i] : i in [4..#label]];
434
else
435
s := label;
436
end if;
437
438
439
sN := "";
440
i := 1;
441
while i le #s and s[i] ge "0" and s[i] le "9" do
442
sN := sN cat s[i];
443
i +:= 1;
444
end while;
445
require IsNumeric(sN) : "The format of argument 1 is invalid.";
446
N := StringToInteger(sN);
447
if i le #s and s[i] eq "k" then
448
i +:= 1;
449
sk := "";
450
while i le #s and s[i] ge "0" and s[i] le "9" do
451
sk := sk cat s[i];
452
i +:= 1;
453
end while;
454
require IsNumeric(sk) : "The format of argument 1 is invalid.";
455
k := StringToInteger(sk);
456
end if;
457
if i gt #s then
458
iso := 0;
459
else
460
sIso := &cat [s[j] : j in [i..#s]];
461
iso := IsogenyCodeToInteger(sIso);
462
require iso ge 1 : "The format of argument 1 is invalid.";
463
end if;
464
465
if k eq 2 and iso gt 0 and N gt 450 then // condition that N > 450 because Cremona's ordering is different.
466
// first check in database.
467
cremona := EllipticCurveDatabase();
468
if iso le LargestConductor(cremona) then
469
if iso le NumberOfIsogenyClasses(cremona,N) then
470
return [* ModularForm(EllipticCurve(cremona,N,iso,1)) *];
471
end if;
472
end if;
473
end if;
474
475
if group eq "G0" then
476
M := ModularForms(N,k);
477
else
478
M := ModularForms(Gamma1(N),k);
479
end if;
480
if iso eq 0 then
481
return Newforms(M);
482
end if;
483
N := Newforms(CuspidalSubspace(M));
484
485
if iso gt #N then
486
E := Newforms(EisensteinSubspace(M));
487
require iso le #E + #N : "The isogeny class is too large.";
488
return E[iso-#N];
489
end if;
490
return N[iso];
491
492
end intrinsic;
493
494
495
intrinsic DirichletCharacter(f::ModFrmElt) -> GrpDrchElt
496
{Suppose f is a newform, created using the Newform command.
497
The Nebentype is a Dirichlet character that is,
498
up to Galois conjugacy, the Nebentypus character
499
of f.}
500
if not assigned f`nebentype then
501
if IsGamma0(Parent(f)) then
502
f`nebentype := DirichletGroup(Level(Parent(f)))!1;
503
elif assigned f`mf_modular_symbols then
504
f`nebentype := DirichletCharacter(f`mf_modular_symbols);
505
elif assigned f`eisenstein then
506
f`nebentype := f`eisenstein[4]*f`eisenstein[5];
507
else
508
require false : "Unable to determine nebentype of f.";
509
end if;
510
end if;
511
return f`nebentype;
512
end intrinsic;
513
514
intrinsic LinearCombinationOfEigenformsOverC(f::ModFrmElt) -> SeqEnum
515
{Write f as a complex linear combination of eigenforms for the
516
anemic Hecke algebra.}
517
require Type(BaseRing(Parent(f))) in {FldRat, RngInt} :
518
"Argument 1 must be defined over the integers or rationals.";
519
520
521
end intrinsic;
522
523
524
/*
525
intrinsic Eigenforms(M::ModFrm : Proof := true) -> List
526
{}
527
require Characteristic(BaseRing(M)) eq 0 :
528
"Argument 1 must have characteristic 0.";
529
if SpaceType(M) in {"cusp_newform", "eis_newform"} then
530
return M`made_from_newform;
531
end if;
532
533
if not assigned M`eigenforms then
534
M`eigenforms := [* *];
535
if assigned M`dimension and M`dimension eq 0 then
536
return M`eigenforms;
537
end if;
538
if not Weight(M) in Integers() or Weight(M) lt 2 then
539
require false : "Eigenforms does not support weight 1 and half integral weight spaces yet.";
540
end if;
541
M`eigenforms := [* *];
542
if assigned M`dirichlet_characters then
543
levels := [Conductor(eps) : eps in M`dirichlet_characters];
544
else
545
levels := [1];
546
end if;
547
for d in [n : n in Divisors(Level(M)) | #[x : x in levels | n mod x eq 0] gt 0 ] do
548
Md := Newforms(M,d);
549
for N in Newforms(Md) do
550
for r in Divisors(Level(M) div d) do
551
FrobN :=
552
end for;
553
Append(M`eigenforms, FrobN);
554
end for;
555
end for;
556
end if;
557
return M`eigenforms;
558
end intrinsic;
559
*/
560
561
562
/*
563
intrinsic FlattenNewformList(L::List) -> List
564
{}
565
ans := [* *];
566
for a in L do
567
for b in a do
568
Append(~ans, b);
569
end for;
570
end for;
571
return ans;
572
end intrinsic;
573
*/
574