CoCalc Public Fileswww / tables / magma_src / ModFrm / predicates.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: creation.m
10
11
$Header: /home/was/magma/packages/ModFrm/code/RCS/predicates.m,v 1.7 2002/08/26 20:12:58 was Exp was $
12
13
$Log: predicates.m,v $
14
Revision 1.7 2002/08/26 20:12:58 was
15
Deleted a comment.
16
17
Revision 1.6 2002/04/13 07:25:51 was
18
Added stuff for p-new subspaces.
19
20
Revision 1.5 2001/05/30 19:52:22 was
21
Only allow degree for certain fields.
22
23
Revision 1.4 2001/05/30 18:56:33 was
24
Created.
25
26
Revision 1.3 2001/05/16 04:01:11 was
27
*** empty log message ***
28
29
Revision 1.2 2001/05/16 03:56:17 was
30
clearing it.
31
32
Revision 1.1 2001/05/16 03:56:03 was
33
Initial revision
34
35
Revision 1.1 2001/05/16 03:51:41 was
36
Initial revision
37
38
39
***************************************************************************/
40
41
42
import "eisenstein.m" : DimensionOfEisensteinSpace;
43
44
forward Element,
45
WhichNewform;
46
47
48
function SpaceType(M)
49
assert Type(M) eq ModFrm;
50
return M`type;
51
end function;
52
53
function SpaceTypeParam(M)
54
assert Type(M) eq ModFrm;
55
if not assigned M`type_param then
56
M`type_param := 0;
57
end if;
58
return M`type_param;
59
end function;
60
61
intrinsic BaseRing(M::ModFrm) -> Rng
62
{The field over which Basis(M) is defined. This is either the rational
63
numbers, a prime finite field, or a p-adic field Q_p.}
64
return M`base_ring;
65
end intrinsic;
66
67
68
function DimensionOfCuspidalSpace(M)
69
assert Type(M) eq ModFrm;
70
assert IsAmbientSpace(M);
71
72
k := Weight(M);
73
if k eq 1 then
74
error "Weight one cuspidal dimension not programmed.";
75
elif not (k in Integers()) then
76
error "Half integral cuspidal dimension not programmed.";
77
else
78
if IsGamma1(M) then
79
return DimensionCuspFormsGamma1(Level(M),k);
80
else
81
eps := DirichletCharacters(M);
82
return &+[EulerPhi(Order(e))*
83
DimensionCuspForms(e, k) : e in eps];
84
end if;
85
end if;
86
end function;
87
88
function DimensionOfNewCuspidalSpace(M, param)
89
assert Type(M) eq ModFrm;
90
assert IsAmbientSpace(M);
91
k := Weight(M);
92
if k eq 1 then
93
error "Weight one new cuspidal dimension not programmed.";
94
elif not (k in Integers()) then
95
error "Half integral new cuspidal dimension not programmed.";
96
else
97
if IsGamma1(M) then
98
return DimensionNewCuspFormsGamma1(Level(M),k,param);
99
elif #DirichletCharacters(M) eq 1 and IsTrivial(DirichletCharacters(M)[1]) then
100
return DimensionNewCuspFormsGamma0(Level(M),k,param);
101
else
102
return &+[EulerPhi(Order(eps))*DimensionNewCuspForms(eps,k,param) :
103
eps in DirichletCharacters(M)];
104
end if;
105
end if;
106
end function;
107
108
109
function DimensionOfNewEisensteinSpace(M, param)
110
assert Type(M) eq ModFrm;
111
assert IsAmbientSpace(M);
112
if param ne 0 then
113
error "DimensionOfNewEisensteinSpace -- nontrivial p-new subspace, not yet programmed.";
114
end if;
115
116
k := Weight(M);
117
if k eq 1 then
118
error "Weight one new eisenstein dimension not programmed.";
119
elif not (k in Integers()) then
120
error "Half integral new eisenstein dimension not programmed.";
121
else
122
E := EisensteinSubspace(M);
123
N := Newforms(E);
124
return &+[Integers()|#f : f in N];
125
end if;
126
end function;
127
128
129
function ObviouslyHasDimensionZero(M)
130
k := Weight(M);
131
if not IsGamma1(M) and k in Integers() then
132
t := true;
133
for eps in DirichletCharacters(M) do
134
if not ((IsEven(k) and IsOdd(eps)) or (IsOdd(k) and IsEven(eps))) then
135
t := false;
136
break;
137
end if;
138
end for;
139
if t then
140
return true;
141
end if;
142
end if;
143
if k le 0 then
144
return true;
145
end if;
146
return false;
147
end function;
148
149
intrinsic Dimension(M::ModFrm) -> RngIntElt
150
{The dimension of the space M of modular forms. (If M is defined
151
over a ring R, then M is free and this is the rank of M.)}
152
153
if assigned M`dimension and M`dimension eq -1 then
154
error "There is a bug in Dimension that will result in an "*
155
"infinite recursive call of Dimension by itself.";
156
end if;
157
158
if not assigned M`dimension then
159
vprint ModularForms : "ModularForms: Computing dimension.";
160
if ObviouslyHasDimensionZero(M) then
161
M`dimension := 0;
162
return M`dimension;
163
end if;
164
M`dimension := -1; // this means its being computed.
165
case SpaceType(M):
166
when "full":
167
E := EisensteinSubspace(M);
168
S := CuspidalSubspace(M);
169
M`dimension := Dimension(E) + Dimension(S);
170
when "cusp":
171
M`dimension := DimensionOfCuspidalSpace(AmbientSpace(M));
172
when "eis":
173
M`dimension := DimensionOfEisensteinSpace(AmbientSpace(M));
174
when "new":
175
M`dimension := Dimension(NewSubspace(EisensteinSubspace(M),SpaceTypeParam(M)))
176
+ Dimension(NewSubspace(CuspidalSubspace(M),SpaceTypeParam(M)));
177
when "cusp_new":
178
M`dimension := DimensionOfNewCuspidalSpace(AmbientSpace(M), SpaceTypeParam(M));
179
when "eis_new":
180
M`dimension := DimensionOfNewEisensteinSpace(AmbientSpace(M), SpaceTypeParam(M));
181
else:
182
error "M has an invalid type, where M = ", M;
183
end case;
184
185
end if;
186
187
if assigned M`dimension then
188
return M`dimension;
189
end if;
190
191
error "Dimension -- MAGMA is currently not clever enough to "*
192
"compute the dimension in this case.";
193
end intrinsic;
194
195
196
intrinsic Level(M::ModFrm) -> RngIntElt
197
{The level of M.}
198
if not assigned M`level then
199
if assigned M`dirichlet_character then
200
M`level := Modulus(M`dirichlet_character[1]);
201
end if;
202
require assigned M`level : "The level of argument 1 is not defined.";
203
end if;
204
return M`level;
205
end intrinsic;
206
207
intrinsic Level(f::ModFrmElt) -> RngIntElt
208
{The level of f.}
209
require not IsRingOfAllModularForms(Parent(f)) :
210
"The level of f is not known.";
211
return Level(Parent(f));
212
end intrinsic;
213
214
intrinsic IsRingOfAllModularForms(M::ModFrm) -> BoolElt
215
{True if and only if M is the ring of all modular forms over
216
a given ring.}
217
return not assigned M`weight;
218
end intrinsic;
219
220
intrinsic Weight(M::ModFrm) -> RngIntElt
221
{The weight of M.}
222
require not IsRingOfAllModularForms(M) :
223
"The weight of f is not known or not defined.";
224
return M`weight;
225
end intrinsic;
226
227
intrinsic Weight(f::ModFrmElt) -> RngIntElt
228
{The weight of f, if it is defined.}
229
if not assigned f`weight then
230
require not IsRingOfAllModularForms(Parent(f)) :
231
"The weight of f is not known or not defined.";
232
f`weight := Weight(Parent(f));
233
end if;
234
return f`weight;
235
end intrinsic;
236
237
intrinsic IsGamma1(M::ModFrm) -> BoolElt
238
{True if and only if M is a space of modular forms for Gamma_1(N).}
239
if IsRingOfAllModularForms(M) then
240
return false;
241
end if;
242
assert assigned M`is_gamma1;
243
return M`is_gamma1;
244
end intrinsic;
245
246
intrinsic IsGamma0(M::ModFrm) -> BoolElt
247
{True if and only if M is a space of modular forms for Gamma_0(N).}
248
if IsRingOfAllModularForms(M) then
249
return false;
250
end if;
251
if IsGamma1(M) then
252
return Level(M) le 2;
253
end if;
254
return #DirichletCharacters(M) eq 1 and IsTrivial(DirichletCharacters(M)[1]);
255
end intrinsic;
256
257
intrinsic IsAmbientSpace(M::ModFrm) -> BoolElt
258
{True if and only if M is an ambient space.}
259
return M`type eq "full";
260
end intrinsic;
261
262
intrinsic IsCuspidal(M::ModFrm) -> BoolElt
263
{True if M is contained in the cuspidal subspace of the ambient space of M.}
264
if not assigned M`is_cuspidal then
265
if assigned M`dimension and M`dimension eq 0 then
266
M`is_cuspidal := true;
267
return true;
268
end if;
269
case M`type:
270
when "cusp", "cusp_new", "cusp_newform":
271
M`is_cuspidal := true;
272
when "full":
273
M`is_cuspidal := false;
274
when "eis", "eis_new", "new", "eis_newform":
275
M`is_cuspidal := false;
276
else:
277
print M`type;
278
error "Bug in IsCuspidal";
279
end case;
280
end if;
281
282
return M`is_cuspidal;
283
end intrinsic;
284
285
intrinsic IsEisenstein(M::ModFrm) -> BoolElt
286
{True if M is contained in the Eisenstein subspace of the ambient space of M.}
287
288
if not assigned M`is_eisenstein then
289
if assigned M`dimension and M`dimension eq 0 then
290
M`is_eisenstein := true;
291
return true;
292
end if;
293
case M`type:
294
when "eis", "eis_new", "eis_newform":
295
M`is_eisenstein := true;
296
when "full":
297
M`is_eisenstein := false;
298
when "cusp", "cusp_new", "new", "cusp_newform":
299
M`is_eisenstein := false;
300
else:
301
error "Bug in IsEisenstein";
302
end case;
303
end if;
304
305
return M`is_eisenstein;
306
end intrinsic;
307
308
309
function AbsoluteDegreeOfRingGeneratedBy(gens)
310
assert Type(gens) eq SeqEnum;
311
if #gens eq 0 then
312
return 1;
313
end if;
314
case Type(Universe(gens)):
315
when RngInt, FldRat:
316
return 1;
317
when FldNum:
318
return Degree(sub< Universe(gens) | gens >);
319
when FldFin:
320
d := Max([Degree(sub< Universe(gens) | g >) : g in gens]);
321
return d;
322
when FldCyc:
323
k,phi := NumberField(Universe(gens));
324
return AbsoluteDegreeOfRingGeneratedBy([phi(g) : g in gens]);
325
else:
326
error "Invalid type.";
327
end case;
328
end function;
329
330
intrinsic Degree(f::ModFrmElt) -> RngIntElt
331
{The number of Galois conjugates of f over the
332
prime subfield.}
333
require Type(BaseRing(Parent(f))) in
334
{FldRat, FldNum, RngInt, FldFin, FldCyc, FldAlg, FldQuad} :
335
"Argument 1 must be defined over a number field or a finite field.";
336
if not assigned f`degree then
337
if assigned f`element then
338
f`degree := AbsoluteDegreeOfRingGeneratedBy(Eltseq(f`element));
339
elif assigned f`eisenstein then
340
f`degree := EulerPhi(LCM(Order(f`eisenstein[1]), Order(f`eisenstein[2])));
341
elif assigned f`mf_modular_symbols then
342
f`degree := Dimension(f`mf_modular_symbols)*
343
Degree(BaseField(f`mf_modular_symbols));
344
else
345
f`degree := AbsoluteDegreeOfRingGeneratedBy(Eltseq(Element(f)));
346
end if;
347
end if;
348
if f`degree eq 0 then
349
require false : "Unable to determine the degree of argument 1.";
350
end if;
351
return f`degree;
352
end intrinsic;
353
354
355
intrinsic DirichletCharacters(M::ModFrm) -> SeqEnum
356
{The sequence of Dirichlet characters associated with M.}
357
358
if not assigned M`dirichlet_character then
359
if IsGamma1(M) then
360
N := Level(M);
361
vprint ModularForms, 2 :
362
"Computing Galois-conjugacy classes of Dirichlet characters of level", N;
363
n := EulerPhi(N);
364
F := n le 2 select RationalField() else
365
CyclotomicField(n);
366
G := DirichletGroup(N,F);
367
M`dirichlet_character :=
368
GaloisConjugacyRepresentatives(G);
369
else
370
M`dirichlet_character :=
371
[DirichletGroup(Level(M))!1];
372
end if;
373
374
end if;
375
return M`dirichlet_character;
376
end intrinsic;
377
378
379
intrinsic HackobjParentModFrmElt(f::ModFrmElt) -> ModFrm
380
{}
381
return f`parent;
382
end intrinsic;
383
384
intrinsic 'ne' (M::ModFrm,N::ModFrm) -> BoolElt
385
{}
386
return not (M eq N);
387
end intrinsic;
388
389
intrinsic 'eq' (M::ModFrm,N::ModFrm) -> BoolElt
390
{}
391
if BaseRing(M) ne BaseRing(N) then
392
return false;
393
end if;
394
if IsRingOfAllModularForms(M) then
395
return IsRingOfAllModularForms(M);
396
end if;
397
if IsAmbientSpace(M) and IsAmbientSpace(N) then
398
if Weight(M) eq Weight(N) and Level(M) eq Level(N) then
399
charM := DirichletCharacters(M);
400
charN := DirichletCharacters(N);
401
if charM cmpeq charN then
402
return true;
403
else
404
return false;
405
end if;
406
else
407
return false;
408
end if;
409
elif AmbientSpace(M) eq AmbientSpace(N) then
410
if SpaceType(M) ne SpaceType(N) then
411
return false;
412
end if;
413
if SpaceType(M) in {"cusp_newform", "eis_newform"} then
414
f := M`made_from_newform;
415
g := N`made_from_newform;
416
if PowerSeries(f,5) cmpne PowerSeries(g,5) then
417
return false;
418
end if;
419
d := PrecisionBound(AmbientSpace(M) : Exact := false); // bad
420
return PowerSeries(f,d) eq PowerSeries(g,d);
421
else
422
return true;
423
end if;
424
425
else
426
return false;
427
end if;
428
end intrinsic;
429
430
intrinsic 'eq' (f::ModFrmElt,g::ModFrmElt) -> BoolElt
431
{}
432
return Parent(f) eq Parent(g) and Eltseq(f) eq Eltseq(g);
433
end intrinsic;
434
435
intrinsic 'subset'(M1::ModFrm, M2::ModFrm) -> BoolElt
436
{}
437
if AmbientSpace(M1) ne AmbientSpace(M2) then
438
return false;
439
end if;
440
if Dimension(M1) eq 0 then
441
return true;
442
end if;
443
if IsAmbientSpace(M2) then
444
return true;
445
end if;
446
case SpaceType(M1):
447
when "ambient":
448
return false;
449
when "cusp":
450
return SpaceType(M2) in {"cusp", "cusp_new", "cusp_newform"};
451
when "eis":
452
return SpaceType(M2) in {"eis", "eis_new", "eis_newform"};
453
when "new":
454
return SpaceType(M2) in {"new", "cusp_new", "eis_new", "eis_newform", "cusp_newform"}
455
and (SpaceTypeParam(M2) eq 0 or SpaceTypeParam(M1) mod SpaceTypeParam(M2) eq 0);
456
when "cusp_new":
457
return SpaceType(M2) in {"cusp_new", "cusp_newform"}
458
and (SpaceTypeParam(M2) eq 0 or SpaceTypeParam(M1) mod SpaceTypeParam(M2) eq 0);
459
when "eis_new":
460
return SpaceType(M2) in {"eis_new", "eis_newform"}
461
and (SpaceTypeParam(M2) eq 0 or SpaceTypeParam(M1) mod SpaceTypeParam(M2) eq 0);
462
when "cusp_newform":
463
if SpaceType(M2) in {"cusp", "cusp_new", "new"} then
464
return true;
465
elif SpaceType(M2) eq "cusp_newform" then
466
if WhichNewform(M1) ne 0 and WhichNewform(M2) ne 0 then
467
return WhichNewform(M1) eq WhichNewform(M2);
468
else // one of the strange situations where we don't know, use q-exp
469
return M1 eq M2;
470
end if;
471
else
472
return false;
473
end if;
474
when "eis_newform":
475
if SpaceType(M2) in {"eis", "eis_new", "new"} then
476
return true;
477
elif SpaceType(M2) eq "eis_newform" then
478
if WhichNewform(M1) ne 0 and WhichNewform(M2) ne 0 then
479
return WhichNewform(M1) eq WhichNewform(M2);
480
else // one of the strange situations where we don't know, use q-exp
481
return M1 eq M2;
482
end if;
483
else
484
return false;
485
end if;
486
else:
487
return false;
488
end case;
489
end intrinsic;
490
491
intrinsic HackobjInModFrm(f::ModFrmElt, M::ModFrm) -> BoolElt
492
{}
493
return Parent(f) eq M;
494
end intrinsic;
495
496
497
intrinsic IsNewform(f::ModFrmElt) -> BoolElt
498
{True if f was created using Newform.}
499
return assigned f`is_newform and f`is_newform;
500
end intrinsic;
501
502
intrinsic IsEisensteinSeries(f::ModFrmElt) -> BoolElt
503
{True if f was created using EisensteinSeries.}
504
return assigned f`eisenstein;
505
end intrinsic;
506
507
intrinsic EisensteinData(f::ModFrmElt) -> Tup
508
{The data <chi, psi, t, chi', psi'> that defines the Eisenstein series f.}
509
require assigned f`eisenstein : "Argument 1 is not an Eisenstein series.";
510
return f`eisenstein;
511
end intrinsic
512
513
intrinsic IsCuspidalNewform(f::ModFrmElt) -> BoolElt
514
{True if f is cuspidal and was created using the Newform intrinsic.}
515
return IsNewform(f) and not IsEisensteinSeries(f);
516
end intrinsic;
517
518
519
intrinsic IsNew(M::ModFrm) -> BoolElt
520
{True if M is contained in the new subspace of the ambient space of M.}
521
if not assigned M`is_new then
522
if M`type in {"new", "cusp_new", "eis_new", "eis_newform", "cusp_newform"} then
523
M`is_new := true;
524
elif assigned M`dimension and M`dimension eq 0 then
525
M`is_new := true;
526
elif Dimension(M) eq Dimension(NewSubspace(M)) then
527
M`is_new := true;
528
else
529
M`is_new := false;
530
end if;
531
end if;
532
return M`is_new;
533
end intrinsic;
534
535
536
intrinsic AmbientSpace(M::ModFrm) -> ModFrm
537
{The ambient space that contains M.}
538
if IsAmbientSpace(M) then
539
return M;
540
end if;
541
assert assigned M`ambient_space;
542
return M`ambient_space;
543
end intrinsic;
544
545
intrinsic RSpace(M::ModFrm) -> ModTupRng, Map, Map
546
{The underlying RSpace of M.}
547
V := RSpace(BaseRing(M), Dimension(M));
548
return V, hom<V -> M | x :-> M!x>, hom<M -> V | x :-> V!Eltseq(x)>;
549
end intrinsic;
550
551
function AssociatedSpaceOverZ(M)
552
assert Type(M) eq ModFrm;
553
if not assigned M`associated_space_over_z then
554
assert Type(BaseRing(M)) eq RngInt;
555
return M;
556
end if;
557
return M`associated_space_over_z;
558
end function;
559
560
intrinsic Precision(M::ModFrm) -> RngIntElt
561
{The default printing precision for elements of M.}
562
if not IsAmbientSpace(M) then
563
return Precision(AmbientSpace(M));
564
end if;
565
if not assigned M`default_precision or M`default_precision eq -1 then
566
M`default_precision := 8;
567
end if;
568
return M`default_precision;
569
end intrinsic;
570
571
intrinsic SetPrecision(M::ModFrm, prec::RngIntElt)
572
{Set the default printing precision for elements of M.}
573
requirege prec,1;
574
if not IsAmbientSpace(M) then
575
SetPrecision(AmbientSpace(M),prec);
576
else
577
M`default_precision := prec;
578
end if;
579
end intrinsic;
580
581
intrinsic Eltseq(f::ModFrmElt) -> SeqEnum
582
{The sequence [a1, ..., an] such that
583
f = a1*g_1 + ... + an*g_n, where
584
g_1, ..., g_n is the basis of the parent of f.}
585
if not assigned f`element then
586
g := Parent(f)!PowerSeries(f);
587
f`element := g`element;
588
end if;
589
return Eltseq(f`element);
590
end intrinsic;
591
592
593
function WhichNewform(M)
594
assert Type(M) eq ModFrm;
595
596
if assigned M`which_newform then
597
return M`which_newform;
598
else
599
return 0;
600
end if;
601
end function;
602
603
function Element(f)
604
assert Type(f) eq ModFrmElt;
605
if not assigned f`element then
606
dummy := Eltseq(f);
607
end if;
608
return f`element;
609
end function;
610