passagemath-lcalc 10.6.31rc1__cp311-cp311-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-lcalc might be problematic. Click here for more details.
- passagemath_lcalc-10.6.31rc1.dist-info/METADATA +92 -0
- passagemath_lcalc-10.6.31rc1.dist-info/RECORD +19 -0
- passagemath_lcalc-10.6.31rc1.dist-info/WHEEL +6 -0
- passagemath_lcalc-10.6.31rc1.dist-info/top_level.txt +2 -0
- passagemath_lcalc.dylibs/libLfunction.2.0.0.dylib +0 -0
- passagemath_lcalc.dylibs/libgf2x.3.dylib +0 -0
- passagemath_lcalc.dylibs/libgmp.10.dylib +0 -0
- passagemath_lcalc.dylibs/libmpfr.6.dylib +0 -0
- passagemath_lcalc.dylibs/libntl.44.dylib +0 -0
- passagemath_lcalc.dylibs/libpari-gmp-tls.dylib +0 -0
- sage/all__sagemath_lcalc.py +2 -0
- sage/lfunctions/all__sagemath_lcalc.py +7 -0
- sage/lfunctions/lcalc.py +413 -0
- sage/libs/all__sagemath_lcalc.py +1 -0
- sage/libs/lcalc/__init__.py +1 -0
- sage/libs/lcalc/lcalc_Lfunction.cpython-311-darwin.so +0 -0
- sage/libs/lcalc/lcalc_Lfunction.pxd +129 -0
- sage/libs/lcalc/lcalc_Lfunction.pyx +982 -0
- sage/libs/lcalc/lcalc_sage.h +66 -0
|
@@ -0,0 +1,982 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-lcalc
|
|
2
|
+
# distutils: libraries = M_LIBRARIES NTL_LIBRARIES Lfunction
|
|
3
|
+
# distutils: extra_compile_args = NTL_CFLAGS -O3 -ffast-math
|
|
4
|
+
# distutils: include_dirs = NTL_INCDIR
|
|
5
|
+
# distutils: library_dirs = NTL_LIBDIR
|
|
6
|
+
# distutils: extra_link_args = NTL_LIBEXTRA
|
|
7
|
+
# distutils: language = c++
|
|
8
|
+
r"""
|
|
9
|
+
Rubinstein's lcalc library
|
|
10
|
+
|
|
11
|
+
This is a wrapper around Michael Rubinstein's lcalc.
|
|
12
|
+
See http://oto.math.uwaterloo.ca/~mrubinst/L_function_public/CODE/.
|
|
13
|
+
|
|
14
|
+
AUTHORS:
|
|
15
|
+
|
|
16
|
+
- Rishikesh (2010): added compute_rank() and hardy_z_function()
|
|
17
|
+
- Yann Laigle-Chapuy (2009): refactored
|
|
18
|
+
- Rishikesh (2009): initial version
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# ****************************************************************************
|
|
22
|
+
# Copyright (C) 2009 William Stein <wstein@gmail.com>
|
|
23
|
+
#
|
|
24
|
+
# This program is free software: you can redistribute it and/or modify
|
|
25
|
+
# it under the terms of the GNU General Public License as published by
|
|
26
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
27
|
+
# (at your option) any later version.
|
|
28
|
+
# https://www.gnu.org/licenses/
|
|
29
|
+
# ****************************************************************************
|
|
30
|
+
|
|
31
|
+
from cysignals.signals cimport sig_on, sig_off
|
|
32
|
+
|
|
33
|
+
from sage.cpython.string cimport str_to_bytes
|
|
34
|
+
|
|
35
|
+
from sage.libs.gmp.mpz cimport *
|
|
36
|
+
from sage.libs.mpfr cimport *
|
|
37
|
+
from sage.rings.integer cimport Integer
|
|
38
|
+
|
|
39
|
+
from sage.rings.complex_mpfr cimport ComplexNumber
|
|
40
|
+
from sage.rings.complex_mpfr import ComplexField
|
|
41
|
+
CCC = ComplexField()
|
|
42
|
+
|
|
43
|
+
from sage.rings.real_mpfr cimport RealNumber
|
|
44
|
+
from sage.rings.real_mpfr import RealField
|
|
45
|
+
RRR = RealField()
|
|
46
|
+
pi = RRR.pi()
|
|
47
|
+
|
|
48
|
+
initialize_globals()
|
|
49
|
+
|
|
50
|
+
##############################################################################
|
|
51
|
+
# Lfunction: base class for L-functions
|
|
52
|
+
##############################################################################
|
|
53
|
+
|
|
54
|
+
cdef class Lfunction:
|
|
55
|
+
# virtual class
|
|
56
|
+
def __init__(self, name, what_type_L, dirichlet_coefficient,
|
|
57
|
+
period, Q, OMEGA, gamma, lambd, pole, residue):
|
|
58
|
+
"""
|
|
59
|
+
Initialization of `L`-function objects.
|
|
60
|
+
See derived class for details, this class is not supposed to be
|
|
61
|
+
instantiated directly.
|
|
62
|
+
|
|
63
|
+
EXAMPLES::
|
|
64
|
+
|
|
65
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
66
|
+
sage: Lfunction_from_character(DirichletGroup(5)[1])
|
|
67
|
+
L-function with complex Dirichlet coefficients
|
|
68
|
+
"""
|
|
69
|
+
cdef int i # for indexing loops
|
|
70
|
+
cdef Integer tmpi # for accessing integer values
|
|
71
|
+
cdef RealNumber tmpr # for accessing real values
|
|
72
|
+
cdef ComplexNumber tmpc # for accessing complex values
|
|
73
|
+
|
|
74
|
+
_name = str_to_bytes(name)
|
|
75
|
+
cdef char *NAME = _name
|
|
76
|
+
cdef int what_type = what_type_L
|
|
77
|
+
|
|
78
|
+
tmpi = Integer(period)
|
|
79
|
+
cdef int Period = mpz_get_si(tmpi.value)
|
|
80
|
+
tmpr = RRR(Q)
|
|
81
|
+
cdef double q=mpfr_get_d(tmpr.value, MPFR_RNDN)
|
|
82
|
+
tmpc = CCC(OMEGA)
|
|
83
|
+
cdef c_Complex w=new_Complex(mpfr_get_d(tmpc.__re, MPFR_RNDN), mpfr_get_d(tmpc.__im, MPFR_RNDN))
|
|
84
|
+
|
|
85
|
+
cdef int A=len(gamma)
|
|
86
|
+
cdef double *g=new_doubles(A+1)
|
|
87
|
+
cdef c_Complex *l=new_Complexes(A+1)
|
|
88
|
+
for i from 0 <= i < A:
|
|
89
|
+
tmpr = RRR(gamma[i])
|
|
90
|
+
g[i+1] = mpfr_get_d(tmpr.value, MPFR_RNDN)
|
|
91
|
+
tmpc = CCC(lambd[i])
|
|
92
|
+
l[i+1] = new_Complex(mpfr_get_d(tmpc.__re, MPFR_RNDN), mpfr_get_d(tmpc.__im, MPFR_RNDN))
|
|
93
|
+
|
|
94
|
+
cdef int n_poles = len(pole)
|
|
95
|
+
cdef c_Complex *p = new_Complexes(n_poles +1)
|
|
96
|
+
cdef c_Complex *r = new_Complexes(n_poles +1)
|
|
97
|
+
for i from 0 <= i < n_poles:
|
|
98
|
+
tmpc=CCC(pole[i])
|
|
99
|
+
p[i+1] = new_Complex(mpfr_get_d(tmpc.__re, MPFR_RNDN), mpfr_get_d(tmpc.__im, MPFR_RNDN))
|
|
100
|
+
tmpc=CCC(residue[i])
|
|
101
|
+
r[i+1] = new_Complex(mpfr_get_d(tmpc.__re, MPFR_RNDN), mpfr_get_d(tmpc.__im, MPFR_RNDN))
|
|
102
|
+
|
|
103
|
+
self._init_fun(NAME, what_type, dirichlet_coefficient, Period, q, w, A, g, l, n_poles, p, r)
|
|
104
|
+
|
|
105
|
+
if name:
|
|
106
|
+
name += ': '
|
|
107
|
+
|
|
108
|
+
self._repr = name + 'L-function'
|
|
109
|
+
|
|
110
|
+
del_doubles(g)
|
|
111
|
+
del_Complexes(l)
|
|
112
|
+
del_Complexes(p)
|
|
113
|
+
del_Complexes(r)
|
|
114
|
+
|
|
115
|
+
def __repr__(self):
|
|
116
|
+
"""
|
|
117
|
+
Return string representation of this `L`-function.
|
|
118
|
+
|
|
119
|
+
EXAMPLES::
|
|
120
|
+
|
|
121
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
122
|
+
sage: Lfunction_from_character(DirichletGroup(5)[1])
|
|
123
|
+
L-function with complex Dirichlet coefficients
|
|
124
|
+
|
|
125
|
+
sage: Lfunction_Zeta()
|
|
126
|
+
The Riemann zeta function
|
|
127
|
+
"""
|
|
128
|
+
return self._repr
|
|
129
|
+
|
|
130
|
+
def value(self, s, derivative=0):
|
|
131
|
+
"""
|
|
132
|
+
Compute the value of the `L`-function at ``s``.
|
|
133
|
+
|
|
134
|
+
INPUT:
|
|
135
|
+
|
|
136
|
+
- ``s`` -- a complex number
|
|
137
|
+
- ``derivative`` -- integer (default: 0); the derivative to be evaluated
|
|
138
|
+
- ``rotate`` -- boolean (default: ``False``); if True, this returns the value of the
|
|
139
|
+
Hardy Z-function (sometimes called the Riemann-Siegel Z-function or
|
|
140
|
+
the Siegel Z-function)
|
|
141
|
+
|
|
142
|
+
EXAMPLES::
|
|
143
|
+
|
|
144
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
145
|
+
sage: chi = DirichletGroup(5)[2] # This is a quadratic character
|
|
146
|
+
sage: L = Lfunction_from_character(chi, type='int')
|
|
147
|
+
sage: (L.value(0.5) - 0.231750947504016).abs() < 1e-8
|
|
148
|
+
True
|
|
149
|
+
sage: v = L.value(0.2 + 0.4*I)
|
|
150
|
+
sage: (v - (0.102558603193 + 0.190840777924*I)).abs() < 1e-8
|
|
151
|
+
True
|
|
152
|
+
sage: L = Lfunction_from_character(chi, type='double')
|
|
153
|
+
sage: (L.value(0.6) - 0.274633355856345).abs() < 1e-8
|
|
154
|
+
True
|
|
155
|
+
sage: v = L.value(0.6 + I)
|
|
156
|
+
sage: (v - (0.362258705721 + 0.43388825062*I)).abs() < 1e-8
|
|
157
|
+
True
|
|
158
|
+
|
|
159
|
+
::
|
|
160
|
+
|
|
161
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
162
|
+
sage: chi = DirichletGroup(5)[1]
|
|
163
|
+
sage: L = Lfunction_from_character(chi, type='complex')
|
|
164
|
+
sage: v = L.value(0.5)
|
|
165
|
+
sage: (v - (0.763747880117 + 0.21696476751*I)).abs() < 1e-8
|
|
166
|
+
True
|
|
167
|
+
sage: v = L.value(0.6 + 5*I)
|
|
168
|
+
sage: (v - (0.702723260619 - 1.10178575243*I)).abs() < 1e-8
|
|
169
|
+
True
|
|
170
|
+
|
|
171
|
+
::
|
|
172
|
+
|
|
173
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
174
|
+
sage: L = Lfunction_Zeta()
|
|
175
|
+
sage: (L.value(0.5) + 1.46035450880).abs() < 1e-8
|
|
176
|
+
True
|
|
177
|
+
sage: v = L.value(0.4 + 0.5*I)
|
|
178
|
+
sage: (v - (-0.450728958517 - 0.780511403019*I)).abs() < 1e-8
|
|
179
|
+
True
|
|
180
|
+
"""
|
|
181
|
+
cdef ComplexNumber complexified_s = CCC(s)
|
|
182
|
+
cdef c_Complex z = new_Complex(mpfr_get_d(complexified_s.__re, MPFR_RNDN), mpfr_get_d(complexified_s.__im, MPFR_RNDN))
|
|
183
|
+
cdef c_Complex result = self._value(z, derivative)
|
|
184
|
+
return CCC(result.real(),result.imag())
|
|
185
|
+
|
|
186
|
+
def hardy_z_function(self, s):
|
|
187
|
+
"""
|
|
188
|
+
Compute the Hardy Z-function of the `L`-function at s.
|
|
189
|
+
|
|
190
|
+
INPUT:
|
|
191
|
+
|
|
192
|
+
- ``s`` -- a complex number with imaginary part between -0.5 and 0.5
|
|
193
|
+
|
|
194
|
+
EXAMPLES::
|
|
195
|
+
|
|
196
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
197
|
+
sage: chi = DirichletGroup(5)[2] # Quadratic character
|
|
198
|
+
sage: L = Lfunction_from_character(chi, type='int')
|
|
199
|
+
sage: (L.hardy_z_function(0) - 0.231750947504).abs() < 1e-8
|
|
200
|
+
True
|
|
201
|
+
sage: L.hardy_z_function(0.5).imag().abs() < 1e-8
|
|
202
|
+
True
|
|
203
|
+
|
|
204
|
+
::
|
|
205
|
+
|
|
206
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
207
|
+
sage: chi = DirichletGroup(5)[1]
|
|
208
|
+
sage: L = Lfunction_from_character(chi, type='complex')
|
|
209
|
+
sage: (L.hardy_z_function(0) - 0.793967590477).abs() < 1e-8
|
|
210
|
+
True
|
|
211
|
+
sage: L.hardy_z_function(0.5).imag().abs() < 1e-8
|
|
212
|
+
True
|
|
213
|
+
|
|
214
|
+
::
|
|
215
|
+
|
|
216
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
217
|
+
sage: E = EllipticCurve([-82,0])
|
|
218
|
+
sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000)
|
|
219
|
+
sage: (L.hardy_z_function(2.1) - (-0.006431791768)).abs() < 1e-8
|
|
220
|
+
True
|
|
221
|
+
"""
|
|
222
|
+
#This takes s -> .5 + I*s
|
|
223
|
+
cdef ComplexNumber complexified_s = CCC(0.5)+ CCC(0,1)*CCC(s)
|
|
224
|
+
cdef c_Complex z = new_Complex(mpfr_get_d(complexified_s.__re, MPFR_RNDN), mpfr_get_d(complexified_s.__im, MPFR_RNDN))
|
|
225
|
+
cdef c_Complex result = self._hardy_z_function(z)
|
|
226
|
+
return CCC(result.real(),result.imag())
|
|
227
|
+
|
|
228
|
+
def compute_rank(self):
|
|
229
|
+
"""
|
|
230
|
+
Compute the analytic rank (the order of vanishing at the center) of
|
|
231
|
+
of the `L`-function.
|
|
232
|
+
|
|
233
|
+
EXAMPLES::
|
|
234
|
+
|
|
235
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
236
|
+
sage: chi = DirichletGroup(5)[2] # This is a quadratic character
|
|
237
|
+
sage: L = Lfunction_from_character(chi, type='int')
|
|
238
|
+
sage: L.compute_rank()
|
|
239
|
+
0
|
|
240
|
+
|
|
241
|
+
::
|
|
242
|
+
|
|
243
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
244
|
+
sage: E = EllipticCurve([-82,0])
|
|
245
|
+
sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000)
|
|
246
|
+
sage: L.compute_rank()
|
|
247
|
+
3
|
|
248
|
+
"""
|
|
249
|
+
return self._compute_rank()
|
|
250
|
+
|
|
251
|
+
def _N(self, T):
|
|
252
|
+
"""
|
|
253
|
+
Compute the number of zeroes upto height `T` using the formula for
|
|
254
|
+
`N(T)` with the error of `S(T)`. Please do not use this. It is only
|
|
255
|
+
for debugging
|
|
256
|
+
|
|
257
|
+
EXAMPLES::
|
|
258
|
+
|
|
259
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
260
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
261
|
+
sage: L=Lfunction_from_character(chi, type='complex')
|
|
262
|
+
sage: L._N(10) # abs tol 1e-8
|
|
263
|
+
4.0
|
|
264
|
+
"""
|
|
265
|
+
cdef RealNumber real_T=RRR(T)
|
|
266
|
+
cdef double double_T = mpfr_get_d(real_T.value, MPFR_RNDN)
|
|
267
|
+
cdef double res_d = self._typedN(double_T)
|
|
268
|
+
return RRR(res_d)
|
|
269
|
+
|
|
270
|
+
def find_zeros(self, T1, T2, stepsize):
|
|
271
|
+
"""
|
|
272
|
+
Finds zeros on critical line between ``T1`` and ``T2`` using step size
|
|
273
|
+
of stepsize. This function might miss zeros if step size is too
|
|
274
|
+
large. This function computes the zeros of the `L`-function by using
|
|
275
|
+
change in signs of areal valued function whose zeros coincide with
|
|
276
|
+
the zeros of `L`-function.
|
|
277
|
+
|
|
278
|
+
Use :meth:`find_zeros_via_N` for slower but more rigorous computation.
|
|
279
|
+
|
|
280
|
+
INPUT:
|
|
281
|
+
|
|
282
|
+
- ``T1`` -- a real number giving the lower bound
|
|
283
|
+
- ``T2`` -- a real number giving the upper bound
|
|
284
|
+
- ``stepsize`` -- step size to be used for the zero search
|
|
285
|
+
|
|
286
|
+
OUTPUT: list of the imaginary parts of the zeros which were found
|
|
287
|
+
|
|
288
|
+
EXAMPLES::
|
|
289
|
+
|
|
290
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
291
|
+
sage: chi = DirichletGroup(5)[2] # This is a quadratic character
|
|
292
|
+
sage: L = Lfunction_from_character(chi, type='int')
|
|
293
|
+
sage: L.find_zeros(5,15,.1)
|
|
294
|
+
[6.64845334472..., 9.83144443288..., 11.9588456260...]
|
|
295
|
+
sage: L = Lfunction_from_character(chi, type='double')
|
|
296
|
+
sage: L.find_zeros(1,15,.1)
|
|
297
|
+
[6.64845334472..., 9.83144443288..., 11.9588456260...]
|
|
298
|
+
|
|
299
|
+
::
|
|
300
|
+
|
|
301
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
302
|
+
sage: chi = DirichletGroup(5)[1]
|
|
303
|
+
sage: L = Lfunction_from_character(chi, type='complex')
|
|
304
|
+
sage: L.find_zeros(-8,8,.1)
|
|
305
|
+
[-4.13290370521..., 6.18357819545...]
|
|
306
|
+
|
|
307
|
+
::
|
|
308
|
+
|
|
309
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
310
|
+
sage: L = Lfunction_Zeta()
|
|
311
|
+
sage: L.find_zeros(10,29.1,.1)
|
|
312
|
+
[14.1347251417..., 21.0220396387..., 25.0108575801...]
|
|
313
|
+
"""
|
|
314
|
+
cdef doublevec result
|
|
315
|
+
cdef double myresult
|
|
316
|
+
cdef int i
|
|
317
|
+
cdef RealNumber real_T1 = RRR(T1)
|
|
318
|
+
cdef RealNumber real_T2 = RRR(T2)
|
|
319
|
+
cdef RealNumber real_stepsize = RRR(stepsize)
|
|
320
|
+
sig_on()
|
|
321
|
+
self._find_zeros_v( mpfr_get_d(real_T1.value, MPFR_RNDN), mpfr_get_d(real_T2.value, MPFR_RNDN), mpfr_get_d(real_stepsize.value, MPFR_RNDN),&result)
|
|
322
|
+
sig_off()
|
|
323
|
+
i=result.size()
|
|
324
|
+
returnvalue = []
|
|
325
|
+
for i in range(result.size()):
|
|
326
|
+
returnvalue.append( RRR(result.ind(i)))
|
|
327
|
+
result.clear()
|
|
328
|
+
return returnvalue
|
|
329
|
+
|
|
330
|
+
#The default values are from L.h. See L.h
|
|
331
|
+
def find_zeros_via_N(self, count=0, start=0, max_refine=1025, rank=-1):
|
|
332
|
+
"""
|
|
333
|
+
Find ``count`` zeros (in order of increasing magnitude) and output
|
|
334
|
+
their imaginary parts. This function verifies that no zeros
|
|
335
|
+
are missed, and that all values output are indeed zeros.
|
|
336
|
+
|
|
337
|
+
If this `L`-function is self-dual (if its Dirichlet coefficients
|
|
338
|
+
are real, up to a tolerance of 1e-6), then only the zeros with
|
|
339
|
+
positive imaginary parts are output. Their conjugates, which
|
|
340
|
+
are also zeros, are not output.
|
|
341
|
+
|
|
342
|
+
INPUT:
|
|
343
|
+
|
|
344
|
+
- ``count`` -- number of zeros to be found
|
|
345
|
+
- ``start`` -- (default: 0) how many initial zeros to skip
|
|
346
|
+
- ``max_refine`` -- when some zeros are found to be missing, the step
|
|
347
|
+
size used to find zeros is refined. max_refine gives an upper limit
|
|
348
|
+
on when lcalc should give up. Use default value unless you know
|
|
349
|
+
what you are doing.
|
|
350
|
+
- ``rank`` -- integer (default: -1); analytic rank of the `L`-function.
|
|
351
|
+
If -1 is passed, then we attempt to compute it. (Use default if in
|
|
352
|
+
doubt)
|
|
353
|
+
|
|
354
|
+
OUTPUT: list of the imaginary parts of the zeros that have been found
|
|
355
|
+
|
|
356
|
+
EXAMPLES::
|
|
357
|
+
|
|
358
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
359
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
360
|
+
sage: L = Lfunction_from_character(chi, type='int')
|
|
361
|
+
sage: L.find_zeros_via_N(3)
|
|
362
|
+
[6.64845334472..., 9.83144443288..., 11.9588456260...]
|
|
363
|
+
sage: L = Lfunction_from_character(chi, type='double')
|
|
364
|
+
sage: L.find_zeros_via_N(3)
|
|
365
|
+
[6.64845334472..., 9.83144443288..., 11.9588456260...]
|
|
366
|
+
|
|
367
|
+
::
|
|
368
|
+
|
|
369
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
370
|
+
sage: chi = DirichletGroup(5)[1]
|
|
371
|
+
sage: L = Lfunction_from_character(chi, type='complex')
|
|
372
|
+
sage: zeros = L.find_zeros_via_N(3)
|
|
373
|
+
sage: (zeros[0] - (-4.13290370521286)).abs() < 1e-8
|
|
374
|
+
True
|
|
375
|
+
sage: (zeros[1] - 6.18357819545086).abs() < 1e-8
|
|
376
|
+
True
|
|
377
|
+
sage: (zeros[2] - 8.45722917442320).abs() < 1e-8
|
|
378
|
+
True
|
|
379
|
+
|
|
380
|
+
::
|
|
381
|
+
|
|
382
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
383
|
+
sage: L = Lfunction_Zeta()
|
|
384
|
+
sage: L.find_zeros_via_N(3)
|
|
385
|
+
[14.1347251417..., 21.0220396387..., 25.0108575801...]
|
|
386
|
+
"""
|
|
387
|
+
|
|
388
|
+
# This is the default value for message_stamp, but we have to
|
|
389
|
+
# pass it explicitly since we're passing in the next argument,
|
|
390
|
+
# our &result pointer.
|
|
391
|
+
cdef const char* message_stamp = ""
|
|
392
|
+
cdef doublevec result
|
|
393
|
+
sig_on()
|
|
394
|
+
self._find_zeros(count, start, max_refine, rank, message_stamp, &result)
|
|
395
|
+
sig_off()
|
|
396
|
+
returnvalue = []
|
|
397
|
+
for i in range(result.size()):
|
|
398
|
+
returnvalue.append( RRR(result.ind(i)))
|
|
399
|
+
result.clear()
|
|
400
|
+
return returnvalue
|
|
401
|
+
|
|
402
|
+
# Needs to be overridden
|
|
403
|
+
cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept:
|
|
404
|
+
raise NotImplementedError
|
|
405
|
+
|
|
406
|
+
cdef c_Complex _value(self, c_Complex s, int derivative) noexcept:
|
|
407
|
+
raise NotImplementedError
|
|
408
|
+
|
|
409
|
+
cdef c_Complex _hardy_z_function(self, c_Complex s) noexcept:
|
|
410
|
+
raise NotImplementedError
|
|
411
|
+
|
|
412
|
+
cdef int _compute_rank(self) noexcept:
|
|
413
|
+
raise NotImplementedError
|
|
414
|
+
|
|
415
|
+
cdef double _typedN(self, double T) noexcept:
|
|
416
|
+
raise NotImplementedError
|
|
417
|
+
|
|
418
|
+
cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept:
|
|
419
|
+
raise NotImplementedError
|
|
420
|
+
|
|
421
|
+
cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept:
|
|
422
|
+
raise NotImplementedError
|
|
423
|
+
|
|
424
|
+
##############################################################################
|
|
425
|
+
# Lfunction_I: L-functions with integer Dirichlet Coefficients
|
|
426
|
+
##############################################################################
|
|
427
|
+
|
|
428
|
+
cdef class Lfunction_I(Lfunction):
|
|
429
|
+
r"""
|
|
430
|
+
The ``Lfunction_I`` class is used to represent `L`-functions
|
|
431
|
+
with integer Dirichlet Coefficients. We assume that `L`-functions
|
|
432
|
+
satisfy the following functional equation.
|
|
433
|
+
|
|
434
|
+
.. MATH::
|
|
435
|
+
|
|
436
|
+
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
|
|
437
|
+
|
|
438
|
+
where
|
|
439
|
+
|
|
440
|
+
.. MATH::
|
|
441
|
+
|
|
442
|
+
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
|
|
443
|
+
|
|
444
|
+
See (23) in :arxiv:`math/0412181`
|
|
445
|
+
|
|
446
|
+
INPUT:
|
|
447
|
+
|
|
448
|
+
- ``what_type_L`` -- integer; this should be set to 1 if the coefficients
|
|
449
|
+
are periodic and 0 otherwise
|
|
450
|
+
|
|
451
|
+
- ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the
|
|
452
|
+
`L`-function. Only first `M` coefficients are needed if they are periodic.
|
|
453
|
+
|
|
454
|
+
- ``period`` -- if the coefficients are periodic, this should be the
|
|
455
|
+
period of the coefficients
|
|
456
|
+
|
|
457
|
+
- ``Q`` -- see above
|
|
458
|
+
|
|
459
|
+
- ``OMEGA`` -- see above
|
|
460
|
+
|
|
461
|
+
- ``kappa`` -- list of the values of `\kappa_j` in the functional equation
|
|
462
|
+
|
|
463
|
+
- ``gamma`` -- list of the values of `\gamma_j` in the functional equation
|
|
464
|
+
|
|
465
|
+
- ``pole`` -- list of the poles of `L`-function
|
|
466
|
+
|
|
467
|
+
- ``residue`` -- list of the residues of the `L`-function
|
|
468
|
+
|
|
469
|
+
.. NOTE::
|
|
470
|
+
|
|
471
|
+
If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`,
|
|
472
|
+
by replacing `s` by `s+(k-1)/2`, one can get it in the form we need.
|
|
473
|
+
"""
|
|
474
|
+
|
|
475
|
+
def __init__(self, name, what_type_L, dirichlet_coefficient,
|
|
476
|
+
period, Q, OMEGA, gamma, lambd, pole, residue):
|
|
477
|
+
r"""
|
|
478
|
+
Initialize an `L`-function with integer coefficients.
|
|
479
|
+
|
|
480
|
+
EXAMPLES::
|
|
481
|
+
|
|
482
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
483
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
484
|
+
sage: L=Lfunction_from_character(chi, type='int')
|
|
485
|
+
sage: type(L)
|
|
486
|
+
<class 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_I'>
|
|
487
|
+
"""
|
|
488
|
+
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
|
|
489
|
+
self._repr += " with integer Dirichlet coefficients"
|
|
490
|
+
|
|
491
|
+
# override
|
|
492
|
+
cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept:
|
|
493
|
+
cdef int N = len(dirichlet_coeff)
|
|
494
|
+
cdef Integer tmpi
|
|
495
|
+
cdef int * coeffs = new_ints(N+1) # lcalc ignores 0th coefficient
|
|
496
|
+
for i from 0 <= i< N by 1:
|
|
497
|
+
tmpi=Integer(dirichlet_coeff[i])
|
|
498
|
+
coeffs[i+1] = mpz_get_si(tmpi.value)
|
|
499
|
+
self.thisptr=new_c_Lfunction_I(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
|
|
500
|
+
del_ints(coeffs)
|
|
501
|
+
|
|
502
|
+
cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept:
|
|
503
|
+
return (<c_Lfunction_I *>(self.thisptr)).value(s, derivative, "pure")
|
|
504
|
+
|
|
505
|
+
cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept:
|
|
506
|
+
return (<c_Lfunction_I *>(self.thisptr)).value(s, 0, "rotated pure")
|
|
507
|
+
|
|
508
|
+
cdef int _compute_rank(self) noexcept:
|
|
509
|
+
return (<c_Lfunction_I *>(self.thisptr)).compute_rank()
|
|
510
|
+
|
|
511
|
+
cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept:
|
|
512
|
+
(<c_Lfunction_I *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
|
|
513
|
+
|
|
514
|
+
cdef double _typedN(self, double T) noexcept:
|
|
515
|
+
return (<c_Lfunction_I *>self.thisptr).N(T)
|
|
516
|
+
|
|
517
|
+
cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept:
|
|
518
|
+
(<c_Lfunction_I *>self.thisptr).find_zeros(count, start, max_refine, rank, message_stamp, result)
|
|
519
|
+
|
|
520
|
+
# debug tools
|
|
521
|
+
def _print_data_to_standard_output(self):
|
|
522
|
+
"""
|
|
523
|
+
This is used in debugging. It prints out information from
|
|
524
|
+
the C++ object behind the scenes. It will use standard output.
|
|
525
|
+
|
|
526
|
+
EXAMPLES::
|
|
527
|
+
|
|
528
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
529
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
530
|
+
sage: L=Lfunction_from_character(chi, type='int')
|
|
531
|
+
sage: L._print_data_to_standard_output() # tol 1e-8
|
|
532
|
+
-----------------------------------------------
|
|
533
|
+
<BLANKLINE>
|
|
534
|
+
Name of L_function:
|
|
535
|
+
number of dirichlet coefficients = 5
|
|
536
|
+
coefficients are periodic
|
|
537
|
+
b[1] = 1
|
|
538
|
+
b[2] = -1
|
|
539
|
+
b[3] = -1
|
|
540
|
+
b[4] = 1
|
|
541
|
+
b[5] = 0
|
|
542
|
+
<BLANKLINE>
|
|
543
|
+
Q = 1.26156626101
|
|
544
|
+
OMEGA = (1,0)
|
|
545
|
+
a = 1 (the quasi degree)
|
|
546
|
+
gamma[1] =0.5 lambda[1] =(0,0)
|
|
547
|
+
<BLANKLINE>
|
|
548
|
+
<BLANKLINE>
|
|
549
|
+
number of poles (of the completed L function) = 0
|
|
550
|
+
-----------------------------------------------
|
|
551
|
+
<BLANKLINE>
|
|
552
|
+
"""
|
|
553
|
+
(<c_Lfunction_I *>self.thisptr).print_data_L()
|
|
554
|
+
|
|
555
|
+
def __dealloc__(self):
|
|
556
|
+
"""
|
|
557
|
+
Deallocate memory used
|
|
558
|
+
"""
|
|
559
|
+
del_c_Lfunction_I(<c_Lfunction_I *>(self.thisptr))
|
|
560
|
+
|
|
561
|
+
##############################################################################
|
|
562
|
+
# Lfunction_D: `L`-functions with double (real) Dirichlet Coefficients
|
|
563
|
+
##############################################################################
|
|
564
|
+
|
|
565
|
+
cdef class Lfunction_D(Lfunction):
|
|
566
|
+
r"""
|
|
567
|
+
The ``Lfunction_D`` class is used to represent `L`-functions
|
|
568
|
+
with real Dirichlet coefficients. We assume that `L`-functions
|
|
569
|
+
satisfy the following functional equation.
|
|
570
|
+
|
|
571
|
+
.. MATH::
|
|
572
|
+
|
|
573
|
+
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
|
|
574
|
+
|
|
575
|
+
where
|
|
576
|
+
|
|
577
|
+
.. MATH::
|
|
578
|
+
|
|
579
|
+
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
|
|
580
|
+
|
|
581
|
+
See (23) in :arxiv:`math/0412181`
|
|
582
|
+
|
|
583
|
+
INPUT:
|
|
584
|
+
|
|
585
|
+
- ``what_type_L`` -- integer; this should be set to 1 if the coefficients are
|
|
586
|
+
periodic and 0 otherwise
|
|
587
|
+
|
|
588
|
+
- ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the
|
|
589
|
+
`L`-function. Only first `M` coefficients are needed if they are periodic.
|
|
590
|
+
|
|
591
|
+
- ``period`` -- if the coefficients are periodic, this should be the
|
|
592
|
+
period of the coefficients
|
|
593
|
+
|
|
594
|
+
- ``Q`` -- see above
|
|
595
|
+
|
|
596
|
+
- ``OMEGA`` -- see above
|
|
597
|
+
|
|
598
|
+
- ``kappa`` -- list of the values of `\kappa_j` in the functional equation
|
|
599
|
+
|
|
600
|
+
- ``gamma`` -- list of the values of `\gamma_j` in the functional equation
|
|
601
|
+
|
|
602
|
+
- ``pole`` -- list of the poles of `L`-function
|
|
603
|
+
|
|
604
|
+
- ``residue`` -- list of the residues of the `L`-function
|
|
605
|
+
|
|
606
|
+
.. NOTE::
|
|
607
|
+
|
|
608
|
+
If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`,
|
|
609
|
+
by replacing `s` by `s+(k-1)/2`, one can get it in the form we need.
|
|
610
|
+
"""
|
|
611
|
+
def __init__(self, name, what_type_L, dirichlet_coefficient,
|
|
612
|
+
period, Q, OMEGA, gamma, lambd, pole, residue):
|
|
613
|
+
r"""
|
|
614
|
+
Initialize an `L`-function with real coefficients.
|
|
615
|
+
|
|
616
|
+
EXAMPLES::
|
|
617
|
+
|
|
618
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
619
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
620
|
+
sage: L=Lfunction_from_character(chi, type='double')
|
|
621
|
+
sage: type(L)
|
|
622
|
+
<class 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_D'>
|
|
623
|
+
"""
|
|
624
|
+
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
|
|
625
|
+
self._repr += " with real Dirichlet coefficients"
|
|
626
|
+
|
|
627
|
+
# override
|
|
628
|
+
cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept:
|
|
629
|
+
cdef int i
|
|
630
|
+
cdef RealNumber tmpr
|
|
631
|
+
cdef int N = len(dirichlet_coeff)
|
|
632
|
+
cdef double * coeffs = new_doubles(N+1) # lcalc ignores 0th position
|
|
633
|
+
for i in range(N):
|
|
634
|
+
tmpr = RRR(dirichlet_coeff[i])
|
|
635
|
+
coeffs[i+1] = mpfr_get_d(tmpr.value, MPFR_RNDN)
|
|
636
|
+
self.thisptr=new_c_Lfunction_D(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
|
|
637
|
+
del_doubles(coeffs)
|
|
638
|
+
|
|
639
|
+
cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept:
|
|
640
|
+
return (<c_Lfunction_D *>(self.thisptr)).value(s, derivative, "pure")
|
|
641
|
+
|
|
642
|
+
cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept:
|
|
643
|
+
return (<c_Lfunction_D *>(self.thisptr)).value(s, 0, "rotated pure")
|
|
644
|
+
|
|
645
|
+
cdef inline int _compute_rank(self) noexcept:
|
|
646
|
+
return (<c_Lfunction_D *>(self.thisptr)).compute_rank()
|
|
647
|
+
|
|
648
|
+
cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept:
|
|
649
|
+
(<c_Lfunction_D *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
|
|
650
|
+
|
|
651
|
+
cdef double _typedN(self, double T) noexcept:
|
|
652
|
+
return (<c_Lfunction_D *>self.thisptr).N(T)
|
|
653
|
+
|
|
654
|
+
cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept:
|
|
655
|
+
(<c_Lfunction_D *>self.thisptr).find_zeros(count, start, max_refine, rank, message_stamp, result)
|
|
656
|
+
|
|
657
|
+
# debug tools
|
|
658
|
+
def _print_data_to_standard_output(self):
|
|
659
|
+
"""
|
|
660
|
+
This is used in debugging. It prints out information from
|
|
661
|
+
the C++ object behind the scenes. It will use standard output.
|
|
662
|
+
|
|
663
|
+
EXAMPLES::
|
|
664
|
+
|
|
665
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
666
|
+
sage: chi = DirichletGroup(5)[2] #This is a quadratic character
|
|
667
|
+
sage: L=Lfunction_from_character(chi, type='double')
|
|
668
|
+
sage: L._print_data_to_standard_output() # tol 1e-8
|
|
669
|
+
-----------------------------------------------
|
|
670
|
+
<BLANKLINE>
|
|
671
|
+
Name of L_function:
|
|
672
|
+
number of dirichlet coefficients = 5
|
|
673
|
+
coefficients are periodic
|
|
674
|
+
b[1] = 1
|
|
675
|
+
b[2] = -1
|
|
676
|
+
b[3] = -1
|
|
677
|
+
b[4] = 1
|
|
678
|
+
b[5] = 0
|
|
679
|
+
<BLANKLINE>
|
|
680
|
+
Q = 1.26156626101
|
|
681
|
+
OMEGA = (1,0)
|
|
682
|
+
a = 1 (the quasi degree)
|
|
683
|
+
gamma[1] =0.5 lambda[1] =(0,0)
|
|
684
|
+
<BLANKLINE>
|
|
685
|
+
<BLANKLINE>
|
|
686
|
+
number of poles (of the completed L function) = 0
|
|
687
|
+
-----------------------------------------------
|
|
688
|
+
<BLANKLINE>
|
|
689
|
+
"""
|
|
690
|
+
(<c_Lfunction_D *>self.thisptr).print_data_L()
|
|
691
|
+
|
|
692
|
+
def __dealloc__(self):
|
|
693
|
+
"""
|
|
694
|
+
Deallocate memory used
|
|
695
|
+
"""
|
|
696
|
+
del_c_Lfunction_D(<c_Lfunction_D *>(self.thisptr))
|
|
697
|
+
|
|
698
|
+
##############################################################################
|
|
699
|
+
# Lfunction_C: L-functions with Complex Dirichlet Coefficients
|
|
700
|
+
##############################################################################
|
|
701
|
+
|
|
702
|
+
cdef class Lfunction_C:
|
|
703
|
+
r"""
|
|
704
|
+
The ``Lfunction_C`` class is used to represent `L`-functions
|
|
705
|
+
with complex Dirichlet Coefficients. We assume that `L`-functions
|
|
706
|
+
satisfy the following functional equation.
|
|
707
|
+
|
|
708
|
+
.. MATH::
|
|
709
|
+
|
|
710
|
+
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
|
|
711
|
+
|
|
712
|
+
where
|
|
713
|
+
|
|
714
|
+
.. MATH::
|
|
715
|
+
|
|
716
|
+
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
|
|
717
|
+
|
|
718
|
+
See (23) in :arxiv:`math/0412181`
|
|
719
|
+
|
|
720
|
+
INPUT:
|
|
721
|
+
|
|
722
|
+
- ``what_type_L`` -- integer; this should be set to 1 if the coefficients are
|
|
723
|
+
periodic and 0 otherwise
|
|
724
|
+
|
|
725
|
+
- ``dirichlet_coefficient`` -- list of Dirichlet coefficients of the
|
|
726
|
+
`L`-function. Only first `M` coefficients are needed if they are periodic.
|
|
727
|
+
|
|
728
|
+
- ``period`` -- if the coefficients are periodic, this should be the
|
|
729
|
+
period of the coefficients
|
|
730
|
+
|
|
731
|
+
- ``Q`` -- see above
|
|
732
|
+
|
|
733
|
+
- ``OMEGA`` -- see above
|
|
734
|
+
|
|
735
|
+
- ``kappa`` -- list of the values of `\kappa_j` in the functional equation
|
|
736
|
+
|
|
737
|
+
- ``gamma`` -- list of the values of `\gamma_j` in the functional equation
|
|
738
|
+
|
|
739
|
+
- ``pole`` -- list of the poles of `L`-function
|
|
740
|
+
|
|
741
|
+
- ``residue`` -- list of the residues of the `L`-function
|
|
742
|
+
|
|
743
|
+
.. NOTE::
|
|
744
|
+
|
|
745
|
+
If an `L`-function satisfies `\Lambda(s) = \omega Q^s \Lambda(k-s)`,
|
|
746
|
+
by replacing `s` by `s+(k-1)/2`, one can get it in the form we need.
|
|
747
|
+
"""
|
|
748
|
+
|
|
749
|
+
def __init__(self, name, what_type_L, dirichlet_coefficient,
|
|
750
|
+
period, Q, OMEGA, gamma, lambd, pole, residue):
|
|
751
|
+
r"""
|
|
752
|
+
Initialize an `L`-function with complex coefficients.
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
757
|
+
sage: chi = DirichletGroup(5)[1]
|
|
758
|
+
sage: L=Lfunction_from_character(chi, type='complex')
|
|
759
|
+
sage: type(L)
|
|
760
|
+
<class 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_C'>
|
|
761
|
+
"""
|
|
762
|
+
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
|
|
763
|
+
self._repr += " with complex Dirichlet coefficients"
|
|
764
|
+
|
|
765
|
+
# override
|
|
766
|
+
cdef void _init_fun(self, char *NAME, int what_type, dirichlet_coeff, long long Period, double q, c_Complex w, int A, double *g, c_Complex *l, int n_poles, c_Complex *p, c_Complex *r) noexcept:
|
|
767
|
+
cdef int i
|
|
768
|
+
cdef int N = len(dirichlet_coeff)
|
|
769
|
+
cdef ComplexNumber tmpc
|
|
770
|
+
|
|
771
|
+
cdef c_Complex * coeffs = new_Complexes(N+1)
|
|
772
|
+
coeffs[0]=new_Complex(0,0)
|
|
773
|
+
for i from 0 <= i< N by 1:
|
|
774
|
+
tmpc=CCC(dirichlet_coeff[i])
|
|
775
|
+
coeffs[i+1] = new_Complex(mpfr_get_d(tmpc.__re, MPFR_RNDN), mpfr_get_d(tmpc.__im, MPFR_RNDN))
|
|
776
|
+
|
|
777
|
+
self.thisptr = new_c_Lfunction_C(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
|
|
778
|
+
|
|
779
|
+
del_Complexes(coeffs)
|
|
780
|
+
|
|
781
|
+
cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept:
|
|
782
|
+
return (<c_Lfunction_C *>(self.thisptr)).value(s, derivative, "pure")
|
|
783
|
+
|
|
784
|
+
cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept:
|
|
785
|
+
return (<c_Lfunction_C *>(self.thisptr)).value(s, 0,"rotated pure")
|
|
786
|
+
|
|
787
|
+
cdef inline int _compute_rank(self) noexcept:
|
|
788
|
+
return (<c_Lfunction_C *>(self.thisptr)).compute_rank()
|
|
789
|
+
|
|
790
|
+
cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept:
|
|
791
|
+
(<c_Lfunction_C *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
|
|
792
|
+
|
|
793
|
+
cdef double _typedN(self, double T) noexcept:
|
|
794
|
+
return (<c_Lfunction_C *>self.thisptr).N(T)
|
|
795
|
+
|
|
796
|
+
cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept:
|
|
797
|
+
(<c_Lfunction_C *>self.thisptr).find_zeros(count, start, max_refine, rank, message_stamp, result)
|
|
798
|
+
|
|
799
|
+
# debug tools
|
|
800
|
+
def _print_data_to_standard_output(self):
|
|
801
|
+
"""
|
|
802
|
+
This is used in debugging. It prints out information from
|
|
803
|
+
the C++ object behind the scenes. It will use standard output.
|
|
804
|
+
|
|
805
|
+
EXAMPLES::
|
|
806
|
+
|
|
807
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
808
|
+
sage: chi = DirichletGroup(5)[1]
|
|
809
|
+
sage: L=Lfunction_from_character(chi, type='complex')
|
|
810
|
+
sage: L._print_data_to_standard_output() # tol 1e-8
|
|
811
|
+
-----------------------------------------------
|
|
812
|
+
<BLANKLINE>
|
|
813
|
+
Name of L_function:
|
|
814
|
+
number of dirichlet coefficients = 5
|
|
815
|
+
coefficients are periodic
|
|
816
|
+
b[1] = (1,0)
|
|
817
|
+
b[2] = (0,1)
|
|
818
|
+
b[3] = (0,-1)
|
|
819
|
+
b[4] = (-1,0)
|
|
820
|
+
b[5] = (0,0)
|
|
821
|
+
<BLANKLINE>
|
|
822
|
+
Q = 1.26156626101
|
|
823
|
+
OMEGA = (0.850650808352,0.525731112119)
|
|
824
|
+
a = 1 (the quasi degree)
|
|
825
|
+
gamma[1] =0.5 lambda[1] =(0.5,0)
|
|
826
|
+
<BLANKLINE>
|
|
827
|
+
<BLANKLINE>
|
|
828
|
+
number of poles (of the completed L function) = 0
|
|
829
|
+
-----------------------------------------------
|
|
830
|
+
<BLANKLINE>
|
|
831
|
+
"""
|
|
832
|
+
(<c_Lfunction_C *>self.thisptr).print_data_L()
|
|
833
|
+
|
|
834
|
+
def __dealloc__(self):
|
|
835
|
+
"""
|
|
836
|
+
Deallocate memory used
|
|
837
|
+
"""
|
|
838
|
+
del_c_Lfunction_C(<c_Lfunction_C *>(self.thisptr))
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
##############################################################################
|
|
842
|
+
# Zeta function
|
|
843
|
+
##############################################################################
|
|
844
|
+
|
|
845
|
+
cdef class Lfunction_Zeta(Lfunction):
|
|
846
|
+
r"""
|
|
847
|
+
The ``Lfunction_Zeta`` class is used to generate the Riemann zeta function.
|
|
848
|
+
"""
|
|
849
|
+
def __init__(self):
|
|
850
|
+
r"""
|
|
851
|
+
Initialize the Riemann zeta function.
|
|
852
|
+
|
|
853
|
+
EXAMPLES::
|
|
854
|
+
|
|
855
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import *
|
|
856
|
+
sage: sage.libs.lcalc.lcalc_Lfunction.Lfunction_Zeta()
|
|
857
|
+
The Riemann zeta function
|
|
858
|
+
"""
|
|
859
|
+
self.thisptr = new_c_Lfunction_Zeta()
|
|
860
|
+
self._repr = "The Riemann zeta function"
|
|
861
|
+
|
|
862
|
+
cdef inline c_Complex _value(self, c_Complex s, int derivative) noexcept:
|
|
863
|
+
return (<c_Lfunction_Zeta *>(self.thisptr)).value(s, derivative, "pure")
|
|
864
|
+
|
|
865
|
+
cdef inline c_Complex _hardy_z_function(self, c_Complex s) noexcept:
|
|
866
|
+
return (<c_Lfunction_Zeta *>(self.thisptr)).value(s, 0, "rotated pure")
|
|
867
|
+
|
|
868
|
+
cdef inline int _compute_rank(self) noexcept:
|
|
869
|
+
return (<c_Lfunction_Zeta *>(self.thisptr)).compute_rank()
|
|
870
|
+
|
|
871
|
+
cdef void _find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result) noexcept:
|
|
872
|
+
(<c_Lfunction_Zeta *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
|
|
873
|
+
|
|
874
|
+
cdef double _typedN(self, double T) noexcept:
|
|
875
|
+
return (<c_Lfunction_Zeta *>self.thisptr).N(T)
|
|
876
|
+
|
|
877
|
+
cdef int _find_zeros(self, long count, long start, double max_refine, int rank, const char* message_stamp, doublevec *result) noexcept:
|
|
878
|
+
(<c_Lfunction_Zeta *>self.thisptr).find_zeros(count, start, max_refine, rank, message_stamp, result)
|
|
879
|
+
|
|
880
|
+
def __dealloc__(self):
|
|
881
|
+
"""
|
|
882
|
+
Deallocate memory used
|
|
883
|
+
"""
|
|
884
|
+
del_c_Lfunction_Zeta(<c_Lfunction_Zeta *>(self.thisptr))
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
##############################################################################
|
|
888
|
+
# Tools
|
|
889
|
+
##############################################################################
|
|
890
|
+
|
|
891
|
+
def Lfunction_from_character(chi, type='complex'):
|
|
892
|
+
"""
|
|
893
|
+
Given a primitive Dirichlet character, this function returns
|
|
894
|
+
an lcalc `L`-function object for the `L`-function of the character.
|
|
895
|
+
|
|
896
|
+
INPUT:
|
|
897
|
+
|
|
898
|
+
- ``chi`` -- a Dirichlet character
|
|
899
|
+
- ``use_type`` -- string (default: ``'complex'``); type used for the Dirichlet
|
|
900
|
+
coefficients. This can be ``'int'``, ``'double'`` or ``'complex'``.
|
|
901
|
+
|
|
902
|
+
OUTPUT: `L`-function object for ``chi``
|
|
903
|
+
|
|
904
|
+
EXAMPLES::
|
|
905
|
+
|
|
906
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_character
|
|
907
|
+
sage: Lfunction_from_character(DirichletGroup(5)[1])
|
|
908
|
+
L-function with complex Dirichlet coefficients
|
|
909
|
+
sage: Lfunction_from_character(DirichletGroup(5)[2], type='int')
|
|
910
|
+
L-function with integer Dirichlet coefficients
|
|
911
|
+
sage: Lfunction_from_character(DirichletGroup(5)[2], type='double')
|
|
912
|
+
L-function with real Dirichlet coefficients
|
|
913
|
+
sage: Lfunction_from_character(DirichletGroup(5)[1], type='int')
|
|
914
|
+
Traceback (most recent call last):
|
|
915
|
+
...
|
|
916
|
+
ValueError: For non quadratic characters you must use type="complex"
|
|
917
|
+
"""
|
|
918
|
+
if (not chi.is_primitive()):
|
|
919
|
+
raise TypeError("Dirichlet character is not primitive")
|
|
920
|
+
|
|
921
|
+
modulus=chi.modulus()
|
|
922
|
+
if chi.is_even():
|
|
923
|
+
a=0
|
|
924
|
+
else:
|
|
925
|
+
a=1
|
|
926
|
+
|
|
927
|
+
Q=(RRR(modulus/pi)).sqrt()
|
|
928
|
+
poles=[]
|
|
929
|
+
residues=[]
|
|
930
|
+
period=modulus
|
|
931
|
+
OMEGA=1.0/ ( CCC(0,1)**a * (CCC(modulus)).sqrt()/chi.gauss_sum() )
|
|
932
|
+
|
|
933
|
+
if type == "complex":
|
|
934
|
+
dir_coeffs = [CCC(chi(n)) for n in range(1, modulus + 1)]
|
|
935
|
+
return Lfunction_C("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
|
|
936
|
+
if type not in ["double", "int"]:
|
|
937
|
+
raise ValueError("unknown type")
|
|
938
|
+
if chi.order() != 2:
|
|
939
|
+
raise ValueError("For non quadratic characters you must use type=\"complex\"")
|
|
940
|
+
if type == "double":
|
|
941
|
+
dir_coeffs = [RRR(chi(n)) for n in range(1, modulus + 1)]
|
|
942
|
+
return Lfunction_D("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
|
|
943
|
+
if type == "int":
|
|
944
|
+
dir_coeffs = [Integer(chi(n)) for n in range(1, modulus + 1)]
|
|
945
|
+
return Lfunction_I("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000):
|
|
949
|
+
"""
|
|
950
|
+
Given an elliptic curve E, return an `L`-function object for
|
|
951
|
+
the function `L(s, E)`.
|
|
952
|
+
|
|
953
|
+
INPUT:
|
|
954
|
+
|
|
955
|
+
- ``E`` -- an elliptic curve
|
|
956
|
+
- ``number_of_coeffs`` -- integer (default: 10000); the number of
|
|
957
|
+
coefficients to be used when constructing the `L`-function object. Right
|
|
958
|
+
now this is fixed at object creation time, and is not automatically
|
|
959
|
+
set intelligently.
|
|
960
|
+
|
|
961
|
+
OUTPUT: `L`-function object for ``L(s, E)``
|
|
962
|
+
|
|
963
|
+
EXAMPLES::
|
|
964
|
+
|
|
965
|
+
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_elliptic_curve
|
|
966
|
+
sage: L = Lfunction_from_elliptic_curve(EllipticCurve('37'))
|
|
967
|
+
sage: L
|
|
968
|
+
L-function with real Dirichlet coefficients
|
|
969
|
+
sage: L.value(0.5).abs() < 1e-8
|
|
970
|
+
True
|
|
971
|
+
sage: (L.value(0.5, derivative=1) - 0.305999773835200).abs() < 1e-6
|
|
972
|
+
True
|
|
973
|
+
"""
|
|
974
|
+
Q = RRR(E.conductor()).sqrt() / RRR(2 * pi)
|
|
975
|
+
poles = []
|
|
976
|
+
residues = []
|
|
977
|
+
dir_coeffs = E.anlist(number_of_coeffs)
|
|
978
|
+
dir_coeffs = [RRR(dir_coeffs[i]) / (RRR(i)).sqrt()
|
|
979
|
+
for i in range(1, number_of_coeffs)]
|
|
980
|
+
OMEGA = E.root_number()
|
|
981
|
+
return Lfunction_D("", 2, dir_coeffs, 0, Q, OMEGA, [1], [.5],
|
|
982
|
+
poles, residues)
|