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

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
compute_rank()

Computes the analytic rank (the order of vanishing at the center) of of the L-function

EXAMPLES:

sage: chi=DirichletGroup(5)[2] #This is a quadratic character
sage: from sage.libs.lcalc.lcalc_Lfunction import *
sage: L=Lfunction_from_character(chi, type="int")
sage: L.compute_rank()
0
sage: E=EllipticCurve([-82,0])
sage: L=Lfunction_from_elliptic_curve(E, number_of_coeffs=40000)
sage: L.compute_rank()
3
find_zeros(T1, T2, stepsize)

Finds zeros on critical line between T1 and T2 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 bound

  • T2 – a real number giving the upper bound

  • stepsize – 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...]

sage: chi=DirichletGroup(5)[1]
sage: L=Lfunction_from_character(chi, type="complex")
sage: L.find_zeros(-8,8,.1)
[-4.13290370521..., 6.18357819545...]

sage: L=Lfunction_Zeta()
sage: L.find_zeros(10,29.1,.1)
[14.1347251417..., 21.0220396387..., 25.0108575801...]
find_zeros_via_N(count=0, do_negative=False, max_refine=1025, rank=- 1, test_explicit_formula=0)

Finds count number of zeros with positive imaginary part starting at real axis. This function also verifies that all the zeros have been found.

INPUT:

  • count - number of zeros to be found

  • do_negative - (default: False) False to ignore zeros below the real axis.

  • 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.

  • 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)

  • test_explicit_formula - integer (default: 0) If nonzero, test the explicit formula for additional confidence that all the zeros have been found and are accurate. This is still being tested, so using the default is recommended.

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...]

sage: chi=DirichletGroup(5)[1]
sage: L=Lfunction_from_character(chi, type="complex")
sage: L.find_zeros_via_N(3)
[6.18357819545..., 8.45722917442..., 12.6749464170...]

sage: L=Lfunction_Zeta()
sage: L.find_zeros_via_N(3)
[14.1347251417..., 21.0220396387..., 25.0108575801...]
hardy_z_function(s)

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: chi = DirichletGroup(5)[2]  # Quadratic character
sage: from sage.libs.lcalc.lcalc_Lfunction import *
sage: L = Lfunction_from_character(chi, type="int")
sage: L.hardy_z_function(0)
0.231750947504... 
sage: L.hardy_z_function(.5).imag()  # abs tol 1e-15
1.17253174178320e-17
sage: L.hardy_z_function(.4+.3*I)
0.2166144222685... - 0.00408187127850...*I
sage: chi = DirichletGroup(5)[1]
sage: L = Lfunction_from_character(chi, type="complex")
sage: L.hardy_z_function(0)
0.793967590477...
sage: L.hardy_z_function(.5).imag()  # abs tol 1e-15
0.000000000000000
sage: E = EllipticCurve([-82,0])
sage: L = Lfunction_from_elliptic_curve(E, number_of_coeffs=40000)
sage: L.hardy_z_function(2.1)
-0.00643179176869...
sage: L.hardy_z_function(2.1).imag()  # abs tol 1e-15
-3.93833660115668e-19
value(s, derivative=0)

Computes the value of the L-function at s

INPUT:

  • s - a complex number

  • derivative - integer (default: 0) the derivative to be evaluated

  • rotate - (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: chi=DirichletGroup(5)[2] #This is a quadratic character
sage: from sage.libs.lcalc.lcalc_Lfunction import *
sage: L=Lfunction_from_character(chi, type="int")
sage: L.value(.5)  # abs tol 3e-15
0.231750947504016 + 5.75329642226136e-18*I
sage: L.value(.2+.4*I)
0.102558603193... + 0.190840777924...*I

sage: L=Lfunction_from_character(chi, type="double")
sage: L.value(.6)  # abs tol 3e-15
0.274633355856345 + 6.59869267328199e-18*I
sage: L.value(.6+I)
0.362258705721... + 0.433888250620...*I

sage: chi=DirichletGroup(5)[1]
sage: L=Lfunction_from_character(chi, type="complex")
sage: L.value(.5)
0.763747880117... + 0.216964767518...*I
sage: L.value(.6+5*I)
0.702723260619... - 1.10178575243...*I

sage: L=Lfunction_Zeta()
sage: L.value(.5)
-1.46035450880...
sage: L.value(.4+.5*I)
-0.450728958517... - 0.780511403019...*I
class sage.libs.lcalc.lcalc_Lfunction.Lfunction_C

Bases: sage.libs.lcalc.lcalc_Lfunction.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 above

  • OMEGA - See above

  • kappa - List of the values of \(\kappa_j\) in the functional equation

  • gamma - List of the values of \(\gamma_j\) in the functional equation

  • pole - List of the poles of L-function

  • residue - 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

Bases: sage.libs.lcalc.lcalc_Lfunction.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 above

  • OMEGA - See above

  • kappa - List of the values of \(\kappa_j\) in the functional equation

  • gamma - List of the values of \(\gamma_j\) in the functional equation

  • pole - List of the poles of L-function

  • residue - 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

Bases: sage.libs.lcalc.lcalc_Lfunction.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 above

  • OMEGA - See above

  • kappa - List of the values of \(\kappa_j\) in the functional equation

  • gamma - List of the values of \(\gamma_j\) in the functional equation

  • pole - List of the poles of L-function

  • residue - 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

Bases: sage.libs.lcalc.lcalc_Lfunction.Lfunction

The Lfunction_Zeta class is used to generate the Riemann zeta function.

sage.libs.lcalc.lcalc_Lfunction.Lfunction_from_character(chi, type='complex')

Given a primitive Dirichlet character, this function returns an lcalc L-function object for the L-function of the character.

INPUT:

  • chi - A Dirichlet character

  • use_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"
sage.libs.lcalc.lcalc_Lfunction.Lfunction_from_elliptic_curve(E, number_of_coeffs=10000)

Given an elliptic curve E, return an L-function object for the function \(L(s, E)\).

INPUT:

  • E - An elliptic curve

  • number_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-15   # "noisy" zero on some platforms (see #9615)
True
sage: L.value(0.5, derivative=1)
0.305999...