Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/lcalc/lcalc_Lfunction.pyx
4057 views
1
r"""
2
This wraps lcalc Library
3
4
AUTHORS:
5
- Rishikesh (2009): initial version
6
- Yann Laigle-Chapuy (2009): refactored
7
8
"""
9
#*****************************************************************************
10
# Copyright (C) 2009 William Stein <[email protected]>
11
#
12
# Distributed under the terms of the GNU General Public License (GPL)
13
#
14
# This code is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
# General Public License for more details.
18
#
19
# The full text of the GPL is available at:
20
#
21
# http://www.gnu.org/licenses/
22
#*****************************************************************************
23
24
include "../../ext/interrupt.pxi"
25
include "../../ext/stdsage.pxi"
26
include "../../ext/cdefs.pxi"
27
include "../mpfr.pxd"
28
29
from sage.rings.integer cimport Integer
30
31
from sage.rings.complex_number cimport ComplexNumber
32
from sage.rings.complex_field import ComplexField
33
CCC=ComplexField()
34
35
from sage.rings.real_mpfr cimport RealNumber
36
from sage.rings.real_mpfr import RealField
37
RRR= RealField ()
38
pi=RRR.pi()
39
40
initialize_globals()
41
42
##############################################################################
43
# Lfunction: base class for L functions
44
##############################################################################
45
46
cdef class Lfunction:
47
# virtual class
48
def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue):
49
"""
50
Initialisation of L-function objects.
51
See derived class for details, this class is not supposed to be instanciated directly.
52
53
EXAMPLES::
54
55
sage: from sage.libs.lcalc.lcalc_Lfunction import *
56
sage: Lfunction_from_character(DirichletGroup(5)[1])
57
L-function with complex Dirichlet coefficients
58
"""
59
cdef int i #for indexing loops
60
cdef Integer tmpi #for accessing integer values
61
cdef RealNumber tmpr #for accessing real values
62
cdef ComplexNumber tmpc #for accessing complexe values
63
64
cdef char *NAME=name
65
cdef int what_type = what_type_L
66
67
tmpi=Integer(period)
68
cdef int Period = mpz_get_si(tmpi.value)
69
tmpr = RRR(Q)
70
cdef double q=mpfr_get_d(tmpr.value,GMP_RNDN)
71
tmpc=CCC(OMEGA)
72
cdef c_Complex w=new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN))
73
74
cdef int A=len(gamma)
75
cdef double *g=new_doubles(A+1)
76
cdef c_Complex *l=new_Complexes(A+1)
77
for i from 0 <= i < A:
78
tmpr = RRR(gamma[i])
79
g[i+1] = mpfr_get_d(tmpr.value,GMP_RNDN)
80
tmpc = CCC(lambd[i])
81
l[i+1] = new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN))
82
83
cdef int n_poles = len(pole)
84
cdef c_Complex *p = new_Complexes(n_poles +1)
85
cdef c_Complex *r = new_Complexes(n_poles +1)
86
for i from 0 <= i < n_poles:
87
tmpc=CCC(pole[i])
88
p[i+1] = new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN))
89
tmpc=CCC(residue[i])
90
r[i+1] = new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN))
91
92
self.__init_fun(NAME, what_type, dirichlet_coefficient, Period, q, w, A, g, l, n_poles, p, r)
93
94
repr_name = str(NAME)
95
if str(repr_name) != "":
96
repr_name += ": "
97
98
self._repr = repr_name + "L-function"
99
100
del_doubles(g)
101
del_Complexes(l)
102
del_Complexes(p)
103
del_Complexes(r)
104
105
def __repr__(self):
106
"""
107
Return string representation of this L-function.
108
109
EXAMPLES::
110
111
sage: from sage.libs.lcalc.lcalc_Lfunction import *
112
sage: Lfunction_from_character(DirichletGroup(5)[1])
113
L-function with complex Dirichlet coefficients
114
115
sage: Lfunction_Zeta()
116
The Zeta function
117
"""
118
return self._repr
119
120
def value(self,s,derivative=0):
121
"""
122
Computes the value of L-function at s
123
124
INPUT:
125
s -- a complex number
126
derivative -- (default 0) the derivative to be evaluated
127
128
EXAMPLES::
129
130
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
131
sage: from sage.libs.lcalc.lcalc_Lfunction import *
132
sage: L=Lfunction_from_character(chi, type="int")
133
sage: L.value(.5)
134
0.231750947504... + 5.75329642226...e-18*I
135
sage: L.value(.2+.4*I)
136
0.102558603193... + 0.190840777924...*I
137
138
sage: L=Lfunction_from_character(chi, type="double")
139
sage: L.value(.6)
140
0.274633355856... + 6.59869267328...e-18*I
141
sage: L.value(.6+I)
142
0.362258705721... + 0.433888250620...*I
143
144
sage: chi=DirichletGroup(5)[1]
145
sage: L=Lfunction_from_character(chi, type="complex")
146
sage: L.value(.5)
147
0.763747880117... + 0.216964767518...*I
148
sage: L.value(.6+5*I)
149
0.702723260619... - 1.10178575243...*I
150
151
sage: L=Lfunction_Zeta()
152
sage: L.value(.5)
153
-1.46035450880...
154
sage: L.value(.4+.5*I)
155
-0.450728958517... - 0.780511403019...*I
156
"""
157
cdef ComplexNumber complexified_s = CCC(s)
158
cdef c_Complex z = new_Complex(mpfr_get_d(complexified_s.__re,GMP_RNDN), mpfr_get_d(complexified_s.__im, GMP_RNDN))
159
cdef c_Complex result = self.__value(z, derivative)
160
return CCC(result.real(),result.imag())
161
162
def __N(self, T):
163
"""
164
Computes number of zeroes upto height T using the formula for
165
N(T) with the error of S(T). Please do not use this. It is only
166
for debugging
167
168
EXAMPLES::
169
170
sage: from sage.libs.lcalc.lcalc_Lfunction import *
171
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
172
sage: L=Lfunction_from_character(chi, type="complex")
173
sage: L.__N(10)
174
3.17043978326...
175
"""
176
cdef RealNumber real_T=RRR(T)
177
cdef double double_T = mpfr_get_d(real_T.value, GMP_RNDN)
178
cdef double res_d = self.__typedN(double_T)
179
return RRR(res_d)
180
181
def find_zeros(self, T1, T2, stepsize):
182
"""
183
Finds zeros on critical line between T1 and T2 using step size
184
of stepsize. This function might miss zeros if step size is too
185
large. This function computes the zeros of the L-function by using
186
change in signs of real valued function whose zeros coincide with
187
the zeros of L-function.
188
189
Use find_zeros_via_N for slower but more rigorous computation.
190
191
INPUT:
192
T1 -- a real number giving the lower bound
193
T2 -- a real number giving the upper bound
194
stepsize -- step size to be used for search for zeros
195
196
OUTPUT:
197
A vector of zeros on the critical line which were found.
198
199
EXAMPLES:
200
sage: from sage.libs.lcalc.lcalc_Lfunction import *
201
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
202
sage: L=Lfunction_from_character(chi, type="int")
203
sage: L.find_zeros(5,15,.1)
204
[6.64845334472..., 9.83144443288..., 11.9588456260...]
205
206
sage: L=Lfunction_from_character(chi, type="double")
207
sage: L.find_zeros(1,15,.1)
208
[6.64845334472..., 9.83144443288..., 11.9588456260...]
209
210
sage: chi=DirichletGroup(5)[1]
211
sage: L=Lfunction_from_character(chi, type="complex")
212
sage: L.find_zeros(-8,8,.1)
213
[-4.13290370521..., 6.18357819545...]
214
215
sage: L=Lfunction_Zeta()
216
sage: L.find_zeros(10,29.1,.1)
217
[14.1347251417..., 21.0220396387..., 25.0108575801...]
218
"""
219
cdef doublevec result
220
cdef double myresult
221
cdef int i
222
cdef RealNumber real_T1 = RRR(T1)
223
cdef RealNumber real_T2 = RRR(T2)
224
cdef RealNumber real_stepsize = RRR(stepsize)
225
sig_on()
226
self.__find_zeros_v( mpfr_get_d(real_T1.value, GMP_RNDN), mpfr_get_d(real_T2.value, GMP_RNDN), mpfr_get_d(real_stepsize.value, GMP_RNDN),&result)
227
sig_off()
228
i=result.size()
229
returnvalue = []
230
for i in range(result.size()):
231
returnvalue.append( RRR(result.ind(i)))
232
result.clear()
233
return returnvalue
234
235
#The default values are from L.h. See L.h
236
def find_zeros_via_N(self, count=0, do_negative=False, max_refine=1025, rank=-1, test_explicit_formula=0):
237
"""
238
Finds "count" number of zeros with positive imaginary part
239
starting at real axis. This function also verifies if all
240
the zeros have been found.
241
242
INPUT:
243
count -- number of zeros to be found
244
do_negative -- (default False) False to ignore zeros below the real axis.
245
max_refine -- when some zeros are found to be missing, the step size used to find zeros is refined. max_refine gives an upper limit on when lcalc should give up. Use default value unless you know what you are doing.
246
247
rank -- analytic rank of the L-function. If it is -1, then lcalccomputes it. (Use default if you are in doubt)
248
249
test_explicit_formula -- test explicit fomula for additional confidence that all the zeros have been found. This is still being tested, so use the default.
250
251
252
OUTPUT:
253
List of zeros.
254
255
EXAMPLES:
256
sage: from sage.libs.lcalc.lcalc_Lfunction import *
257
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
258
sage: L=Lfunction_from_character(chi, type="int")
259
sage: L.find_zeros_via_N(3)
260
[6.64845334472..., 9.83144443288..., 11.9588456260...]
261
262
sage: L=Lfunction_from_character(chi, type="double")
263
sage: L.find_zeros_via_N(3)
264
[6.64845334472..., 9.83144443288..., 11.9588456260...]
265
266
sage: chi=DirichletGroup(5)[1]
267
sage: L=Lfunction_from_character(chi, type="complex")
268
sage: L.find_zeros_via_N(3)
269
[6.18357819545..., 8.45722917442..., 12.6749464170...]
270
271
sage: L=Lfunction_Zeta()
272
sage: L.find_zeros_via_N(3)
273
[14.1347251417..., 21.0220396387..., 25.0108575801...]
274
275
"""
276
cdef Integer count_I = Integer(count)
277
cdef Integer do_negative_I = Integer(do_negative)
278
cdef RealNumber max_refine_R = RRR(max_refine)
279
cdef Integer rank_I = Integer(rank)
280
cdef Integer test_explicit_I = Integer(test_explicit_formula)
281
cdef doublevec result
282
sig_on()
283
self.__find_zeros_via_N_v(mpz_get_si(count_I.value), mpz_get_si(do_negative_I.value), mpfr_get_d(max_refine_R.value, GMP_RNDN), mpz_get_si(rank_I.value), mpz_get_si(test_explicit_I.value), &result)
284
sig_off()
285
returnvalue = []
286
for i in range(result.size()):
287
returnvalue.append( RRR(result.ind(i)))
288
result.clear()
289
return returnvalue
290
291
#### Needs to be overriden
292
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):
293
raise NotImplementedError
294
295
cdef c_Complex __value(self,c_Complex s,int derivative):
296
raise NotImplementedError
297
298
cdef double __typedN(self,double T):
299
raise NotImplementedError
300
301
cdef void __find_zeros_v(self,double T1, double T2, double stepsize, doublevec *result):
302
raise NotImplementedError
303
304
cdef void __find_zeros_via_N_v(self, long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec *result):
305
raise NotImplementedError
306
307
##############################################################################
308
# Lfunction_I: L functions with integer Dirichlet Coefficients
309
##############################################################################
310
311
cdef class Lfunction_I(Lfunction):
312
r"""
313
The \class{Lfunction_I} class is used to represent L functions
314
with integer Dirichlet Coefficients. We assume that L functions
315
satisfy the following functional equation
316
317
.. math::
318
319
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
320
321
where
322
323
.. math::
324
325
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
326
327
328
329
See (23) in http://arxiv.org/abs/math/0412181
330
331
INPUT:
332
what_type_L -- 1 for periodic and 0 for general
333
334
dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1)
335
Only first M coefficients are needed if they are periodic
336
337
period -- Period of the dirichlet coeffcients
338
339
Q -- See above
340
341
OMEGA -- omega above
342
343
gamma -- list of \gamma_j in Gamma factor, see the reference above
344
345
lambd -- list of \lambda_j in Gamma see the reference above
346
347
pole -- list of poles of \Lambda
348
349
residue -- list of residues of \Lambda at above poles
350
351
NOTES:
352
If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s),
353
by replacing s by s+(k-1)/2, one can get it in the form we need.
354
"""
355
356
def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue):
357
r"""
358
Initiaize L function with integer coefficients
359
360
EXAMPLES:
361
sage: from sage.libs.lcalc.lcalc_Lfunction import *
362
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
363
sage: L=Lfunction_from_character(chi, type="int")
364
sage: type(L)
365
<type 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_I'>
366
"""
367
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
368
self._repr += " with integer Dirichlet coefficients"
369
370
### override
371
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):
372
cdef int N = len(dirichlet_coeff)
373
cdef Integer tmpi
374
cdef int * coeffs = new_ints(N+1) #lcalc ignores 0the coefficient
375
for i from 0 <= i< N by 1:
376
tmpi=Integer(dirichlet_coeff[i])
377
coeffs[i+1] = mpz_get_si(tmpi.value)
378
self.thisptr=new_c_Lfunction_I(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
379
del_ints(coeffs)
380
381
cdef inline c_Complex __value(self,c_Complex s,int derivative):
382
return (<c_Lfunction_I *>(self.thisptr)).value(s, derivative, "pure")
383
384
cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result):
385
(<c_Lfunction_I *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
386
387
cdef double __typedN(self, double T):
388
return (<c_Lfunction_I *>self.thisptr).N(T)
389
390
cdef void __find_zeros_via_N_v(self, long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec *result):
391
(<c_Lfunction_I *>self.thisptr).find_zeros_via_N_v(count, do_negative, max_refine, rank, test_explicit_formula, result[0])
392
393
### debug tools
394
def _print_data_to_standard_output(self):
395
"""
396
This is used in debugging. It prints out information from
397
the C++ object behind the scenes. It will use standard output.
398
399
EXAMPLES::
400
401
sage: from sage.libs.lcalc.lcalc_Lfunction import *
402
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
403
sage: L=Lfunction_from_character(chi, type="int")
404
sage: L._print_data_to_standard_output()
405
"""
406
(<c_Lfunction_I *>self.thisptr).print_data_L()
407
408
def __dealloc__(self):
409
"""
410
Deallocate memory used
411
"""
412
del_c_Lfunction_I(<c_Lfunction_I *>(self.thisptr))
413
414
##############################################################################
415
# Lfunction_D: L functions with double (real) Dirichlet Coefficients
416
##############################################################################
417
418
cdef class Lfunction_D(Lfunction):
419
r"""
420
The \class{Lfunction_D} class is used to represent L functions
421
with real Dirichlet Coefficients. We assume that L functions
422
satisfy the following functional equation
423
424
.. math::
425
426
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
427
428
where
429
430
.. math::
431
432
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
433
434
435
436
437
See (23) in http://arxiv.org/abs/math/0412181
438
439
INPUT:
440
what_type_L -- 1 for periodic and 0 for general
441
442
dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1)
443
Only first M coefficients are needed in they are periodic
444
445
period -- Period of the dirichlet coeffcients
446
447
Q -- See above
448
449
OMEGA -- omega above
450
451
gamma -- list of \gamma_j in Gamma factor, see the reference above
452
453
lambd -- list of \lambda_j in Gamma see the reference above
454
455
pole -- list of poles of \Lambda
456
457
residue -- list of residues of \Lambda at above poles
458
459
NOTES:
460
If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s),
461
by replacing s by s+(k-1)/2, one can get it in the form we need.
462
"""
463
def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue):
464
r"""
465
Initiaize L function with real coefficients
466
467
EXAMPLES:
468
sage: from sage.libs.lcalc.lcalc_Lfunction import *
469
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
470
sage: L=Lfunction_from_character(chi, type="double")
471
sage: type(L)
472
<type 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_D'>
473
"""
474
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
475
self._repr += " with real Dirichlet coefficients"
476
477
### override
478
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):
479
cdef int i
480
cdef RealNumber tmpr
481
cdef int N = len(dirichlet_coeff)
482
cdef double * coeffs = new_doubles(N+1)#lcalc ignores 0th position
483
for i from 0 <= i< N by 1:
484
tmpr=RRR(dirichlet_coeff[i])
485
coeffs[i+1] = mpfr_get_d(tmpr.value, GMP_RNDN)
486
self.thisptr=new_c_Lfunction_D(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
487
del_doubles(coeffs)
488
489
cdef inline c_Complex __value(self,c_Complex s,int derivative):
490
return (<c_Lfunction_D *>(self.thisptr)).value(s, derivative, "pure")
491
492
cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result):
493
(<c_Lfunction_D *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
494
495
cdef double __typedN(self, double T):
496
return (<c_Lfunction_D *>self.thisptr).N(T)
497
498
cdef void __find_zeros_via_N_v(self, long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec *result):
499
(<c_Lfunction_D *>self.thisptr).find_zeros_via_N_v(count, do_negative, max_refine, rank, test_explicit_formula, result[0])
500
501
### debug tools
502
def _print_data_to_standard_output(self):
503
"""
504
This is used in debugging. It prints out information from
505
the C++ object behind the scenes. It will use standard output.
506
507
EXAMPLES::
508
509
sage: from sage.libs.lcalc.lcalc_Lfunction import *
510
sage: chi=DirichletGroup(5)[2] #This is a quadratic character
511
sage: L=Lfunction_from_character(chi, type="double")
512
sage: L._print_data_to_standard_output()
513
"""
514
(<c_Lfunction_D *>self.thisptr).print_data_L()
515
516
def __dealloc__(self):
517
"""
518
Deallocate memory used
519
"""
520
del_c_Lfunction_D(<c_Lfunction_D *>(self.thisptr))
521
522
##############################################################################
523
# Lfunction_C: L functions with Complex Dirichlet Coefficients
524
##############################################################################
525
526
cdef class Lfunction_C:
527
r"""
528
The \class{Lfunction_C} class is used to represent L functions
529
with complex Dirichlet Coefficients. We assume that L functions
530
satisfy the following functional equation
531
532
.. math::
533
534
\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}
535
536
where
537
538
.. math::
539
540
\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)
541
542
543
544
545
See (23) in http://arxiv.org/abs/math/0412181
546
547
INPUT:
548
what_type_L -- 1 for periodic and 0 for general
549
550
dirichlet_coefficient -- List of dirichlet coefficients (starting from n=1)
551
Only first M coefficients are needed in they are periodic
552
553
period -- Period of the dirichlet coeffcients
554
555
Q -- See above
556
557
OMEGA -- omega above
558
559
gamma -- list of \gamma_j in Gamma factor, see the reference above
560
561
lambd -- list of \lambda_j in Gamma see the reference above
562
563
pole -- list of poles of \Lambda
564
565
residue -- list of residues of \Lambda at above poles
566
567
NOTES:
568
If an L function satisfies \Lambda(s) = \omega Q^s \Lamda(k-s),
569
by replacing s by s+(k-1)/2, one can get it in the form we need.
570
"""
571
572
def __init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue):
573
r"""
574
Initiaize L function with complex coefficients
575
576
EXAMPLES:
577
sage: from sage.libs.lcalc.lcalc_Lfunction import *
578
sage: chi=DirichletGroup(5)[1]
579
sage: L=Lfunction_from_character(chi, type="complex")
580
sage: type(L)
581
<type 'sage.libs.lcalc.lcalc_Lfunction.Lfunction_C'>
582
"""
583
Lfunction.__init__(self, name, what_type_L, dirichlet_coefficient, period, Q, OMEGA, gamma,lambd, pole,residue)
584
self._repr += " with complex Dirichlet coefficients"
585
586
### override
587
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):
588
cdef int i
589
cdef int N = len(dirichlet_coeff)
590
cdef ComplexNumber tmpc
591
592
cdef c_Complex * coeffs = new_Complexes(N+1)
593
coeffs[0]=new_Complex(0,0)
594
for i from 0 <= i< N by 1:
595
tmpc=CCC(dirichlet_coeff[i])
596
coeffs[i+1] = new_Complex(mpfr_get_d(tmpc.__re,GMP_RNDN), mpfr_get_d(tmpc.__im, GMP_RNDN))
597
598
self.thisptr = new_c_Lfunction_C(NAME, what_type, N, coeffs, Period, q, w, A, g, l, n_poles, p, r)
599
600
del_Complexes(coeffs)
601
602
cdef inline c_Complex __value(self,c_Complex s,int derivative):
603
return (<c_Lfunction_C *>(self.thisptr)).value(s, derivative)
604
605
cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result):
606
(<c_Lfunction_C *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
607
608
cdef double __typedN(self, double T):
609
return (<c_Lfunction_C *>self.thisptr).N(T)
610
611
cdef void __find_zeros_via_N_v(self, long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec *result):
612
(<c_Lfunction_C *>self.thisptr).find_zeros_via_N_v(count, do_negative, max_refine, rank, test_explicit_formula, result[0])
613
614
### debug tools
615
def _print_data_to_standard_output(self):
616
"""
617
This is used in debugging. It prints out information from
618
the C++ object behind the scenes. It will use standard output.
619
620
EXAMPLES::
621
622
sage: from sage.libs.lcalc.lcalc_Lfunction import *
623
sage: chi=DirichletGroup(5)[1]
624
sage: L=Lfunction_from_character(chi, type="complex")
625
sage: L._print_data_to_standard_output()
626
627
"""
628
(<c_Lfunction_C *>self.thisptr).print_data_L()
629
630
def __dealloc__(self):
631
"""
632
Deallocate memory used
633
"""
634
del_c_Lfunction_C(<c_Lfunction_C *>(self.thisptr))
635
636
637
##############################################################################
638
#Zeta function
639
##############################################################################
640
641
cdef class Lfunction_Zeta(Lfunction):
642
r"""
643
The \class{Lfunction_Zeta} class is used to generate Zeta function
644
645
INPUT: no input
646
"""
647
def __init__(self):
648
r"""
649
Initialize Zeta function
650
651
EXAMPLES::
652
sage: from sage.libs.lcalc.lcalc_Lfunction import *
653
sage: sage.libs.lcalc.lcalc_Lfunction.Lfunction_Zeta()
654
The Zeta function
655
"""
656
657
self.thisptr = new_c_Lfunction_Zeta()
658
self._repr = "The Zeta function"
659
660
cdef inline c_Complex __value(self,c_Complex s,int derivative):
661
return (<c_Lfunction_Zeta *>(self.thisptr)).value(s, derivative, "pure")
662
663
cdef void __find_zeros_v(self, double T1, double T2, double stepsize, doublevec *result):
664
(<c_Lfunction_Zeta *>self.thisptr).find_zeros_v(T1,T2,stepsize,result[0])
665
666
cdef double __typedN(self, double T):
667
return (<c_Lfunction_Zeta *>self.thisptr).N(T)
668
669
cdef void __find_zeros_via_N_v(self, long count,int do_negative,double max_refine, int rank, int test_explicit_formula, doublevec *result):
670
(<c_Lfunction_Zeta *>self.thisptr).find_zeros_via_N_v(count, do_negative, max_refine, rank, test_explicit_formula, result[0])
671
672
def __dealloc__(self):
673
"""
674
Deallocate memory used
675
"""
676
del_c_Lfunction_Zeta(<c_Lfunction_Zeta *>(self.thisptr))
677
678
# def find_zeros_via_N_to_file(self, filename, count=0, do_negative=0, max_refine=1025, rank=-1, test_explicit_formula=0):
679
# """
680
# Find the first "count" number of zeros of the Zeta function, and
681
# write them to the file given by the string filename. This is being
682
# tested so do not use it.
683
684
# EXAMPLES:
685
# """
686
# tmpfile=open(filename,'w')
687
# tmpfile.close()
688
# cdef char *FILE = filename
689
# #test code begins
690
# tmpf = FILE
691
# print
692
# #test code ends
693
# cdef Integer count_I = Integer(count)
694
# cdef Integer do_negative_I = Integer(do_negative)
695
# cdef RealNumber max_refine_R = RRR(max_refine)
696
# cdef Integer rank_I = Integer(rank)
697
# cdef Integer test_explicit_I = Integer(test_explicit_formula)
698
# sig_on()
699
# self.thisptr.find_zeros_via_N(mpz_get_si(count_I.value), mpz_get_si(do_negative_I.value), mpfr_get_d(max_refine_R.value, GMP_RNDN), mpz_get_si(rank_I.value), mpz_get_si(test_explicit_I.value),FILE)
700
# sig_off()
701
702
##############################################################################
703
# Tools
704
##############################################################################
705
706
def Lfunction_from_character(chi, type="complex"):
707
"""
708
Given a primitive Dirichlet Character, this function returns
709
lcalc L-Function Object for that.
710
711
INPUT:
712
chi -- A character in Dirichlet Group
713
use_type -- (default: "complex") type used for Dirichlet coefficients
714
can be "int", "double" or "complex"
715
OUTPUT:
716
L-function object for chi
717
718
EXAMPLES::
719
720
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_character
721
sage: Lfunction_from_character(DirichletGroup(5)[1])
722
L-function with complex Dirichlet coefficients
723
sage: Lfunction_from_character(DirichletGroup(5)[2], type="int")
724
L-function with integer Dirichlet coefficients
725
sage: Lfunction_from_character(DirichletGroup(5)[2], type="double")
726
L-function with real Dirichlet coefficients
727
sage: Lfunction_from_character(DirichletGroup(5)[1], type="int")
728
Traceback (most recent call last):
729
...
730
ValueError: For non quadratic characters you must use type="complex"
731
"""
732
if (not chi.is_primitive()):
733
raise TypeError("Dirichlet character is not primitive")
734
735
modulus=chi.modulus()
736
if (chi(-1) == 1):
737
a=0
738
else:
739
a=1
740
741
Q=(RRR(modulus/pi)).sqrt()
742
poles=[]
743
residues=[]
744
period=modulus
745
OMEGA=1.0/ ( CCC(0,1)**a * (CCC(modulus)).sqrt()/chi.gauss_sum() )
746
747
if type=="complex":
748
dir_coeffs=[CCC(chi(n)) for n in xrange(1,modulus+1)]
749
return Lfunction_C("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
750
if not type in ["double","int"]:
751
raise ValueError("unknown type")
752
if chi.order() != 2:
753
raise ValueError("For non quadratic characters you must use type=\"complex\"")
754
if type=="double":
755
dir_coeffs=[RRR(chi(n)) for n in xrange(1,modulus+1)]
756
return Lfunction_D("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
757
if type=="int":
758
dir_coeffs=[Integer(chi(n)) for n in xrange(1,modulus+1)]
759
return Lfunction_I("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues)
760
761
762
def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000):
763
"""
764
Given an Elliptic Curve E, it returns an L-function Object
765
for E.
766
767
INPUT:
768
E -- An Elliptic Curve
769
number_of_coeffs -- Number of coeffs to be used for contructing L-function object
770
771
OUTPUT:
772
L-function object for E.
773
774
EXAMPLES::
775
776
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_elliptic_curve
777
sage: L = Lfunction_from_elliptic_curve(EllipticCurve('37'))
778
sage: L
779
L-function with real Dirichlet coefficients
780
sage: L.value(0.5).abs() < 1e-15 # "noisy" zero on some platforms (see #9615)
781
True
782
sage: L.value(0.5, derivative=1)
783
0.305999...
784
"""
785
Q=(RRR(E.conductor())).sqrt()/(RRR(2*pi))
786
poles=[]
787
residues=[]
788
import sage.libs.lcalc.lcalc_Lfunction
789
dir_coeffs=E.anlist(number_of_coeffs)
790
dir_coeffs=[RRR(dir_coeffs[i])/(RRR(i)).sqrt() for i in xrange(1,number_of_coeffs)]
791
OMEGA=E.root_number()
792
return Lfunction_D("", 2,dir_coeffs, 0,Q,OMEGA,[1],[.5],poles,residues)
793
794