Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/ssmod/ssmod.py
4057 views
1
"""
2
Module of Supersingular Points
3
4
The module of divisors on the modular curve `X_0(N)` over `F_p` supported at supersingular points.
5
6
AUTHORS:
7
8
- William Stein
9
10
- David Kohel
11
12
- Iftikhar Burhanuddin
13
14
EXAMPLES::
15
16
sage: x = SupersingularModule(389)
17
sage: m = x.T(2).matrix()
18
sage: a = m.change_ring(GF(97))
19
sage: D = a.decomposition()
20
sage: D[:3]
21
[
22
(Vector space of degree 33 and dimension 1 over Finite Field of size 97
23
Basis matrix:
24
[ 0 0 0 1 96 96 1 96 96 0 2 96 96 0 1 0 1 2 95 0 1 1 0 1 0 95 0 96 95 1 96 0 2], True),
25
(Vector space of degree 33 and dimension 1 over Finite Field of size 97
26
Basis matrix:
27
[ 0 1 96 75 16 81 22 17 17 0 0 80 80 1 16 40 74 0 0 96 81 23 57 74 0 0 0 24 0 23 73 0 0], True),
28
(Vector space of degree 33 and dimension 1 over Finite Field of size 97
29
Basis matrix:
30
[ 0 1 96 90 90 7 7 6 91 0 0 91 6 13 7 0 91 0 0 84 90 6 0 6 0 0 0 90 0 91 7 0 0], True)
31
]
32
sage: len(D)
33
9
34
35
We compute a Hecke operator on a space of huge dimension!::
36
37
sage: X = SupersingularModule(next_prime(10000))
38
sage: t = X.T(2).matrix() # long time (21s on sage.math, 2011)
39
sage: t.nrows() # long time
40
835
41
42
TESTS::
43
44
sage: X = SupersingularModule(389)
45
sage: T = X.T(2).matrix().change_ring(QQ)
46
sage: d = T.decomposition()
47
sage: len(d)
48
6
49
sage: [a[0].dimension() for a in d]
50
[1, 1, 2, 3, 6, 20]
51
sage: loads(dumps(X)) == X
52
True
53
sage: loads(dumps(d)) == d
54
True
55
"""
56
57
#*****************************************************************************
58
# Copyright (C) 2004,2006 William Stein <[email protected]>
59
# Copyright (C) 2006 David Kohel <[email protected]>
60
# Copyright (C) 2006 Iftikhar Burhanuddin <[email protected]>
61
# Distributed under the terms of the GNU General Public License (GPL)
62
#
63
# This code is distributed in the hope that it will be useful,
64
# but WITHOUT ANY WARRANTY; without even the implied warranty of
65
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
66
# General Public License for more details.
67
#
68
# The full text of the GPL is available at:
69
#
70
# http://www.gnu.org/licenses/
71
#*****************************************************************************
72
73
import math
74
75
import sage.modular.hecke.all as hecke
76
import sage.rings.all as rings
77
from sage.matrix.matrix_space import MatrixSpace
78
from sage.modular.arithgroup.all import Gamma0
79
from sage.databases.db_class_polynomials import HilbertClassPolynomialDatabase
80
from sage.databases.db_modular_polynomials \
81
import ClassicalModularPolynomialDatabase
82
83
from sage.misc.misc import verbose
84
85
86
def Phi2_quad(J3, ssJ1, ssJ2):
87
r"""
88
This function returns a certain quadratic polynomial over a finite
89
field in indeterminate J3.
90
91
The roots of the polynomial along with ssJ1 are the
92
neighboring/2-isogenous supersingular j-invariants of ssJ2.
93
94
INPUT:
95
96
- ``J3`` -- indeterminate of a univariate polynomial ring defined over a finite
97
field with p^2 elements where p is a prime number
98
99
- ``ssJ2``, ``ssJ2`` -- supersingular j-invariants over the finite field
100
101
OUTPUT:
102
103
- polynomial -- defined over the finite field
104
105
EXAMPLES:
106
The following code snippet produces a factor of the modular polynomial
107
`\Phi_{2}(x,j_{in})`, where `j_{in}` is a supersingular j-invariant
108
defined over the finite field with `37^2` elements::
109
110
sage: F = GF(37^2, 'a')
111
sage: X = PolynomialRing(F, 'x').gen()
112
sage: j_in = supersingular_j(F)
113
sage: poly = sage.modular.ssmod.ssmod.Phi_polys(2,X,j_in)
114
sage: poly.roots()
115
[(8, 1), (27*a + 23, 1), (10*a + 20, 1)]
116
sage: sage.modular.ssmod.ssmod.Phi2_quad(X, F(8), j_in)
117
x^2 + 31*x + 31
118
119
.. note::
120
121
Given a root (j1,j2) to the polynomial `Phi_2(J1,J2)`, the pairs
122
(j2,j3) not equal to (j2,j1) which solve `Phi_2(j2,j3)` are roots of
123
the quadratic equation:
124
125
J3^2 + (-j2^2 + 1488*j2 + (j1 - 162000))*J3 + (-j1 + 1488)*j2^2 +
126
(1488*j1 + 40773375)*j2 + j1^2 - 162000*j1 + 8748000000
127
128
This will be of use to extend the 2-isogeny graph, once the initial
129
three roots are determined for `Phi_2(J1,J2)`.
130
131
AUTHORS:
132
133
- David Kohel -- [email protected]
134
135
- Iftikhar Burhanuddin -- [email protected]
136
"""
137
ssJ1_pow2 = ssJ1**2
138
ssJ2_pow2 = ssJ2**2
139
140
return J3.parent()([(-ssJ1 + 1488)*ssJ2_pow2+ (1488*ssJ1 +
141
40773375)*ssJ2 + ssJ1_pow2 - 162000*ssJ1 + 8748000000,
142
-ssJ2_pow2 + 1488*ssJ2 + (ssJ1 - 162000),
143
1])
144
145
146
147
def Phi_polys(L, x, j):
148
r"""
149
This function returns a certain polynomial of degree `L+1` in the
150
indeterminate x over a finite field.
151
152
The roots of the **modular** polynomial `\Phi(L, x, j)` are the
153
`L`-isogenous supersingular j-invariants of j.
154
155
INPUT:
156
157
- ``L`` -- integer, either 2,3,5,7 or 11
158
159
- ``x`` -- indeterminate of a univariate polynomial ring defined over a
160
finite field with p^2 elements, where p is a prime number
161
162
- ``j`` -- supersingular j-invariant over the finite field
163
164
OUTPUT:
165
166
- polynomial -- defined over the finite field
167
168
EXAMPLES:
169
The following code snippet produces the modular polynomial
170
`\Phi_{L}(x,j_{in})`, where `j_{in}` is a supersingular j-invariant
171
defined over the finite field with `7^2` elements::
172
173
sage: F = GF(7^2, 'a')
174
sage: X = PolynomialRing(F, 'x').gen()
175
sage: j_in = supersingular_j(F)
176
sage: sage.modular.ssmod.ssmod.Phi_polys(2,X,j_in)
177
x^3 + 3*x^2 + 3*x + 1
178
sage: sage.modular.ssmod.ssmod.Phi_polys(3,X,j_in)
179
x^4 + 4*x^3 + 6*x^2 + 4*x + 1
180
sage: sage.modular.ssmod.ssmod.Phi_polys(5,X,j_in)
181
x^6 + 6*x^5 + x^4 + 6*x^3 + x^2 + 6*x + 1
182
sage: sage.modular.ssmod.ssmod.Phi_polys(7,X,j_in)
183
x^8 + x^7 + x + 1
184
sage: sage.modular.ssmod.ssmod.Phi_polys(11,X,j_in)
185
x^12 + 5*x^11 + 3*x^10 + 3*x^9 + 5*x^8 + x^7 + x^5 + 5*x^4 + 3*x^3 + 3*x^2 + 5*x + 1
186
187
AUTHORS:
188
189
- William Stein -- [email protected]
190
191
- David Kohel -- [email protected]
192
193
- Iftikhar Burhanuddin -- [email protected]
194
"""
195
if not(L in [2,3,5,7,11]):
196
raise ValueError, "L should be either 2,3,5,7 or 11. For other values use ClassicalModularPolynomialDatabase()."
197
198
j_tmp = 1
199
j_pow = [j_tmp]
200
#degree of polynomial = L+1
201
for i in range(int(L+2)):
202
j_tmp = j_tmp*j
203
j_pow += [j_tmp]
204
205
if L == 2:
206
return x.parent()([j_pow[3] - 162000*j_pow[2] + 8748000000*j_pow[1] -
207
157464000000000,
208
1488*j_pow[2] + 40773375*j_pow[1] + 8748000000,
209
- (j_pow[2] - 1488*j_pow[1] + 162000),
210
1])
211
elif L == 3:
212
return x.parent()([1855425871872000000000*j_pow[1] +
213
452984832000000*j_pow[2] + 36864000*j_pow[3] + j_pow[4],
214
1855425871872000000000 - 770845966336000000*j_pow[1] +
215
8900222976000*j_pow[2] - 1069956*j_pow[3],
216
452984832000000 + 8900222976000*j_pow[1] + 2587918086*j_pow[2] + 2232*j_pow[3],
217
36864000 - 1069956*j_pow[1] + 2232*j_pow[2] - j_pow[3],
218
1])
219
elif L == 5:
220
return x.parent()([
221
141359947154721358697753474691071362751004672000 +
222
53274330803424425450420160273356509151232000*j_pow[1] +
223
6692500042627997708487149415015068467200*j_pow[2] +
224
280244777828439527804321565297868800*j_pow[3] +
225
1284733132841424456253440*j_pow[4] + 1963211489280*j_pow[5] +
226
j_pow[6],
227
53274330803424425450420160273356509151232000 -
228
264073457076620596259715790247978782949376*j_pow[1] +
229
36554736583949629295706472332656640000*j_pow[2] -
230
192457934618928299655108231168000*j_pow[3] +
231
128541798906828816384000*j_pow[4] - 246683410950*j_pow[5],
232
6692500042627997708487149415015068467200 +
233
36554736583949629295706472332656640000*j_pow[1] +
234
5110941777552418083110765199360000*j_pow[2] +
235
26898488858380731577417728000*j_pow[3] +
236
383083609779811215375*j_pow[4] + 2028551200*j_pow[5],
237
280244777828439527804321565297868800 -
238
192457934618928299655108231168000*j_pow[1] +
239
26898488858380731577417728000*j_pow[2] -
240
441206965512914835246100*j_pow[3] +
241
107878928185336800*j_pow[4] - 4550940*j_pow[5],
242
1284733132841424456253440 + 128541798906828816384000*j_pow[1]
243
+ 383083609779811215375*j_pow[2] + 107878928185336800*j_pow[3]
244
+ 1665999364600*j_pow[4] + 3720*j_pow[5],
245
1963211489280 - 246683410950*j_pow[1] + 2028551200*j_pow[2] - 4550940*j_pow[3]
246
+ 3720*j_pow[4] - j_pow[5],
247
1])
248
elif L == 7:
249
return x.parent()([1464765079488386840337633731737402825128271675392000000000000000000*j_pow[2]
250
+ 13483958224762213714698012883865296529472356352000000000000000*j_pow[3]
251
+ 41375720005635744770247248526572116368162816000000000000*j_pow[4]
252
+ 42320664241971721884753245384947305283584000000000*j_pow[5] +
253
3643255017844740441130401792000000*j_pow[6] +
254
104545516658688000*j_pow[7] + j_pow[8],
255
1221349308261453750252370983314569119494710493184000000000000000000*j_pow[1]
256
- 838538082798149465723818021032241603179964268544000000000000000*j_pow[2]
257
- 129686683986501811181602978946723823397619367936000000000000*j_pow[3]
258
+ 553293497305121712634517214392820316998991872000000000*j_pow[4]
259
- 40689839325168186578698294668599003971584000000*j_pow[5] +
260
1038063543615451121419229773824000*j_pow[6] -
261
34993297342013192*j_pow[7],
262
1464765079488386840337633731737402825128271675392000000000000000000
263
- 838538082798149465723818021032241603179964268544000000000000000*j_pow[1]
264
- 46666007311089950798495647194817495401448341504000000000000*j_pow[2]
265
+ 72269669689202948469186346100000679630099972096000000000*j_pow[3]
266
+ 308718989330868920558541707287296140145328128000000*j_pow[4] +
267
11269804827778129625111322263056523132928000*j_pow[5] +
268
10685207605419433304631062899228*j_pow[6] +
269
720168419610864*j_pow[7],
270
13483958224762213714698012883865296529472356352000000000000000 -
271
129686683986501811181602978946723823397619367936000000000000*j_pow[1]
272
+ 72269669689202948469186346100000679630099972096000000000*j_pow[2]
273
- 5397554444336630396660447092290576395211374592000000*j_pow[3] +
274
17972351380696034759035751584170427941396480000*j_pow[4] -
275
901645312135695263877115693740562092344*j_pow[5] +
276
16125487429368412743622133040*j_pow[6] - 4079701128594*j_pow[7],
277
41375720005635744770247248526572116368162816000000000000 +
278
553293497305121712634517214392820316998991872000000000*j_pow[1] +
279
308718989330868920558541707287296140145328128000000*j_pow[2] +
280
17972351380696034759035751584170427941396480000*j_pow[3] +
281
88037255060655710247136461896264828390470*j_pow[4] +
282
14066810691825882583305340438456800*j_pow[5] +
283
4460942463213898353207432*j_pow[6] + 9437674400*j_pow[7],
284
42320664241971721884753245384947305283584000000000 -
285
40689839325168186578698294668599003971584000000*j_pow[1] +
286
11269804827778129625111322263056523132928000*j_pow[2] -
287
901645312135695263877115693740562092344*j_pow[3] +
288
14066810691825882583305340438456800*j_pow[4] -
289
18300817137706889881369818348*j_pow[5] +
290
177089350028475373552*j_pow[6] - 10246068*j_pow[7],
291
3643255017844740441130401792000000 +
292
1038063543615451121419229773824000*j_pow[1] +
293
10685207605419433304631062899228*j_pow[2] +
294
16125487429368412743622133040*j_pow[3] +
295
4460942463213898353207432*j_pow[4] +
296
177089350028475373552*j_pow[5] + 312598931380281*j_pow[6] +
297
5208*j_pow[7],
298
104545516658688000 - 34993297342013192*j_pow[1] +
299
720168419610864*j_pow[2] - 4079701128594*j_pow[3] +
300
9437674400*j_pow[4] - 10246068*j_pow[5] + 5208*j_pow[6] -
301
j_pow[7],
302
1])
303
elif L == 11:
304
return x.parent()([3924233450945276549086964624087200490995247233706746270899364206426701740619416867392454656000000000000000000000000000000000000
305
- 3708476896661234261166595138586620846782660237574536888784393380944856551532392652692520960000000000000000000000000000000000*j_pow[1]
306
+ 1509199706449264373105244249368970977209959173066491449939153900434037998316228131684352000000000000000000000000000000000*j_pow[2]
307
- 337500037290942764495395868386562971754016116785390841072048221617443316658082155384012800000000000000000000000000000*j_pow[3]
308
+ 43714682637171236021367604966833305309923746974850894665325331604362303109715777067941888000000000000000000000000*j_pow[4]
309
- 3111357148902865912417988391836350251682805385917571877568422664218078901010004935966720000000000000000000000*j_pow[5]
310
+ 95356266594731795079493309965756674711058734831164489212811553129058773080352804044800000000000000000000*j_pow[6]
311
+ 618840723107761889896363016885251574078635388443306832549992828319945330157158400000000000000000*j_pow[7]
312
+ 1338586400912357073420399795635643400599836918986297982928179335149920452608000000000000*j_pow[8]
313
+ 965122546660349298406724063940884252743873633176129290337528305418240000000000*j_pow[9]
314
+ 29298331981110197366602526090413106879319244800000000*j_pow[10]
315
+ 296470902355240575283200000*j_pow[11]
316
+ j_pow[12],
317
- 3708476896661234261166595138586620846782660237574536888784393380944856551532392652692520960000000000000000000000000000000000
318
+ 6950986496704390042399105433049126860396103535300642728895074819467726754375236055025582080000000000000000000000000000000*j_pow[1]
319
- 4175190947377089941611452135383204997172948465221368432119554418845446929655566146994176000000000000000000000000000000*j_pow[2]
320
+ 493751729222149651035457063068642305508233453469401395944974296438196687728770695603159040000000000000000000000000*j_pow[3]
321
+ 59659609577030961637541110289112021078091104767187787822549078869394205439302452893450240000000000000000000000*j_pow[4]
322
- 7840379248214196729643062796493269425081859930100141304047932909346022483171510017064960000000000000000000*j_pow[5]
323
- 95333447356443287210404497374050404132491763274506548619337189691919811046970438451200000000000000000*j_pow[6]
324
- 24155957253764418975307742823129586187061243620756339515602571075061236992294518784000000000000*j_pow[7]
325
+ 66806304467998310581793391194791115184805127528413091235284315294143736709120000000000*j_pow[8]
326
- 1458178254597295207839980786768623018650234306932331393013634952069120000000*j_pow[9]
327
+ 33446467926379842030532687838341039552110187929600000*j_pow[10]
328
- 374642006356701393515817612*j_pow[11],
329
1509199706449264373105244249368970977209959173066491449939153900434037998316228131684352000000000000000000000000000000000
330
- 4175190947377089941611452135383204997172948465221368432119554418845446929655566146994176000000000000000000000000000000*j_pow[1]
331
- 301851634381591833346238394387907563828793379391119445614595161272769455527698270716428288000000000000000000000000*j_pow[2]
332
+ 1038677201789914991362090465961377302769147065985487222285672689158918175716097236444119040000000000000000000000*j_pow[3]
333
+ 378494977797549959360178068152933818044335078157093771639955480261351930169113765048483840000000000000000000*j_pow[4]
334
+ 9718148718139346647384449201643833517488848029697396574289278515913329360524510494720000000000000000000*j_pow[5]
335
+ 30494044246550310117871895628421273379173050630568397072391110688366558535804457582592000000000000*j_pow[6]
336
+ 44681231489418997440503069818655052635806384532381152777755381649015689662976491520000000000*j_pow[7]
337
+ 171790435018380416903247878610824648919543398246401012395341432490921925017600000000*j_pow[8]
338
+ 804436418307995738740132598166893365099468842089705900525050627891200000*j_pow[9]
339
+ 1587728122949690904187089204116332301200302760915266*j_pow[10]
340
+ 27209811658056645815522600*j_pow[11],
341
- 337500037290942764495395868386562971754016116785390841072048221617443316658082155384012800000000000000000000000000000
342
+ 493751729222149651035457063068642305508233453469401395944974296438196687728770695603159040000000000000000000000000*j_pow[1]
343
+ 1038677201789914991362090465961377302769147065985487222285672689158918175716097236444119040000000000000000000000*j_pow[2]
344
- 925461466455522523607980072366478440235575959511945288268604770825451300845059605937520640000000000000000000*j_pow[3]
345
- 51038778870467375317174627414281203016789153392265449880353463871004348816411677478092800000000000000000*j_pow[4]
346
- 1328993907465108152135763886999825071444084099881098607565574716140191426369978927939584000000000000*j_pow[5]
347
- 7211912299746007510535159486199919697482960389278446632552985263875183091897870581760000000000*j_pow[6]
348
- 22093249696627933419655226823604057638897222562682635800269909178325710985117040640000000*j_pow[7]
349
+ 79513247125057906492841989395207442300133781750924860449090230806481243648000000*j_pow[8]
350
- 199188452917764242987050083089364860927274115441197382331866126825820*j_pow[9]
351
+ 14131378888778142661582693947549844785863493325800*j_pow[10]
352
- 529134841844639613861795*j_pow[11],
353
43714682637171236021367604966833305309923746974850894665325331604362303109715777067941888000000000000000000000000
354
+ 59659609577030961637541110289112021078091104767187787822549078869394205439302452893450240000000000000000000000*j_pow[1]
355
+ 378494977797549959360178068152933818044335078157093771639955480261351930169113765048483840000000000000000000*j_pow[2]
356
- 51038778870467375317174627414281203016789153392265449880353463871004348816411677478092800000000000000000*j_pow[3]
357
+ 15043423165563966645618284609730360176005265392518745580151910727157028699006028388237312000000000000*j_pow[4]
358
- 177994641867075262695184980920462608604060357466681128822395417442867019643767352197120000000000*j_pow[5]
359
+ 1938738373821740121470446368665797412833082873875468530371642913339302678999680942080000000*j_pow[6]
360
+ 2973119672716212219456471881112888569835575578534065127175856819648732682854604800000*j_pow[7]
361
+ 8498500708725193890718329655230574962816784139443636591086906768989729050095*j_pow[8]
362
+ 22148485195925584385790489089697473918894904664093860668378292000*j_pow[9]
363
+ 35372414460361796790312007060191890803134127320*j_pow[10]
364
+ 4297837238774928467520*j_pow[11],
365
- 3111357148902865912417988391836350251682805385917571877568422664218078901010004935966720000000000000000000000
366
- 7840379248214196729643062796493269425081859930100141304047932909346022483171510017064960000000000000000000*j_pow[1]
367
+ 9718148718139346647384449201643833517488848029697396574289278515913329360524510494720000000000000000000*j_pow[2]
368
- 1328993907465108152135763886999825071444084099881098607565574716140191426369978927939584000000000000*j_pow[3]
369
- 177994641867075262695184980920462608604060357466681128822395417442867019643767352197120000000000*j_pow[4]
370
- 15057297311708922526580514410563848478334693758624999774108600968667487260827388477440000000*j_pow[5]
371
+ 224080399886627495149771654692369177094059649940825305182078225594292057242702643200000*j_pow[6]
372
- 75948585201267973403627533631138995089882647284307484579413691458563029509971992*j_pow[7]
373
+ 208334210762751500564946204497082337222910461284651050215872586641463200*j_pow[8]
374
- 994774826102691960922410649494629085486856242714439003812180*j_pow[9]
375
+ 28890545335855949285086003898461917345026160*j_pow[10]
376
- 17899526272883039048*j_pow[11],
377
95356266594731795079493309965756674711058734831164489212811553129058773080352804044800000000000000000000
378
- 95333447356443287210404497374050404132491763274506548619337189691919811046970438451200000000000000000*j_pow[1]
379
+ 30494044246550310117871895628421273379173050630568397072391110688366558535804457582592000000000000*j_pow[2]
380
- 7211912299746007510535159486199919697482960389278446632552985263875183091897870581760000000000*j_pow[3]
381
+ 1938738373821740121470446368665797412833082873875468530371642913339302678999680942080000000*j_pow[4]
382
+ 224080399886627495149771654692369177094059649940825305182078225594292057242702643200000*j_pow[5]
383
+ 1168150167526575837857761510359647773943258089269992605255478096499695783789300124*j_pow[6]
384
+ 247900233561939294388612799857476424364856251769094880288086537904279396400*j_pow[7]
385
+ 987807801334019988631500819088661487281712947788833523552559299560*j_pow[8]
386
+ 14690460927260804690751501000083244161647396386205851440*j_pow[9]
387
+ 7848482999227584325448694633580010490867*j_pow[10]
388
+ 42570393135641712*j_pow[11],
389
618840723107761889896363016885251574078635388443306832549992828319945330157158400000000000000000
390
- 24155957253764418975307742823129586187061243620756339515602571075061236992294518784000000000000*j_pow[1]
391
+ 44681231489418997440503069818655052635806384532381152777755381649015689662976491520000000000*j_pow[2]
392
- 22093249696627933419655226823604057638897222562682635800269909178325710985117040640000000*j_pow[3]
393
+ 2973119672716212219456471881112888569835575578534065127175856819648732682854604800000*j_pow[4]
394
- 75948585201267973403627533631138995089882647284307484579413691458563029509971992*j_pow[5]
395
+ 247900233561939294388612799857476424364856251769094880288086537904279396400*j_pow[6]
396
- 64999046469909490143435875140651300541119093852394968074094803537810*j_pow[7]
397
+ 636861023141767565580039581191818069063579259290464688398880*j_pow[8]
398
- 51135193038502008150804190472844550800569441050500*j_pow[9]
399
+ 645470833566425875717489618904152240*j_pow[10]
400
- 61058988656490*j_pow[11],
401
1338586400912357073420399795635643400599836918986297982928179335149920452608000000000000
402
+ 66806304467998310581793391194791115184805127528413091235284315294143736709120000000000*j_pow[1]
403
+ 171790435018380416903247878610824648919543398246401012395341432490921925017600000000*j_pow[2]
404
+ 79513247125057906492841989395207442300133781750924860449090230806481243648000000*j_pow[3]
405
+ 8498500708725193890718329655230574962816784139443636591086906768989729050095*j_pow[4]
406
+ 208334210762751500564946204497082337222910461284651050215872586641463200*j_pow[5]
407
+ 987807801334019988631500819088661487281712947788833523552559299560*j_pow[6]
408
+ 636861023141767565580039581191818069063579259290464688398880*j_pow[7]
409
+ 29211180544704743418963619709378403797452606969172658*j_pow[8]
410
+ 24228593349948582884094197811518266845689352*j_pow[9]
411
+ 12407796387712093514736413264496*j_pow[10]
412
+ 53686822816*j_pow[11],
413
965122546660349298406724063940884252743873633176129290337528305418240000000000
414
- 1458178254597295207839980786768623018650234306932331393013634952069120000000*j_pow[1]
415
+ 804436418307995738740132598166893365099468842089705900525050627891200000*j_pow[2]
416
- 199188452917764242987050083089364860927274115441197382331866126825820*j_pow[3]
417
+ 22148485195925584385790489089697473918894904664093860668378292000*j_pow[4]
418
- 994774826102691960922410649494629085486856242714439003812180*j_pow[5]
419
+ 14690460927260804690751501000083244161647396386205851440*j_pow[6]
420
- 51135193038502008150804190472844550800569441050500*j_pow[7]
421
+ 24228593349948582884094197811518266845689352*j_pow[8]
422
- 573388748843683532691009051194955437*j_pow[9]
423
+ 30134971854812981978547264*j_pow[10] - 28278756*j_pow[11],
424
29298331981110197366602526090413106879319244800000000
425
+ 33446467926379842030532687838341039552110187929600000*j_pow[1]
426
+ 1587728122949690904187089204116332301200302760915266*j_pow[2]
427
+ 14131378888778142661582693947549844785863493325800*j_pow[3]
428
+ 35372414460361796790312007060191890803134127320*j_pow[4]
429
+ 28890545335855949285086003898461917345026160*j_pow[5]
430
+ 7848482999227584325448694633580010490867*j_pow[6]
431
+ 645470833566425875717489618904152240*j_pow[7]
432
+ 12407796387712093514736413264496*j_pow[8]
433
+ 30134971854812981978547264*j_pow[9]
434
+ 1608331026427734378*j_pow[10]
435
+ 8184*j_pow[11],
436
296470902355240575283200000
437
- 374642006356701393515817612*j_pow[1]
438
+ 27209811658056645815522600*j_pow[2]
439
- 529134841844639613861795*j_pow[3]
440
+ 4297837238774928467520*j_pow[4]
441
- 17899526272883039048*j_pow[5]
442
+ 42570393135641712*j_pow[6]
443
- 61058988656490*j_pow[7]
444
+ 53686822816*j_pow[8]
445
- 28278756*j_pow[9]
446
+ 8184*j_pow[10]
447
- j_pow[11],
448
1])
449
450
451
def dimension_supersingular_module(prime, level=1):
452
r"""
453
This function returns the dimension of the Supersingular module, which is
454
equal to the dimension of the space of modular forms of weight `2`
455
and conductor equal to prime times level.
456
457
INPUT:
458
459
- ``prime`` -- integer, prime
460
461
- ``level`` -- integer, positive
462
463
OUTPUT:
464
dimension -- integer, nonnegative
465
466
EXAMPLES:
467
The code below computes the dimensions of Supersingular modules
468
with level=1 and prime = 7, 15073 and 83401::
469
470
sage: dimension_supersingular_module(7)
471
1
472
473
sage: dimension_supersingular_module(15073)
474
1256
475
476
sage: dimension_supersingular_module(83401)
477
6950
478
479
NOTES:
480
The case of level > 1 has not been implemented yet.
481
482
AUTHORS:
483
484
- David Kohel -- [email protected]
485
486
- Iftikhar Burhanuddin - [email protected]
487
"""
488
if not(rings.Integer(prime).is_prime()):
489
raise ValueError, "%s is not a prime"%prime
490
491
if level == 1:
492
return Gamma0(prime).dimension_modular_forms(2)
493
494
#list of genus(X_0(level)) equal to zero
495
#elif (level in [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 16, 18, 25]):
496
#compute basis
497
498
else:
499
raise NotImplementedError
500
501
502
def supersingular_D(prime):
503
r"""
504
This function returns a fundamental discriminant `D` of an
505
imaginary quadratic field, where the given prime does not split
506
(see Silverman's Advanced Topics in the Arithmetic of Elliptic
507
Curves, page 184, exercise 2.30(d).)
508
509
INPUT:
510
511
- prime -- integer, prime
512
513
OUTPUT:
514
D -- integer, negative
515
516
EXAMPLES:
517
518
These examples return *supersingular discriminants* for 7,
519
15073 and 83401::
520
521
sage: supersingular_D(7)
522
-4
523
524
sage: supersingular_D(15073)
525
-15
526
527
sage: supersingular_D(83401)
528
-7
529
530
AUTHORS:
531
532
- David Kohel - [email protected]
533
534
- Iftikhar Burhanuddin - [email protected]
535
"""
536
if not(rings.Integer(prime).is_prime()):
537
raise ValueError, "%s is not a prime"%prime
538
539
#Making picking D more intelligent
540
D = -1
541
while True:
542
Dmod4 = rings.Mod(D,4)
543
if Dmod4 in (0,1) and (rings.kronecker(D,prime) != 1):
544
return D
545
D = D - 1
546
547
def supersingular_j(FF):
548
r"""
549
This function returns a supersingular j-invariant over the finite
550
field FF.
551
552
INPUT:
553
554
- ``FF`` -- finite field with p^2 elements, where p is a prime number
555
556
OUTPUT:
557
finite field element -- a supersingular j-invariant
558
defined over the finite field FF
559
560
EXAMPLES:
561
562
The following examples calculate supersingular j-invariants for a
563
few finite fields::
564
565
sage: supersingular_j(GF(7^2, 'a'))
566
6
567
568
Observe that in this example the j-invariant is not defined over
569
the prime field::
570
571
sage: supersingular_j(GF(15073^2,'a')) # optional -- requires database
572
10630*a + 6033
573
574
sage: supersingular_j(GF(83401^2, 'a'))
575
67977
576
577
AUTHORS:
578
579
- David Kohel -- [email protected]
580
581
- Iftikhar Burhanuddin -- [email protected]
582
"""
583
if not(FF.is_field()) or not(FF.is_finite()):
584
raise ValueError, "%s is not a finite field"%FF
585
prime = FF.characteristic()
586
if not(rings.Integer(prime).is_prime()):
587
raise ValueError, "%s is not a prime"%prime
588
if not(rings.Integer(FF.cardinality())) == rings.Integer(prime**2):
589
raise ValueError, "%s is not a quadratic extension"%FF
590
if rings.kronecker(-1, prime) != 1:
591
j_invss = 1728 #(2^2 * 3)^3
592
elif rings.kronecker(-2, prime) != 1:
593
j_invss = 8000 #(2^2 * 5)^3
594
elif rings.kronecker(-3, prime) != 1:
595
j_invss = 0 #0^3
596
elif rings.kronecker(-7, prime) != 1:
597
j_invss = 16581375 #(3 * 5 * 17)^3
598
elif rings.kronecker(-11, prime) != 1:
599
j_invss = -32768 #-(2^5)^3
600
elif rings.kronecker(-19, prime) != 1:
601
j_invss = -884736 #-(2^5 * 3)^3
602
elif rings.kronecker(-43, prime) != 1:
603
j_invss = -884736000 #-(2^6 * 3 * 5)^3
604
elif rings.kronecker(-67, prime) != 1:
605
j_invss = -147197952000 #-(2^5 * 3 * 5 * 11)^3
606
elif rings.kronecker(-163, prime) != 1:
607
j_invss = -262537412640768000 #-(2^6 * 3 * 5 * 23 * 29)^3
608
else:
609
D = supersingular_D(prime)
610
DBCP = HilbertClassPolynomialDatabase()
611
hc_poly = FF['x'](DBCP[D])
612
root_hc_poly_list = list(hc_poly.roots())
613
614
j_invss = root_hc_poly_list[0][0]
615
return FF(j_invss)
616
617
class SupersingularModule(hecke.HeckeModule_free_module):
618
r"""
619
The module of supersingular points in a given characteristic, with
620
given level structure.
621
622
The characteristic must not divide the level.
623
624
NOTE: Currently, only level 1 is implemented.
625
626
EXAMPLES::
627
628
sage: S = SupersingularModule(17)
629
sage: S
630
Module of supersingular points on X_0(1)/F_17 over Integer Ring
631
sage: S = SupersingularModule(16)
632
Traceback (most recent call last):
633
...
634
ValueError: the argument prime must be a prime number
635
sage: S = SupersingularModule(prime=17, level=34)
636
Traceback (most recent call last):
637
...
638
ValueError: the argument level must be coprime to the argument prime
639
sage: S = SupersingularModule(prime=17, level=5)
640
Traceback (most recent call last):
641
...
642
NotImplementedError: supersingular modules of level > 1 not yet implemented
643
"""
644
def __init__(self, prime=2, level=1, base_ring=rings.IntegerRing()):
645
r"""
646
Create a supersingular module.
647
648
EXAMPLE::
649
650
sage: SupersingularModule(3)
651
Module of supersingular points on X_0(1)/F_3 over Integer Ring
652
"""
653
654
if not prime.is_prime():
655
raise ValueError, "the argument prime must be a prime number"
656
if prime.divides(level):
657
raise ValueError, "the argument level must be coprime to the argument prime"
658
if level != 1:
659
raise NotImplementedError, "supersingular modules of level > 1 not yet implemented"
660
self.__prime = prime
661
from sage.rings.all import FiniteField
662
self.__finite_field = FiniteField(prime**2,'a')
663
self.__level = level
664
self.__hecke_matrices = {}
665
hecke.HeckeModule_free_module.__init__(
666
self, base_ring, prime*level, weight=2)
667
668
def _repr_(self):
669
"""
670
String representation of self
671
672
EXAMPLES::
673
674
sage: SupersingularModule(11)._repr_()
675
'Module of supersingular points on X_0(1)/F_11 over Integer Ring'
676
"""
677
678
return "Module of supersingular points on X_0(%s)/F_%s over %s"%(
679
self.__level, self.__prime, self.base_ring())
680
681
def __cmp__(self, other):
682
r"""
683
Compare self to other.
684
685
EXAMPLES::
686
687
sage: SupersingularModule(37) == ModularForms(37, 2)
688
False
689
sage: SupersingularModule(37) == SupersingularModule(37, base_ring=Qp(7))
690
False
691
sage: SupersingularModule(37) == SupersingularModule(37)
692
True
693
"""
694
if not isinstance(other, SupersingularModule):
695
return cmp(type(self), type(other))
696
else:
697
return cmp( (self.__level, self.__prime, self.base_ring()), (other.__level, other.__prime, other.base_ring()))
698
699
def dimension(self):
700
r"""
701
Return the dimension of the space of modular forms of weight 2
702
and level equal to the level associated to self.
703
704
INPUT:
705
706
- ``self`` -- SupersingularModule object
707
708
OUTPUT:
709
integer -- dimension, nonnegative
710
711
EXAMPLES::
712
713
sage: S = SupersingularModule(7)
714
sage: S.dimension()
715
1
716
717
sage: S = SupersingularModule(15073)
718
sage: S.dimension()
719
1256
720
721
sage: S = SupersingularModule(83401)
722
sage: S.dimension()
723
6950
724
725
NOTES:
726
The case of level > 1 has not yet been implemented.
727
728
AUTHORS:
729
730
- David Kohel -- [email protected]
731
732
- Iftikhar Burhanuddin -- [email protected]
733
"""
734
try:
735
return self.__dimension
736
except:
737
pass
738
if self.__level == 1:
739
G = Gamma0(self.__prime)
740
self.__dimension = G.dimension_modular_forms(2)
741
else:
742
raise NotImplementedError
743
return self.__dimension
744
745
rank = dimension
746
747
def level(self):
748
r"""
749
This function returns the level associated to self.
750
751
INPUT:
752
753
- ``self`` -- SupersingularModule object
754
755
OUTPUT:
756
integer -- the level, positive
757
758
EXAMPLES::
759
760
sage: S = SupersingularModule(15073)
761
sage: S.level()
762
1
763
764
AUTHORS:
765
766
- David Kohel -- [email protected]
767
768
- Iftikhar Burhanuddin -- [email protected]
769
"""
770
return self.__level
771
772
def prime(self):
773
r"""
774
This function returns the characteristic of the finite field
775
associated to self.
776
777
INPUT:
778
779
- ``self`` -- SupersingularModule object
780
781
OUTPUT:
782
783
- integer -- characteristic, positive
784
785
EXAMPLES::
786
787
sage: S = SupersingularModule(19)
788
sage: S.prime()
789
19
790
791
AUTHORS:
792
793
- David Kohel -- [email protected]
794
795
- Iftikhar Burhanuddin -- [email protected]
796
"""
797
return self.__prime
798
799
def weight(self):
800
r"""
801
This function returns the weight associated to self.
802
803
INPUT:
804
805
- ``self`` -- SupersingularModule object
806
807
OUTPUT:
808
integer -- weight, positive
809
810
EXAMPLES::
811
812
sage: S = SupersingularModule(19)
813
sage: S.weight()
814
2
815
816
AUTHORS:
817
818
- David Kohel -- [email protected]
819
820
- Iftikhar Burhanuddin -- [email protected]
821
"""
822
return 2
823
824
def supersingular_points(self):
825
r"""
826
This function computes the supersingular j-invariants over the
827
finite field associated to self.
828
829
INPUT:
830
831
- ``self`` -- SupersingularModule object
832
833
OUTPUT: list_j, dict_j -- list_j is the list of supersingular
834
j-invariants, dict_j is a dictionary with these
835
j-invariants as keys and their indexes as values. The
836
latter is used to speed up j-invariant look-up. The
837
indexes are based on the order of their *discovery*.
838
839
EXAMPLES:
840
841
The following examples calculate supersingular j-invariants
842
over finite fields with characteristic 7, 11 and 37::
843
844
sage: S = SupersingularModule(7)
845
sage: S.supersingular_points()
846
([6], {6: 0})
847
848
sage: S = SupersingularModule(11)
849
sage: S.supersingular_points()
850
([1, 0], {0: 1, 1: 0})
851
852
sage: S = SupersingularModule(37)
853
sage: S.supersingular_points()
854
([8, 27*a + 23, 10*a + 20], {8: 0, 10*a + 20: 2, 27*a + 23: 1})
855
856
AUTHORS:
857
858
- David Kohel -- [email protected]
859
860
- Iftikhar Burhanuddin -- [email protected]
861
"""
862
try:
863
return (self._ss_points_dic, self._ss_points)
864
except:
865
pass
866
Fp2 = self.__finite_field
867
level = self.__level
868
prime = Fp2.characteristic()
869
X = Fp2['x'].gen()
870
jinv = supersingular_j(Fp2)
871
872
dim = dimension_supersingular_module(prime, level)
873
874
pos = int(0)
875
#using list to keep track of explored nodes using pos
876
ss_points = [jinv]
877
878
#using to keep track of index of the previous node
879
ss_points_pre = [-1]
880
881
#using dictionary for fast j-invariant look-up
882
ss_points_dic = {jinv:pos}
883
884
T2_matrix = MatrixSpace(rings.Integers(), dim, sparse=True)(0)
885
886
while pos < len(ss_points):
887
if pos == 0:
888
neighbors = Phi_polys(2,X,ss_points[pos]).roots()
889
else:
890
j_prev = ss_points_pre[pos]
891
# TODO: These are quadratic polynomials -- maybe we should use the
892
# quadratic formula and fast square root finding (??)
893
neighbors = Phi2_quad(X, ss_points[j_prev], ss_points[pos]).roots()
894
895
for (xj,ej) in neighbors:
896
if not ss_points_dic.has_key(xj):
897
j = len(ss_points)
898
ss_points += [xj]
899
ss_points_pre += [pos]
900
ss_points_dic[xj] = j
901
else:
902
j = ss_points_dic[xj]
903
T2_matrix[pos, j] += ej
904
# end for
905
if pos != 0:
906
# also record the root from j_prev
907
T2_matrix[pos, j_prev] += 1
908
pos += int(1)
909
910
self.__hecke_matrices[2] = T2_matrix
911
return (ss_points, ss_points_dic)
912
913
914
def upper_bound_on_elliptic_factors(self, p=None, ellmax=2):
915
r"""
916
Return an upper bound (provably correct) on the number of
917
elliptic curves of conductor equal to the level of this
918
supersingular module.
919
920
INPUT:
921
922
- ``p`` - (default: 997) prime to work modulo
923
924
ALGORITHM: Currently we only use `T_2`. Function will be
925
extended to use more Hecke operators later.
926
927
The prime p is replaced by the smallest prime that doesn't
928
divide the level.
929
930
EXAMPLE::
931
932
sage: SupersingularModule(37).upper_bound_on_elliptic_factors()
933
2
934
935
(There are 4 elliptic curves of conductor 37, but only 2 isogeny
936
classes.)
937
"""
938
# NOTE: The heuristic runtime is *very* roughly `p^2/(2\cdot 10^6)`.
939
#ellmax -- (default: 2) use Hecke operators T_ell with ell <= ellmax
940
if p is None:
941
p = 997
942
943
while self.level() % p == 0:
944
p = rings.next_prime(p)
945
946
ell = 2
947
t = self.hecke_matrix(ell).change_ring(rings.GF(p))
948
949
# TODO: temporarily try using sparse=False
950
# turn this off when sparse rank is optimized.
951
t = t.dense_matrix()
952
953
B = 2*math.sqrt(ell)
954
bnd = 0
955
lower = -int(math.floor(B))
956
upper = int(math.floor(B))+1
957
for a in range(lower, upper):
958
tm = verbose("computing T_%s - %s"%(ell, a))
959
if a == lower:
960
c = a
961
else:
962
c = 1
963
for i in range(t.nrows()):
964
t[i,i] += c
965
tm = verbose("computing kernel",tm)
966
#dim = t.kernel().dimension()
967
dim = t.nrows() - t.rank()
968
bnd += dim
969
verbose('got dimension = %s; new bound = %s'%(dim, bnd), tm)
970
return bnd
971
972
def hecke_matrix(self,L):
973
r"""
974
This function returns the `L^{\text{th}}` Hecke matrix.
975
976
INPUT:
977
978
- ``self`` -- SupersingularModule object
979
980
- ``L`` -- integer, positive
981
982
OUTPUT:
983
matrix -- sparse integer matrix
984
985
EXAMPLES:
986
This example computes the action of the Hecke operator `T_2`
987
on the module of supersingular points on `X_0(1)/F_{37}`::
988
989
sage: S = SupersingularModule(37)
990
sage: M = S.hecke_matrix(2)
991
sage: M
992
[1 1 1]
993
[1 0 2]
994
[1 2 0]
995
996
This example computes the action of the Hecke operator `T_3`
997
on the module of supersingular points on `X_0(1)/F_{67}`::
998
999
sage: S = SupersingularModule(67)
1000
sage: M = S.hecke_matrix(3)
1001
sage: M
1002
[0 0 0 0 2 2]
1003
[0 0 1 1 1 1]
1004
[0 1 0 2 0 1]
1005
[0 1 2 0 1 0]
1006
[1 1 0 1 0 1]
1007
[1 1 1 0 1 0]
1008
1009
.. note::
1010
1011
The first list --- list_j --- returned by the supersingular_points
1012
function are the rows *and* column indexes of the above hecke
1013
matrices and its ordering should be kept in mind when interpreting
1014
these matrices.
1015
1016
AUTHORS:
1017
1018
- David Kohel -- [email protected]
1019
1020
- Iftikhar Burhanuddin -- [email protected]
1021
"""
1022
if self.__hecke_matrices.has_key(L):
1023
return self.__hecke_matrices[L]
1024
SS, II = self.supersingular_points()
1025
if L == 2:
1026
# since T_2 gets computed as a side effect of computing the supersingular points
1027
return self.__hecke_matrices[2]
1028
Fp2 = self.__finite_field
1029
h = len(SS)
1030
R = self.base_ring()
1031
T_L = MatrixSpace(R,h)(0)
1032
S, X = Fp2['x'].objgen()
1033
1034
if L in [3,5,7,11]:
1035
for i in range(len(SS)):
1036
ss_i = SS[i]
1037
phi_L_in_x = Phi_polys(L, X, ss_i)
1038
rts = phi_L_in_x.roots()
1039
for r in rts:
1040
T_L[i,int(II[r[0]])] = r[1]
1041
else:
1042
DBMP = ClassicalModularPolynomialDatabase()
1043
phi_L = DBMP[L]
1044
M, (x,y) =Fp2['x,y'].objgens()
1045
phi_L = phi_L(x,y)
1046
1047
# As an optimization, we compute the coefficients of y and evaluate
1048
# them, since univariate polynomial evaluation is much faster than
1049
# multivariate evaluation (in Sage :-( ).
1050
uni_coeff = [phi_L(x,0).univariate_polynomial()] + \
1051
[phi_L.coefficient(y**i).univariate_polynomial() for
1052
i in range(1,phi_L.degree(y)+1)]
1053
for i in range(len(SS)):
1054
ss_i = SS[i]
1055
## We would do the eval below, but it is too slow (right now).
1056
#phi_L_in_x = phi_L(X, ss_i)
1057
1058
phi_L_in_x = S([f(ss_i) for f in uni_coeff])
1059
rts = phi_L_in_x.roots()
1060
for r in rts:
1061
T_L[i,int(II[r[0]])] = r[1]
1062
1063
self.__hecke_matrices[L] = T_L
1064
return T_L
1065
1066