Rubinstein’s lcalc library#
This is a wrapper around Michael Rubinstein’s lcalc. See http://oto.math.uwaterloo.ca/~mrubinst/L_function_public/CODE/.
AUTHORS:
Rishikesh (2010): added compute_rank() and hardy_z_function()
Yann Laigle-Chapuy (2009): refactored
Rishikesh (2009): initial version
- class sage.libs.lcalc.lcalc_Lfunction.Lfunction[source]#
Bases:
object
Initialization of L-function objects. See derived class for details, this class is not supposed to be instantiated directly.
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: Lfunction_from_character(DirichletGroup(5)[1]) L-function with complex Dirichlet coefficients
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> Lfunction_from_character(DirichletGroup(Integer(5))[Integer(1)]) L-function with complex Dirichlet coefficients
- compute_rank()[source]#
Computes the analytic rank (the order of vanishing at the center) of of the L-function
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character sage: L = Lfunction_from_character(chi, type="int") sage: L.compute_rank() 0
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(2)] # This is a quadratic character >>> L = Lfunction_from_character(chi, type="int") >>> L.compute_rank() 0
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: E = EllipticCurve([-82,0]) sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) sage: L.compute_rank() 3
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> E = EllipticCurve([-Integer(82),Integer(0)]) >>> L = Lfunction_from_elliptic_curve(E, number_of_coeffs=Integer(40000)) >>> L.compute_rank() 3
- find_zeros(T1, T2, stepsize)[source]#
Finds zeros on critical line between
T1
andT2
using step size of stepsize. This function might miss zeros if step size is too large. This function computes the zeros of the L-function by using change in signs of areal valued function whose zeros coincide with the zeros of L-function.Use
find_zeros_via_N()
for slower but more rigorous computation.INPUT:
T1
– a real number giving the lower boundT2
– a real number giving the upper boundstepsize
– step size to be used for the zero search
OUTPUT:
list – A list of the imaginary parts of the zeros which were found.
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character sage: L = Lfunction_from_character(chi, type="int") sage: L.find_zeros(5,15,.1) [6.64845334472..., 9.83144443288..., 11.9588456260...] sage: L = Lfunction_from_character(chi, type="double") sage: L.find_zeros(1,15,.1) [6.64845334472..., 9.83144443288..., 11.9588456260...]
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(2)] # This is a quadratic character >>> L = Lfunction_from_character(chi, type="int") >>> L.find_zeros(Integer(5),Integer(15),RealNumber('.1')) [6.64845334472..., 9.83144443288..., 11.9588456260...] >>> L = Lfunction_from_character(chi, type="double") >>> L.find_zeros(Integer(1),Integer(15),RealNumber('.1')) [6.64845334472..., 9.83144443288..., 11.9588456260...]
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] sage: L = Lfunction_from_character(chi, type="complex") sage: L.find_zeros(-8,8,.1) [-4.13290370521..., 6.18357819545...]
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(1)] >>> L = Lfunction_from_character(chi, type="complex") >>> L.find_zeros(-Integer(8),Integer(8),RealNumber('.1')) [-4.13290370521..., 6.18357819545...]
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: L = Lfunction_Zeta() sage: L.find_zeros(10,29.1,.1) [14.1347251417..., 21.0220396387..., 25.0108575801...]
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> L = Lfunction_Zeta() >>> L.find_zeros(Integer(10),RealNumber('29.1'),RealNumber('.1')) [14.1347251417..., 21.0220396387..., 25.0108575801...]
- find_zeros_via_N(count=0, start=0, max_refine=1025, rank=-1)[source]#
Find
count
zeros (in order of increasing magnitude) and output their imaginary parts. This function verifies that no zeros are missed, and that all values output are indeed zeros.If this L-function is self-dual (if its Dirichlet coefficients are real, up to a tolerance of 1e-6), then only the zeros with positive imaginary parts are output. Their conjugates, which are also zeros, are not output.
INPUT:
count
– number of zeros to be foundstart
– (default: 0) how many initial zeros to skipmax_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.rank
– integer (default: -1) analytic rank of the L-function. If -1 is passed, then we attempt to compute it. (Use default if in doubt)
OUTPUT:
list – A list of the imaginary parts of the zeros that have been found
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] #This is a quadratic character sage: L = Lfunction_from_character(chi, type="int") sage: L.find_zeros_via_N(3) [6.64845334472..., 9.83144443288..., 11.9588456260...] sage: L = Lfunction_from_character(chi, type="double") sage: L.find_zeros_via_N(3) [6.64845334472..., 9.83144443288..., 11.9588456260...]
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(2)] #This is a quadratic character >>> L = Lfunction_from_character(chi, type="int") >>> L.find_zeros_via_N(Integer(3)) [6.64845334472..., 9.83144443288..., 11.9588456260...] >>> L = Lfunction_from_character(chi, type="double") >>> L.find_zeros_via_N(Integer(3)) [6.64845334472..., 9.83144443288..., 11.9588456260...]
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] sage: L = Lfunction_from_character(chi, type="complex") sage: zeros = L.find_zeros_via_N(3) sage: (zeros[0] - (-4.13290370521286)).abs() < 1e-8 True sage: (zeros[1] - 6.18357819545086).abs() < 1e-8 True sage: (zeros[2] - 8.45722917442320).abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(1)] >>> L = Lfunction_from_character(chi, type="complex") >>> zeros = L.find_zeros_via_N(Integer(3)) >>> (zeros[Integer(0)] - (-RealNumber('4.13290370521286'))).abs() < RealNumber('1e-8') True >>> (zeros[Integer(1)] - RealNumber('6.18357819545086')).abs() < RealNumber('1e-8') True >>> (zeros[Integer(2)] - RealNumber('8.45722917442320')).abs() < RealNumber('1e-8') True
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: L = Lfunction_Zeta() sage: L.find_zeros_via_N(3) [14.1347251417..., 21.0220396387..., 25.0108575801...]
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> L = Lfunction_Zeta() >>> L.find_zeros_via_N(Integer(3)) [14.1347251417..., 21.0220396387..., 25.0108575801...]
- hardy_z_function(s)[source]#
Computes the Hardy Z-function of the L-function at s
INPUT:
s
– a complex number with imaginary part between -0.5 and 0.5
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # Quadratic character sage: L = Lfunction_from_character(chi, type="int") sage: (L.hardy_z_function(0) - 0.231750947504).abs() < 1e-8 True sage: L.hardy_z_function(0.5).imag().abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(2)] # Quadratic character >>> L = Lfunction_from_character(chi, type="int") >>> (L.hardy_z_function(Integer(0)) - RealNumber('0.231750947504')).abs() < RealNumber('1e-8') True >>> L.hardy_z_function(RealNumber('0.5')).imag().abs() < RealNumber('1e-8') True
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] sage: L = Lfunction_from_character(chi, type="complex") sage: (L.hardy_z_function(0) - 0.793967590477).abs() < 1e-8 True sage: L.hardy_z_function(0.5).imag().abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(1)] >>> L = Lfunction_from_character(chi, type="complex") >>> (L.hardy_z_function(Integer(0)) - RealNumber('0.793967590477')).abs() < RealNumber('1e-8') True >>> L.hardy_z_function(RealNumber('0.5')).imag().abs() < RealNumber('1e-8') True
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: E = EllipticCurve([-82,0]) sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000) sage: (L.hardy_z_function(2.1) - (-0.006431791768)).abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> E = EllipticCurve([-Integer(82),Integer(0)]) >>> L = Lfunction_from_elliptic_curve(E, number_of_coeffs=Integer(40000)) >>> (L.hardy_z_function(RealNumber('2.1')) - (-RealNumber('0.006431791768'))).abs() < RealNumber('1e-8') True
- value(s, derivative=0)[source]#
Computes the value of the L-function at
s
INPUT:
s
– a complex numberderivative
– integer (default: 0) the derivative to be evaluatedrotate
– (default:False
) If True, this returns the value of the Hardy Z-function (sometimes called the Riemann-Siegel Z-function or the Siegel Z-function).
EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[2] # This is a quadratic character sage: L = Lfunction_from_character(chi, type="int") sage: (L.value(0.5) - 0.231750947504016).abs() < 1e-8 True sage: v = L.value(0.2 + 0.4*I) sage: (v - (0.102558603193 + 0.190840777924*I)).abs() < 1e-8 True sage: L = Lfunction_from_character(chi, type="double") sage: (L.value(0.6) - 0.274633355856345).abs() < 1e-8 True sage: v = L.value(0.6 + I) sage: (v - (0.362258705721 + 0.43388825062*I)).abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(2)] # This is a quadratic character >>> L = Lfunction_from_character(chi, type="int") >>> (L.value(RealNumber('0.5')) - RealNumber('0.231750947504016')).abs() < RealNumber('1e-8') True >>> v = L.value(RealNumber('0.2') + RealNumber('0.4')*I) >>> (v - (RealNumber('0.102558603193') + RealNumber('0.190840777924')*I)).abs() < RealNumber('1e-8') True >>> L = Lfunction_from_character(chi, type="double") >>> (L.value(RealNumber('0.6')) - RealNumber('0.274633355856345')).abs() < RealNumber('1e-8') True >>> v = L.value(RealNumber('0.6') + I) >>> (v - (RealNumber('0.362258705721') + RealNumber('0.43388825062')*I)).abs() < RealNumber('1e-8') True
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: chi = DirichletGroup(5)[1] sage: L = Lfunction_from_character(chi, type="complex") sage: v = L.value(0.5) sage: (v - (0.763747880117 + 0.21696476751*I)).abs() < 1e-8 True sage: v = L.value(0.6 + 5*I) sage: (v - (0.702723260619 - 1.10178575243*I)).abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> chi = DirichletGroup(Integer(5))[Integer(1)] >>> L = Lfunction_from_character(chi, type="complex") >>> v = L.value(RealNumber('0.5')) >>> (v - (RealNumber('0.763747880117') + RealNumber('0.21696476751')*I)).abs() < RealNumber('1e-8') True >>> v = L.value(RealNumber('0.6') + Integer(5)*I) >>> (v - (RealNumber('0.702723260619') - RealNumber('1.10178575243')*I)).abs() < RealNumber('1e-8') True
sage: from sage.libs.lcalc.lcalc_Lfunction import * sage: L = Lfunction_Zeta() sage: (L.value(0.5) + 1.46035450880).abs() < 1e-8 True sage: v = L.value(0.4 + 0.5*I) sage: (v - (-0.450728958517 - 0.780511403019*I)).abs() < 1e-8 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import * >>> L = Lfunction_Zeta() >>> (L.value(RealNumber('0.5')) + RealNumber('1.46035450880')).abs() < RealNumber('1e-8') True >>> v = L.value(RealNumber('0.4') + RealNumber('0.5')*I) >>> (v - (-RealNumber('0.450728958517') - RealNumber('0.780511403019')*I)).abs() < RealNumber('1e-8') True
- class sage.libs.lcalc.lcalc_Lfunction.Lfunction_C[source]#
Bases:
Lfunction
The
Lfunction_C
class is used to represent L-functions with complex Dirichlet Coefficients. We assume that L-functions satisfy the following functional equation.\[\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}\]where
\[\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)\]See (23) in arXiv math/0412181
INPUT:
what_type_L
– integer, this should be set to 1 if the coefficients are periodic and 0 otherwise.dirichlet_coefficient
– List of Dirichlet coefficients of the L-function. Only first \(M\) coefficients are needed if they are periodic.period
– If the coefficients are periodic, this should be the period of the coefficients.Q
– See aboveOMEGA
– See abovekappa
– List of the values of \(\kappa_j\) in the functional equationgamma
– List of the values of \(\gamma_j\) in the functional equationpole
– List of the poles of L-functionresidue
– List of the residues of the L-function
Note
If an L-function satisfies \(\Lambda(s) = \omega Q^s \Lambda(k-s)\), by replacing \(s\) by \(s+(k-1)/2\), one can get it in the form we need.
- class sage.libs.lcalc.lcalc_Lfunction.Lfunction_D[source]#
Bases:
Lfunction
The
Lfunction_D
class is used to represent L-functions with real Dirichlet coefficients. We assume that L-functions satisfy the following functional equation.\[\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}\]where
\[\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)\]See (23) in arXiv math/0412181
INPUT:
what_type_L
– integer, this should be set to 1 if the coefficients are periodic and 0 otherwise.dirichlet_coefficient
– List of Dirichlet coefficients of the L-function. Only first \(M\) coefficients are needed if they are periodic.period
– If the coefficients are periodic, this should be the period of the coefficients.Q
– See aboveOMEGA
– See abovekappa
– List of the values of \(\kappa_j\) in the functional equationgamma
– List of the values of \(\gamma_j\) in the functional equationpole
– List of the poles of L-functionresidue
– List of the residues of the L-function
Note
If an L-function satisfies \(\Lambda(s) = \omega Q^s \Lambda(k-s)\), by replacing \(s\) by \(s+(k-1)/2\), one can get it in the form we need.
- class sage.libs.lcalc.lcalc_Lfunction.Lfunction_I[source]#
Bases:
Lfunction
The
Lfunction_I
class is used to represent L-functions with integer Dirichlet Coefficients. We assume that L-functions satisfy the following functional equation.\[\Lambda(s) = \omega Q^s \overline{\Lambda(1-\bar s)}\]where
\[\Lambda(s) = Q^s \left( \prod_{j=1}^a \Gamma(\kappa_j s + \gamma_j) \right) L(s)\]See (23) in arXiv math/0412181
INPUT:
what_type_L
– integer, this should be set to 1 if the coefficients are periodic and 0 otherwise.dirichlet_coefficient
– List of Dirichlet coefficients of the L-function. Only first \(M\) coefficients are needed if they are periodic.period
– If the coefficients are periodic, this should be the period of the coefficients.Q
– See aboveOMEGA
– See abovekappa
– List of the values of \(\kappa_j\) in the functional equationgamma
– List of the values of \(\gamma_j\) in the functional equationpole
– List of the poles of L-functionresidue
– List of the residues of the L-function
Note
If an L-function satisfies \(\Lambda(s) = \omega Q^s \Lambda(k-s)\), by replacing \(s\) by \(s+(k-1)/2\), one can get it in the form we need.
- class sage.libs.lcalc.lcalc_Lfunction.Lfunction_Zeta[source]#
Bases:
Lfunction
The
Lfunction_Zeta
class is used to generate the Riemann zeta function.
- sage.libs.lcalc.lcalc_Lfunction.Lfunction_from_character(chi, type='complex')[source]#
Given a primitive Dirichlet character, this function returns an lcalc L-function object for the L-function of the character.
INPUT:
chi
– A Dirichlet characteruse_type
– string (default: “complex”) type used for the Dirichlet coefficients. This can be “int”, “double” or “complex”.
OUTPUT:
L-function object for
chi
.EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_character sage: Lfunction_from_character(DirichletGroup(5)[1]) L-function with complex Dirichlet coefficients sage: Lfunction_from_character(DirichletGroup(5)[2], type="int") L-function with integer Dirichlet coefficients sage: Lfunction_from_character(DirichletGroup(5)[2], type="double") L-function with real Dirichlet coefficients sage: Lfunction_from_character(DirichletGroup(5)[1], type="int") Traceback (most recent call last): ... ValueError: For non quadratic characters you must use type="complex"
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_character >>> Lfunction_from_character(DirichletGroup(Integer(5))[Integer(1)]) L-function with complex Dirichlet coefficients >>> Lfunction_from_character(DirichletGroup(Integer(5))[Integer(2)], type="int") L-function with integer Dirichlet coefficients >>> Lfunction_from_character(DirichletGroup(Integer(5))[Integer(2)], type="double") L-function with real Dirichlet coefficients >>> Lfunction_from_character(DirichletGroup(Integer(5))[Integer(1)], type="int") Traceback (most recent call last): ... ValueError: For non quadratic characters you must use type="complex"
- sage.libs.lcalc.lcalc_Lfunction.Lfunction_from_elliptic_curve(E, number_of_coeffs=10000)[source]#
Given an elliptic curve E, return an L-function object for the function \(L(s, E)\).
INPUT:
E
– An elliptic curvenumber_of_coeffs
– integer (default: 10000) The number of coefficients to be used when constructing the L-function object. Right now this is fixed at object creation time, and is not automatically set intelligently.
OUTPUT:
L-function object for
L(s, E)
.EXAMPLES:
sage: from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_elliptic_curve sage: L = Lfunction_from_elliptic_curve(EllipticCurve('37')) sage: L L-function with real Dirichlet coefficients sage: L.value(0.5).abs() < 1e-8 True sage: (L.value(0.5, derivative=1) - 0.305999773835200).abs() < 1e-6 True
>>> from sage.all import * >>> from sage.libs.lcalc.lcalc_Lfunction import Lfunction_from_elliptic_curve >>> L = Lfunction_from_elliptic_curve(EllipticCurve('37')) >>> L L-function with real Dirichlet coefficients >>> L.value(RealNumber('0.5')).abs() < RealNumber('1e-8') True >>> (L.value(RealNumber('0.5'), derivative=Integer(1)) - RealNumber('0.305999773835200')).abs() < RealNumber('1e-6') True