CoCalc Public Fileswww / tables / magma_src / ModFrm / congruences.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: congruences.m
10
11
11/10/02: Added some support for congruence for sequences of spaces.
12
13
$Header: /home/was/magma/packages/ModFrm/code/RCS/congruences.m,v 1.13 2002/10/26 22:40:39 was Exp was $
14
15
$Log: congruences.m,v $
16
Revision 1.13 2002/10/26 22:40:39 was
17
More fine tuning.
18
19
Revision 1.12 2002/10/26 22:35:46 was
20
nothing.
21
22
Revision 1.11 2002/10/26 22:35:24 was
23
More fine tuning.
24
25
Revision 1.10 2002/10/26 22:21:42 was
26
Finished fixing bug...
27
28
Revision 1.9 2002/10/26 22:21:03 was
29
Fixed a bug in CongruenceGroupAnemic -- sometimes there were false congruences
30
because one of the individual spaces wasn't saturated.
31
32
Revision 1.8 2002/05/30 10:00:27 was
33
Added CongruenceGroup for newforms.
34
35
Revision 1.7 2002/05/28 08:36:07 was
36
...
37
38
Revision 1.6 2002/05/28 08:35:34 was
39
Removed version of CongruenceGroupAnemic that doesn't ask for precision, because I don't know how
40
to compute the correct precision. Definitely what is given there currently is wrong. E.g.,
41
Level 2, weight 8, congruence between cuspidal and Eisenstein stuff.
42
43
Revision 1.5 2002/05/06 05:27:31 was
44
Allow congruence groups even when not over Z or Q, since basis is, by definition, always
45
actually defined over Z!
46
47
Revision 1.4 2002/04/13 07:26:33 was
48
??
49
50
Revision 1.3 2001/08/27 23:33:14 was
51
Added CongruenceGroupAnemic.
52
53
Revision 1.2 2001/05/30 18:54:09 was
54
Created.
55
56
Revision 1.1 2001/05/16 03:50:53 was
57
Initial revision
58
59
60
***************************************************************************/
61
62
import "misc.m" : SaturatePowerSeriesSequence;
63
64
function DepriveAndSaturate(B, N, prec)
65
R<q> := Parent(B[1]);
66
inds := [j : j in [0..prec-1] | GCD(j,N) eq 1];
67
C := [&+[Coefficient(f,i)*q^i : i in inds] + O(q^prec) : f in B];
68
return SaturatePowerSeriesSequence(C);
69
end function;
70
71
72
function IndexInSaturation(B, prec, N)
73
assert Type(B) eq SeqEnum;
74
// Returns the index and structure of the Z-module generated by the sum of
75
// the saturations of B1 and B2, taking into account only coefficients
76
// of the q-expansion of index coprime to N. We only saturate B1 and B2
77
// when N=/=1, since otherwise they should already be saturated.
78
// When N=/=1, they might not be, e.g., "23k2A" and "46k2A".
79
if #B le 1 or (#B eq 2 and (#B[1] eq 0 or #B[2] eq 0)) then
80
return AbelianGroup([1]);
81
end if;
82
if N eq 1 then
83
P := &cat B;
84
else
85
P := &cat [DepriveAndSaturate(A,N, prec) : A in B];
86
end if;
87
R := Parent(P[1]);
88
inds := [j : j in [0..prec-1] | GCD(j,N) eq 1];
89
X := [[Coefficient(f,i) : i in inds] : f in P];
90
D := RMatrixSpace(Integers(),#P,#inds)!(&cat X);
91
S := SmithForm(D);
92
if Rank(S) lt Nrows(S) then
93
return AbelianGroup([0]); // any congruence you'd like!
94
end if;
95
96
return AbelianGroup([S[i,i] : i in [1..Min(Nrows(S),Ncols(S))] | S[i,i] gt 1 ]);
97
end function;
98
99
intrinsic CongruenceGroup(M1::ModFrm, M2::ModFrm) -> GrpAb
100
{A group that measures all possible congruences to precision prec
101
between some integral modular form in M1 and some modular form in M2.}
102
require Characteristic(BaseRing(M1)) eq 0 and Characteristic(BaseRing(M2)) eq 0 :
103
"Arguments 1 and 2 must have characteristic 0.";
104
return CongruenceGroup(M1, M2,
105
1 + Max(PrecisionBound(M1 : Exact := false), PrecisionBound(M2 : Exact := false)));
106
end intrinsic;
107
108
intrinsic CongruenceGroup(M1::ModFrm, M2::ModFrm, prec::RngIntElt) -> GrpAb
109
{A group that measures all possible congruences to precision prec
110
between some integral modular form in M1 and some modular form in M2.}
111
require Characteristic(BaseRing(M1)) eq 0 and Characteristic(BaseRing(M2)) eq 0 :
112
"Arguments 1 and 2 must have characteristic 0.";
113
R := PowerSeriesRing(PolynomialRing(IntegerRing()));
114
return IndexInSaturation([[R| PowerSeries(f,prec) : f in Basis(M1)],
115
[R| PowerSeries(f,prec) : f in Basis(M2)]], prec, 1);
116
end intrinsic;
117
118
intrinsic CongruenceGroupAnemic(M1::ModFrm, M2::ModFrm, prec::RngIntElt) -> GrpAb
119
{A group that measures all possible congruences to precision prec
120
between some integral modular form in M1 and some modular form in M2, where
121
we only consider coefficients of q^n when n is 0 or coprime to the levels
122
of M1 and M2.}
123
require Characteristic(BaseRing(M1)) eq 0 and Characteristic(BaseRing(M2)) eq 0 :
124
"Arguments 1 and 2 must have characteristic 0.";
125
126
R := PowerSeriesRing(PolynomialRing(IntegerRing()));
127
B1 := [R|PowerSeries(f,prec) : f in Basis(M1)];
128
B2 := [R|PowerSeries(f,prec) : f in Basis(M2)];
129
return IndexInSaturation([B1, B2], prec, Level(M1)*Level(M2));
130
end intrinsic;
131
132
intrinsic CongruenceGroup(M1::ModSym, M2::ModSym, prec::RngIntElt) -> GrpAb
133
{A group that measures all possible congruences to precision prec
134
between some integral modular form in M1 and some modular form in M2.
135
Both M1 and M2 must be cuspidal.}
136
require Type(BaseField(M1)) eq FldRat :
137
"The base field of argument 1 must be Q.";
138
require Type(BaseField(M2)) eq FldRat :
139
"The base field of argument 2 must be Q.";
140
require IsCuspidal(M1) : "Argument 1 must be cuspidal.";
141
require IsCuspidal(M2) : "Argument 2 must be cuspidal.";
142
return IndexInSaturation([qIntegralBasis(M1,prec), qIntegralBasis(M2,prec)], prec, 1);
143
end intrinsic;
144
145
intrinsic CongruenceGroup(M::[ModSym], prec::RngIntElt) -> GrpAb
146
{A group that measures all possible congruences to precision prec
147
between some integral modular form in some Mi and some Mj where Mi, Mj in M.
148
The elements of M must be cuspidal.}
149
for A in M do
150
require Type(BaseField(A)) eq FldRat :
151
"Base fields of argument 1 must be Q.";
152
require IsCuspidal(A) : "Argument 1 must be cuspidal.";
153
end for;
154
return IndexInSaturation([qIntegralBasis(A,prec) : A in M], prec, 1);
155
end intrinsic;
156
157
158
intrinsic CongruenceGroupAnemic(M1::ModSym, M2::ModSym, prec::RngIntElt) -> GrpAb
159
{A group that measures all possible congruences to precision prec
160
between some integral modular form in M1 and some modular form in M2, but
161
where only the coefficients a_n, with n coprime to both levels, are considered.
162
Both M1 and M2 must be cuspidal.}
163
require Type(BaseField(M1)) eq FldRat :
164
"The base field of argument 1 must be Q.";
165
require Type(BaseField(M2)) eq FldRat :
166
"The base field of argument 2 must be Q.";
167
require IsCuspidal(M1) : "Argument 1 must be cuspidal.";
168
require IsCuspidal(M2) : "Argument 2 must be cuspidal.";
169
return IndexInSaturation([qIntegralBasis(M1,prec), qIntegralBasis(M2,prec)], prec,
170
Level(M1)*Level(M2));
171
end intrinsic;
172
173
intrinsic CongruenceGroup(M1::ModSym, M2::ModFrm, prec::RngIntElt) -> GrpAb
174
{}
175
require Type(BaseField(M1)) eq FldRat :
176
"The base field of argument 1 must be Q.";
177
require Characteristic(BaseRing(M2)) eq 0 :
178
"The base ring of argument 1 must have characteristic 0.";
179
R := PowerSeriesRing(PolynomialRing(IntegerRing()));
180
return IndexInSaturation([qIntegralBasis(M1,prec),
181
[R| PowerSeries(f,prec) : f in Basis(M2)]],
182
prec, 1);
183
end intrinsic;
184
185
intrinsic CongruenceGroupAnemic(M1::ModSym, M2::ModFrm,
186
prec::RngIntElt) -> GrpAb
187
{}
188
require Type(BaseField(M1)) eq FldRat :
189
"The base field of argument 1 must be Q.";
190
require Characteristic(BaseRing(M2)) eq 0 :
191
"The base ring of argument 1 must have characteristic 0.";
192
require IsCuspidal(M1) : "Argument 1 must be cuspidal.";
193
R := PowerSeriesRing(PolynomialRing(IntegerRing()));
194
return IndexInSaturation([qIntegralBasis(M1,prec),
195
[R| PowerSeries(f,prec) : f in Basis(M2)]],
196
prec, Level(M1)*Level(M2));
197
end intrinsic;
198
199
intrinsic CongruenceGroup(M1::ModFrm, M2::ModSym, prec::RngIntElt) -> GrpAb
200
{}
201
require Characteristic(BaseRing(M1)) eq 0 :
202
"The base ring of argument 1 must have characteristic 0.";
203
require Type(BaseField(M2)) eq FldRat :
204
"The base field of argument 2 must be Q.";
205
return CongruenceGroup(M2,M1,prec);
206
end intrinsic;
207
208
intrinsic CongruenceGroupAnemic(M1::ModFrm, M2::ModSym,
209
prec::RngIntElt) -> GrpAb
210
{}
211
require Characteristic(BaseRing(M1)) eq 0 :
212
"The base ring of argument 1 must have characteristic 0.";
213
require Type(BaseField(M2)) eq FldRat :
214
"The base field of argument 2 must be Q.";
215
require IsCuspidal(M1) : "Argument 1 must be cuspidal.";
216
return CongruenceGroupAnemic(M2,M1,prec);
217
end intrinsic;
218
219
220
///////////////////////////////////////////
221
222
intrinsic CongruenceGroup(f1::ModFrmElt, f2::ModFrmElt) -> GrpAb
223
{}
224
require Characteristic(BaseRing(Parent(f1))) eq 0 and Characteristic(BaseRing(Parent(f2))) eq 0 :
225
"Arguments 1 and 2 must have characteristic 0.";
226
require IsNewform(f1) and IsNewform(f2) : "Arguments 1 and 2 must be newforms";
227
return CongruenceGroup(Parent(f1),Parent(f2));
228
end intrinsic;
229
230
intrinsic CongruenceGroup(f1::ModFrmElt, f2::ModFrmElt, prec::RngIntElt) -> GrpAb
231
{}
232
require Characteristic(BaseRing(Parent(f1))) eq 0 and Characteristic(BaseRing(Parent(f2))) eq 0 :
233
"Arguments 1 and 2 must have characteristic 0.";
234
require IsNewform(f1) and IsNewform(f2) : "Arguments 1 and 2 must be newforms";
235
return CongruenceGroup(Parent(f1),Parent(f2),prec);
236
end intrinsic;
237
238
intrinsic CongruenceGroupAnemic(f1::ModFrmElt, f2::ModFrmElt, prec::RngIntElt) -> GrpAb
239
{}
240
require Characteristic(BaseRing(Parent(f1))) eq 0 and Characteristic(BaseRing(Parent(f2))) eq 0 :
241
"Arguments 1 and 2 must have characteristic 0.";
242
require IsNewform(f1) and IsNewform(f2) : "Arguments 1 and 2 must be newforms";
243
return CongruenceGroupAnemic(Parent(f1),Parent(f2),prec);
244
end intrinsic;
245
246