Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
AndrewVSutherland
GitHub Repository: AndrewVSutherland/lmfdb
Path: blob/main/scripts/hmf/WebHMF.py
1448 views
1
import math
2
import logging
3
import re
4
from lmfdb.utils import pair2complex, splitcoeff
5
6
class WebHMF:
7
"""Class for presenting a Hilbert modular form on a web page
8
9
"""
10
11
def __init__(self, dict):
12
self.type = dict['type']
13
self.coefficient_period = 0
14
self.poles = []
15
self.residues = []
16
self.kappa_fe = []
17
self.lambda_fe = []
18
self.mu_fe = []
19
self.nu_fe = []
20
self.langlands = True
21
22
if self.type == 'lcalcurl':
23
from six.moves.urllib.request import urlopen
24
self.url = dict['url']
25
self.contents = urlopen(self.url).read()
26
self.parseLcalcfile_ver1()
27
28
elif self.type == 'lcalcfile':
29
self.contents = dict['filecontents']
30
self.parseLcalcfile_ver1()
31
32
elif self.type == 'modularform':
33
self.level = dict['level']
34
self.weight = dict['weight']
35
logging.info('My level is ' + self.level + ' and my weight is' + self.weight)
36
37
else:
38
raise KeyError
39
40
"""
41
self.coefficient_type: 1 = integer, 2 = double, 3 = complex
42
self.ceofficient_period: 0 = non-periodic
43
self.sageLfunction = lc.Lfunction_C(self.title, self.coefficient_type, self.dirichlet_coefficients, self.ceofficient_period, self.Q_fe, self.sign , self.kappa_fe, self.lambda_fe ,self.poles, self.residues)
44
"""
45
46
def parseLcalcfile_ver1(self):
47
lines = self.contents.split('\n', 6)
48
self.coefficient_type = int(lines[0])
49
self.quasidegree = int(lines[4])
50
lines = self.contents.split('\n', 8 + 2 * self.quasidegree)
51
self.Q_fe = float(lines[5 + 2 * self.quasidegree])
52
self.sign = pair2complex(lines[6 + 2 * self.quasidegree])
53
54
for i in range(self.quasidegree):
55
localdegree = float(lines[5 + 2 * i])
56
self.kappa_fe.append(localdegree)
57
locallambda = pair2complex(lines[6 + 2 * i])
58
self.lambda_fe.append(locallambda)
59
if math.fabs(localdegree - 0.5) < 0.00001:
60
self.mu_fe.append(2 * locallambda)
61
elif math.fabs(localdegree - 1) < 0.00001:
62
self.nu_fe.append(locallambda)
63
else:
64
self.nu_fe.append(locallambda)
65
self.langlands = False
66
67
""" Do poles here later
68
"""
69
70
self.degree = round(2 * sum(self.kappa_fe))
71
self.level = round(math.pi ** self.degree * 4 ** len(self.nu_fe) * self.Q_fe ** 2)
72
73
self.dirichlet_coefficients = splitcoeff(lines[-1])
74
75
originalfile = re.match(".*/([^/]+)$", self.url)
76
originalfile = originalfile.group(1)
77
# self.title = "An L-function generated by an Lcalc file: "
78
self.title = "An L-function generated by an Lcalc file: " + originalfile
79
self.credit = "David Farmer, Sally Koutsoliotas and Stefan Lemurell"
80
81
82
## Sep 2018, really no longer used
83
## July 2015. no longer used. delete later
84
## def lfuncDStex(self, fmt):
85
## numperline = 5
86
## numcoeffs = 10
87
## ans = ""
88
## if fmt == "analytic":
89
## ans = "\\begin{align}\n"
90
## ans = ans + latex(self.dirichlet_coefficients[0]) + "\\mathstrut&"
91
## for n in range(1, numcoeffs):
92
## ans = ans + seriescoeff(self.dirichlet_coefficients[n], n + 1, "dirichlet", 0.000000001)
93
## if(n % numperline == 0):
94
## ans = ans + "\\cr\n"
95
## ans = ans + "&"
96
## ans = ans + "\\cdots\n\\end{align}"
97
## return(ans)
98
#
99
##===========================
100
# def lfuncFEtex(self, fmt):
101
# ans = ""
102
# if fmt == "lang":
103
# ans = "\\begin{align}\n\\Lambda(s)=&"
104
# ans = ans + latex(self.level) + "^{-\\frac{s}{2}}"
105
# for mu in self.mu_fe:
106
# ans = ans + "\Gamma_{\mathbb{R}}(s+" + latex(mu) + ")"
107
# for nu in self.nu_fe:
108
# ans = ans + "\Gamma_{\mathbb{C}}(s+" + latex(nu) + ")"
109
# ans = ans + "\\cdot L(s)\\cr\n"
110
# ans = ans + "=\\mathstrut & " + latex(self.sign) +\
111
# "\\overline{\\Lambda(1-\\overline{s})}\n\\end{align}\n"
112
# return(ans)
113
114
#===========================
115
def lfuncFEtex(self, fmt):
116
ans = ""
117
if fmt == "lang":
118
ans = "\\begin{aligned}\n\\Lambda(s)=&"
119
ans = ans + latex(self.level) + "^{-\\frac{s}{2}}"
120
for mu in self.mu_fe:
121
ans = ans + r"\Gamma_{\mathbb{R}}(s+" + latex(mu) + ")"
122
for nu in self.nu_fe:
123
ans = ans + r"\Gamma_{\mathbb{C}}(s+" + latex(nu) + ")"
124
ans = ans + "\\cdot L(s)\\cr\n"
125
ans = ans + "=\\mathstrut & " + latex(self.sign) +\
126
"\\overline{\\Lambda(1-\\overline{s})}\n\\end{aligned}\n"
127
return(ans)
128
129
130
def latex(thetext):
131
return str(thetext)
132
133
134
def seriescoeff(coeff, index, seriestype, truncation):
135
rp = real_part(coeff)
136
ip = imag_part(coeff)
137
# below we use float(abs()) instead of abs() to avoid a sage bug
138
if (float(abs(rp)) > truncation) & (float(abs(ip)) > truncation):
139
return("+(" + latex(coeff) + ")" + seriesvar(index, seriestype))
140
elif (float(abs(rp)) < truncation) & (float(abs(ip)) < truncation):
141
return("")
142
# if we get this far, either pure real or pure imaginary
143
if rp > truncation:
144
if float(abs(rp - 1)) < truncation:
145
return("+" + seriesvar(index, seriestype))
146
else:
147
return("+" + latex(rp) + seriesvar(index, seriestype))
148
elif float(abs(rp + 1)) < truncation:
149
return("-" + seriesvar(index, seriestype))
150
elif ip > truncation:
151
if float(abs(ip - 1)) < truncation:
152
return("+" + seriesvar(index, seriestype))
153
else:
154
return("+" + latex(ip) + seriesvar(index, seriestype))
155
elif float(abs(ip + 1)) < truncation:
156
return("-" + seriesvar(index, seriestype))
157
else:
158
return(latex(coeff) + seriesvar(index, seriestype))
159
160
#---------
161
162
163
def seriesvar(index, seriestype):
164
if seriestype == "dirichlet":
165
return(" \\ " + str(index) + "^{-s}")
166
else:
167
return("\\, " + "q^{" + str(index) + "}")
168
169
170
def real_part(pair):
171
return pair[0]
172
173
174
def imag_part(pair):
175
return pair[1]
176
177