CoCalc Shared Fileswww / cgi-bin / mfd / mfe_full.pyOpen in CoCalc with one click!
Author: William A. Stein
1
# mfe_full.py
2
# (c) William Stein, 2000
3
4
import cgi # cgi-bin
5
import Documents, HTML
6
7
import misc
8
import constants
9
import mfd # modular forms database
10
import mfe_misc, mfe_data_table, mfe_glossary
11
12
import pari
13
14
import os, string
15
16
too_long = 6 # stuff longer than this is centered
17
18
def is_valid(form):
19
if form.has_key("level_weight"):
20
x = mfe_misc.parse_level_weight(form["level_weight"].value)
21
if x[0] == 0:
22
return [0]
23
level = x[1]
24
weight = x[2]
25
elif form.has_key("level") and form.has_key("weight"):
26
level = string.replace(form["level"].value," ","")
27
weight = string.replace(form["weight"].value, " ","")
28
else:
29
return [0]
30
if not (misc.is_nonnegative_number(level) and misc.is_nonnegative_number(weight)):
31
return [0]
32
if len(level) > 9 or int(level) < 1:
33
return [0]
34
if len(weight) > 9 or int(weight) < 2:
35
return [0]
36
return [1, level, weight]
37
38
def factor_level(N):
39
f = pari.pari("factor(%s)"%N)
40
if f[0]=='M':
41
f=f[4:-1]
42
if f[0]=='m':
43
s="%s"%N
44
else:
45
f = string.replace(f,"[","")
46
f = string.replace(f,"]","")
47
f = string.replace(f," ","")
48
is_first = 1
49
s = ""
50
for a in string.split(f,";"):
51
b = string.split(a,",")
52
if not is_first:
53
s = s + "*"
54
s = s + "%s"%b[0]
55
if b[1]!="1":
56
s = s + "<sup>%s</sup>"%b[1]
57
is_first = 0
58
return s
59
60
61
def character_selector(N,k,eps):
62
if not mfd.characters_are_known(N):
63
return ["Trivial Character", 1]
64
if k % 2 == 1:
65
parity = -1
66
else:
67
parity = +1
68
chars = mfd.characters(N)
69
s = '<SELECT name="character">';
70
selected = 0
71
our_order=1
72
for chi in chars:
73
if chi['parity'] == parity:
74
if chi['label'] == eps:
75
s = s+'<OPTION selected '
76
selected = 1
77
our_order = chi['degree']
78
else:
79
s = s+'<OPTION '
80
if chi['label'] == '1':
81
s = s+' value="1:1">Trivial character</option>'
82
else:
83
s = s + ' value="%s:%s"> Conductor %s and Order %s, &nbsp&nbsp %s </OPTION>'%(chi['label'],chi['modulus'],chi['conductor'],chi['degree'],chi['label']);
84
if not selected:
85
s = s + '<OPTION selected value="%s:%s"> %s </OPTION>'%(eps,N,eps)
86
s = s + '</SELECT>'
87
return [s,our_order]
88
89
def charpoly_links(M):
90
known = M.known_charpolys()
91
if len(known) == 0:
92
return ""
93
ans = ""
94
for n in known:
95
url = '<a href="%s/mfe_charpoly.py?code=%s&n=%s">%s</a>'%(constants.CGIROOT,M.code(),n,n)
96
ans = ans + url + "&nbsp "
97
return ans
98
99
def eigenvalue_links(M):
100
known = M.known_ap()
101
if len(known) == 0 or M.number > 1:
102
return ""
103
ans = ""
104
for n in known:
105
#if n < 100:
106
url = '<a href="%s/mfe_ap.py?code=%s&n=%s">%s</a>'%(constants.CGIROOT,M.code(),n,n)
107
ans = ans + url + "&nbsp "
108
ans = ans
109
return ans
110
111
112
def trace_links(M):
113
known = M.known_trace_ap()
114
return "%s, %s, %s, %s"%(M.trace_ap(2),M.trace_ap(3),M.trace_ap(5),M.trace_ap(7))
115
116
def slope_links(M):
117
primes = M.known_slopes()
118
if len(primes) == 0:
119
return ""
120
ans = "Click for slopes: "
121
for p in primes:
122
url = '<a href="%s/mfe_slopes.py?code=%s&prime=%s">%s</a>'%(constants.CGIROOT,M.code(),p,p)
123
ans = ans + url
124
if p != primes[len(primes)-1]:
125
ans = ans + ", "
126
return ans
127
128
def lratio_links(M):
129
if M.weight == 2:
130
return M.lratio_k2()
131
lratio = M.lratio()
132
ans=""
133
if lratio != constants.not_computed:
134
r = range(1,len(lratio)+1) + ['all']
135
for j in r:
136
url = '<a href="%s/mfe_lratio.py?code=%s&j=%s">L(%s)</a>'%(constants.CGIROOT,M.code(),j,j)
137
ans = ans + url + "&nbsp "
138
return ans
139
140
def lratio_odd_links(M):
141
if M.weight == 2:
142
return M.lratio_odd_k2()
143
lratio_odd = M.lratio_odd()
144
ans=""
145
if lratio_odd != constants.not_computed:
146
r = range(1,len(lratio_odd)+1) + ['all']
147
for j in r:
148
url = '<a href="%s/mfe_lratio_odd.py?code=%s&j=%s">L(%s)</a>'%(constants.CGIROOT,M.code(),j,j)
149
ans = ans + url + "&nbsp "
150
return ans
151
152
def level_weight_character_selector(N,k,eps):
153
s= '<form action=%s/mfe_full_html.py method="get">'%constants.CGIROOT
154
s=s+'<input type="hidden" name="level_fallback" value="%s">\n'%N
155
s=s+'<input type="hidden" name="weight_fallback" value="%s">\n'%k
156
s=s+'<input type="hidden" name="level" value="%s">\n'%N
157
s=s+'<input type="hidden" name="weight" value="%s">\n'%k
158
s=s+'<input type="hidden" name="iso_class" value="0">\n'
159
s=s+'<input type="submit" value="Change space to ">\n'
160
s=s+'<input type="text" name="level_weight" value="%s,%s">\n'%(N,k)
161
x = character_selector(N,k,eps)
162
s=s + x[0]
163
s=s+ ' </form>'
164
return [s, x[1]] # returns string and order of character, since character_select computes order of character.
165
166
167
def browser(N,k):
168
s = '<a href="%s/mfe_known_html.py?level_weight=%s,%s&table=ap_data"> '%\
169
(constants.CGIROOT, N, k) + \
170
'Open Graphical Browser</a>'
171
return s
172
173
def is_complete(M, order_of_eps):
174
phi_of_order_of_eps = int(pari.eulerphi(order_of_eps))
175
dim = M.dimension_new() * phi_of_order_of_eps
176
d = 0
177
for f in M.get_iso_classes():
178
if f.dimension() == constants.not_computed:
179
return 0
180
d = d + f.dimension()
181
return d == dim
182
183
def table_newforms(N,k,eps, order_of_eps):
184
M = mfd.ModSym(N,k,0,eps)
185
iso = mfd.iso_class_data(N,k,eps)
186
ans = ""
187
if M.dimension_new() == constants.not_computed:
188
ans = "WARNING: Some newforms <b>might be</b> missing."
189
elif not is_complete(M, order_of_eps):
190
ans = "WARNING: Some newforms <b>are definitely missing</b>... (or?)"
191
192
if ans=="" and len(iso) == 0:
193
ans = "No newforms of this level, weight, and character"
194
195
if ans != "":
196
ans='<br><center><table bgcolor=white cellpadding=10 border=2><tr><td>' + ans + '</td></tr></table></center><br>'
197
198
if len(iso) != 0:
199
color = constants.TABLE_HEADING_COLOR
200
ans = ans + '<table border=0 cellpadding=4 cellspacing=2 bgcolor=%s><tr>'%constants.TABLE_BORDER_COLOR
201
ans = ans+'<td bgcolor="%s" align=center><b>Label (id)</b>&nbsp</td>'%color+\
202
'<td bgcolor="%s" align=center><b>Eigenvalue Field</b></td>'%color+\
203
'<td bgcolor="%s" align=center><b>q-Expansions</b></td>'%color+\
204
'<td bgcolor="%s" align=center><b>Traces of a<sub>p</sub> for p=2,3,5,7</b></td>'%color+\
205
'</tr>'
206
207
for i in range(0,len(iso)):
208
f = mfd.ModSym(N,k,iso[i]['iso_class'],eps,'Q',iso[i]['number'])
209
code = f.code()
210
211
################
212
url = constants.CGIROOT + "/mfe_newfactor.py?code=%s"%code
213
label_button = '<a href="%s">%s</a><font size=1>(%s)</font>'%(url,code,f.id)
214
if k == 2 and eps == '1' and f.dimension() == 1:
215
cremona_label = misc.stein_to_cremona(N, f.iso_class)
216
if cremona_label[1] != f.iso_class:
217
label_button = label_button + "<br>(%s%s in [Cremona])"%\
218
(N,misc.ToIsogenyCode(cremona_label[1]))
219
220
221
################
222
#if f.aplist_maxp() != constants.not_computed or \
223
# f.traces() != constants.not_computed:
224
# if f.traces() != constants.not_computed:
225
# s = "%s"%f.traces()
226
# s = string.replace(s," ","")
227
# s = string.replace(s,"'","")
228
# s = string.replace(s,"[","")
229
# s = string.replace(s,"]","")
230
# s = s[:15+string.find(s[15:],",")] + ", ..."
231
# else:
232
# s = "q-Expansions"
233
#else:
234
# s = "unknown"
235
s = "<center>Click</center>"
236
url = constants.CGIROOT + '/mfe_eigenvalues.py?code=%s'%code
237
aplist_button = '<a href="%s">%s</a>'%(url,s)
238
239
################
240
if f.hecke_field() != constants.not_computed:
241
field = f.hecke_field()
242
field = string.replace(field, " ","")
243
field = string.replace(field, "+", "+")
244
field = string.replace(field, "-", "-")
245
n = 9
246
if len(field)>n:
247
m = min(string.find(field[n-5:],"+"), string.find(field[n-5:],"-")) + 2
248
field=field[:n-5+m] + "..."
249
else:
250
field = "unknown"
251
url = constants.CGIROOT + "/mfe_hecke_field.py?code=%s"%code
252
field_button = '<a href="%s">%s</a>'%(url,field)
253
254
#charpoly_button = charpoly_links(f)
255
traces_button = "%s"%trace_links(f)
256
257
258
td = '<td align=center bgcolor="%s">'%constants.TABLE_BGCOLOR
259
ans = ans + "<tr>%s%s</td>%s%s</td>%s%s</td>%s%s</td></tr>"%\
260
(td,label_button, td,field_button, td,aplist_button, td, traces_button)
261
ans = ans + "</table>"
262
ans = "<table border=1><tr><td>" + ans + "</td></tr></table>"
263
return ans
264
265
266
def miscellaneous_rows(M):
267
ans = []
268
for m in M.miscellaneous():
269
field = m['field']
270
data = m['data']
271
notes = m['notes']
272
if str(notes) == "None":
273
notes =""
274
source = m['source']
275
if str(source) == "None":
276
source ="NA"
277
ans.append([M, field, "", data, notes, source])
278
return ans
279
280
def order_with_character(M,order_of_eps):
281
if order_of_eps == 1:
282
return [M,"Dimension of space spanned by forms with character a conjugate of eps.", "dimension", \
283
M.dimension(), "","", 0]
284
phi_of_order_of_eps = int(pari.eulerphi(order_of_eps))
285
return [M,"Dimension of space spanned by forms with character a conjugate of eps.", "dimension", \
286
str(phi_of_order_of_eps*M.dimension()), "","", 1]
287
288
def fullspace_with_char_table(N,k,eps, order_of_eps):
289
M = mfd.ModSym(N,k,0,eps,'Q')
290
table = [\
291
[M,"Dimension (over C)", "dimension", str(M.dimension()), "", ""]\
292
,order_with_character(M,order_of_eps)\
293
#,[M,"Characteristic polynomials", "charpoly", charpoly_links(M),"<center>Get charpoly of T<sub>p</sub></center>","NA"]\
294
,[M,"Dimension of new subspace", "dimension_new", str(M.dimension_new()), "", ""]\
295
,[M,"Cuspidal subgroup", "cuspidal_subgroup", str(M.cuspidal_subgroup()),"", ""]\
296
,[M,"Cusps on modular curve", "cusps", str(M.cusps()),"",""]\
297
,[M,"Discriminant (of Hecke algebra)", "discriminant", str(M.discriminant()), "", ""]\
298
,[M,"Discriminant (factored)", "discriminant", str(M.discriminant_factored()), "", ""]\
299
,[M,"Equation for Modular Curve", "equation", str(M.equation()),"", ""]\
300
,[M,"Rank of Mordell-Weil group", "mwrank", str(M.mwrank()), "", ""]\
301
,[M,"Mordell-Weil group generators", "mw_generators",str(M.mw_generators()),"",""]\
302
,[M,"Regulator of Mordell-Weil group", "regulator", str(M.regulator()),"", ""]\
303
,[M,"Leading coefficient", "leading_coefficient", str(M.leading_coefficient()), "... of expansion of L-series about s=1.",""]\
304
,[M,"Real volume", "real_volume", str(M.real_volume()), "Omega in the BSD conjecture, up to a Manin constant", ""]\
305
,[M,"Anomalous j-invariants in characteristic %s"%N, "anomalous_j_invariants", str(M.anomalous_j_invariants()), "", ""]\
306
,[M,"Torsion subgroup", "torsion_subgroup",str(M.torsion_subgroup()), "", ""]\
307
,[M,"Torsion subgroup size", "torsion_size", str(M.torsion_size()), "", "torsion_subgroup"]\
308
,[M,"Torsion subgroup size (upper bound)", "torsion_upper_bound", str(M.torsion_upper_bound()), "Multiple of order of torsion subgroup", "torsion_subgroup"]\
309
,[M,"Torsion subgroup size (odd part of upper bound)", "torsion_odd_upper_bound",str(M.torsion_odd_upper_bound()), "", ""]\
310
,[M,"Torsion subgroup size (lower bound)", "torsion_lower_bound", str(M.torsion_lower_bound()), "", "torsion_subgroup"]\
311
,[M,"Tamagawa numbers", "tamagawa_numbers", str(M.tamagawa_numbers()), "the c<sub>p</sub> in BSD conjecture", ""]\
312
,[M,"Tamagawa numbers (odd parts)", "tamagawa_numbers_odd",str(M.tamagawa_numbers_odd()), "(0 means not yet computed)", ""]\
313
,[M,"Slopes of T<sub>p</sub>", "slopes", slope_links(M), "p-adic slopes of Newton polygon", ""]\
314
,[M,"L-ratios L(A,i)/Omega_i for i=1,...,k-1", "lratio", lratio_links(M), "", "", M.weight > 2]\
315
,[M,"L-ratio L(A,1)/Omega", "lratio_k2", str(M.lratio_k2()), "", "lratio", M.weight == 2]\
316
,[M,"L-ratios L(A,i)/Omega_i for i=1,...,k-1 (odd parts)", "lratio_odd", lratio_odd_links(M), "", "", M.weight > 2]\
317
,[M,"L-ratio L(A,1)/Omega (odd parts)", "lratio_odd_k2", str(M.lratio_odd_k2()), "", "lratio_odd", M.weight == 2]\
318
,[M,"Shafarevich-Tate group (analytic order)", "sha_an", str(M.sha_an()), "", ""]\
319
,[M,"Shafarevich-Tate group (odd part of analytic order)", "sha_an_odd", str(M.sha_an_odd()), "", ""]\
320
,[M,"Shafarevich-Tate group (upper bound on odd part of analytic order)", "sha_an_odd_upper_bound", str(M.sha_an_odd_upper_bound()), "", "sha_an_odd"]\
321
,[M,"Shafarevich-Tate group (lower bound on odd part of analytic order)", "sha_an_odd_lower_bound", str(M.sha_an_odd_lower_bound()), "", "sha_an_odd"]\
322
,[M,"Notes", "notes",str(M.notes()),"", ""]\
323
]
324
misc = miscellaneous_rows(M)
325
return table + misc
326
327
def parity(x):
328
if x % 2 == 1:
329
return -1
330
return 1
331
332
def fullspace_table(N,k,eps, order_of_eps):
333
s = "<h2>Newforms / Abelian Variety Table</h2>\n"
334
s = s+table_newforms(N,k,eps, order_of_eps)
335
s = s+"<hr><h2>Information About Full Space</h2>\n"
336
table = fullspace_with_char_table(N,k,eps,order_of_eps)
337
table = mfe_data_table.Generate_Data_Table(table)
338
table = mfe_glossary.Glossarize(table)
339
s = s + table
340
return s
341
342
def contact_info():
343
return "<font size=2> If something is missing or incorrect, "+\
344
"send an email to William Stein at "+\
345
'<a href="mailto:[email protected]">[email protected]</a>.</font>'
346
347
def html_space(N, k, eps, error_msg):
348
title="Level %s and Weight %s\n"%(N,k)
349
link ='<link rel=stylesheet type="text/css" href="/mfd/mfd.css", title="was">'
350
s="<html><head><title>The Modular Forms Explorer: %s</title>\n%s\n</head>\n"\
351
%(title,link)
352
s=s+"<body class=top>\n"
353
s=s+'<center>\n'
354
s=s+'<h1><a href="/mfd/mfe/">The Modular Forms Explorer</a></h1>'
355
s=s+error_msg
356
s=s+'<h2>%s</h2>\n'%title
357
fac = factor_level(N)
358
if fac == str(N):
359
s = s + "Prime Level<br>"
360
else:
361
s=s+str(N)+" = "+factor_level(N)+"<br>\n"
362
s=s+'<hr>\n'
363
x = level_weight_character_selector(N,k,eps)
364
order_of_eps = x[1]
365
s=s+x[0] + '\n'
366
s=s+browser(N,k)+"\n<br>"
367
s=s+"<hr>\n"
368
s=s+fullspace_table(N,k,eps, order_of_eps)
369
s=s+"<hr></center>\n"
370
s=s+contact_info()
371
372
return s
373
374