\(L\)series for elliptic curves¶
AUTHORS:
 Simon Spicer (20140815)  Added LFunctionZeroSum class interface method
 Jeroen Demeyer (20131017)  Compute L series with arbitrary precision instead of floats.
 William Stein et al. (2005 and later)

class
sage.schemes.elliptic_curves.lseries_ell.
Lseries_ell
(E)¶ Bases:
sage.structure.sage_object.SageObject
An elliptic curve \(L\)series.

L1_vanishes
()¶ Returns whether or not \(L(E,1) = 0\). The result is provably correct if the Manin constant of the associated optimal quotient is <= 2. This hypothesis on the Manin constant is true for all curves of conductor <= 40000 (by Cremona) and all semistable curves (i.e., squarefree conductor).
ALGORITHM: see
L_ratio()
.EXAMPLES:
sage: E = EllipticCurve([0, 1, 1, 10, 20]) # 11A = X_0(11) sage: E.lseries().L1_vanishes() False sage: E = EllipticCurve([0, 1, 1, 0, 0]) # X_1(11) sage: E.lseries().L1_vanishes() False sage: E = EllipticCurve([0, 0, 1, 1, 0]) # 37A (rank 1) sage: E.lseries().L1_vanishes() True sage: E = EllipticCurve([0, 1, 1, 2, 0]) # 389A (rank 2) sage: E.lseries().L1_vanishes() True sage: E = EllipticCurve([0, 0, 1, 38, 90]) # 361A (CM curve)) sage: E.lseries().L1_vanishes() True sage: E = EllipticCurve([0,1,1,2,1]) # 141C (13isogeny) sage: E.lseries().L1_vanishes() False
AUTHOR: William Stein, 20050420.

L_ratio
()¶ Return the ratio \(L(E,1) / \Omega\) as an exact rational number.
The result is provably correct if the Manin constant of the associated optimal quotient is \(\leq 2\). This hypothesis on the Manin constant is true for all semistable curves (i.e., squarefree conductor), by a theorem of Mazur from his Rational Isogenies of Prime Degree paper.
EXAMPLES:
sage: E = EllipticCurve([0, 1, 1, 10, 20]) # 11A = X_0(11) sage: E.lseries().L_ratio() 1/5 sage: E = EllipticCurve([0, 1, 1, 0, 0]) # X_1(11) sage: E.lseries().L_ratio() 1/25 sage: E = EllipticCurve([0, 0, 1, 1, 0]) # 37A (rank 1) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 1, 1, 2, 0]) # 389A (rank 2) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 0, 1, 38, 90]) # 361A (CM curve)) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0,1,1,2,1]) # 141C (13isogeny) sage: E.lseries().L_ratio() 1 sage: E = EllipticCurve(RationalField(), [1, 0, 0, 1/24624, 1/886464]) sage: E.lseries().L_ratio() 2
See trac ticket #3651 and trac ticket #15299:
sage: EllipticCurve([0,0,0,193^2,0]).sha().an() 4 sage: EllipticCurve([1, 0, 1, 131, 558]).sha().an() # long time 1.00000000000000
ALGORITHM: Compute the root number. If it is 1 then \(L(E,s)\) vanishes to odd order at 1, hence vanishes. If it is +1, use a result about modular symbols and Mazur’s Rational Isogenies paper to determine a provably correct bound (assuming Manin constant is <= 2) so that we can determine whether \(L(E,1) = 0\).
AUTHOR: William Stein, 20050420.

at1
(k=None, prec=None)¶ Compute \(L(E,1)\) using \(k\) terms of the series for \(L(E,1)\) as explained in Section 7.5.3 of Henri Cohen’s book A Course in Computational Algebraic Number Theory. If the argument \(k\) is not specified, then it defaults to \(\sqrt{N}\), where \(N\) is the conductor.
INPUT:
k
– number of terms of the series. If zero orNone
, use \(k = \sqrt{N}\), where \(N\) is the conductor.prec
– numerical precision in bits. If zero orNone
, use a reasonable automatic default.
OUTPUT:
A tuple of real numbers
(L, err)
whereL
is an approximation for \(L(E,1)\) anderr
is a bound on the error in the approximation.This function is disjoint from the PARI
elllseries
command, which is for a similar purpose. To use that command (via the PARI C library), simply typeE.pari_mincurve().elllseries(1)
.ALGORITHM:
Compute the root number eps. If it is 1, return 0.
Compute the Fourier coefficients \(a_n\), for \(n\) up to and including \(k\).
Compute the sum
\[2 \cdot \sum_{n=1}^{k} \frac{a_n}{n} \cdot \exp(2*pi*n/\sqrt{N}),\]where \(N\) is the conductor of \(E\).
Compute a bound on the tail end of the series, which is
\[2 e^{2 \pi (k+1) / \sqrt{N}} / (1  e^{2 \pi/\sqrt{N}}).\]For a proof see [GrigovJorzaPatrascuPatrikisStein].
EXAMPLES:
sage: L, err = EllipticCurve('11a1').lseries().at1() sage: L, err (0.253804, 0.000181444) sage: parent(L) Real Field with 24 bits of precision sage: E = EllipticCurve('37b') sage: E.lseries().at1() (0.7257177, 0.000800697) sage: E.lseries().at1(100) (0.7256810619361527823362055410263965487367603361763, 1.52469e45) sage: L,err = E.lseries().at1(100, prec=128) sage: L 0.72568106193615278233620554102639654873 sage: parent(L) Real Field with 128 bits of precision sage: err 1.70693e37 sage: parent(err) Real Field with 24 bits of precision and rounding RNDU
Rank 1 through 3 elliptic curves:
sage: E = EllipticCurve('37a1') sage: E.lseries().at1() (0.0000000, 0.000000) sage: E = EllipticCurve('389a1') sage: E.lseries().at1() (0.001769566, 0.00911776) sage: E = EllipticCurve('5077a1') sage: E.lseries().at1() (0.0000000, 0.000000)

deriv_at1
(k=None, prec=None)¶ Compute \(L'(E,1)\) using \(k\) terms of the series for \(L'(E,1)\), under the assumption that \(L(E,1) = 0\).
The algorithm used is from Section 7.5.3 of Henri Cohen’s book A Course in Computational Algebraic Number Theory.
INPUT:
k
– number of terms of the series. If zero orNone
, use \(k = \sqrt{N}\), where \(N\) is the conductor.prec
– numerical precision in bits. If zero orNone
, use a reasonable automatic default.
OUTPUT:
A tuple of real numbers
(L1, err)
whereL1
is an approximation for \(L'(E,1)\) anderr
is a bound on the error in the approximation.Warning
This function only makes sense if \(L(E)\) has positive order of vanishing at 1, or equivalently if \(L(E,1) = 0\).
ALGORITHM:
Compute the root number eps. If it is 1, return 0.
Compute the Fourier coefficients \(a_n\), for \(n\) up to and including \(k\).
Compute the sum
\[2 \cdot \sum_{n=1}^{k} (a_n / n) \cdot E_1(2 \pi n/\sqrt{N}),\]where \(N\) is the conductor of \(E\), and \(E_1\) is the exponential integral function.
Compute a bound on the tail end of the series, which is
\[2 e^{2 \pi (k+1) / \sqrt{N}} / (1  e^{2 \pi/\sqrt{N}}).\]For a proof see [GrigorovJorzaPatrascuPatrikisStein]. This is exactly the same as the bound for the approximation to \(L(E,1)\) produced by
at1()
.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: E.lseries().deriv_at1() (0.3059866, 0.000801045) sage: E.lseries().deriv_at1(100) (0.3059997738340523018204836833216764744526377745903, 1.52493e45) sage: E.lseries().deriv_at1(1000) (0.305999773834052301820483683321676474452637774590771998..., 2.75031e449)
With less numerical precision, the error is bounded by numerical accuracy:
sage: L,err = E.lseries().deriv_at1(100, prec=64) sage: L,err (0.305999773834052302, 5.55318e18) sage: parent(L) Real Field with 64 bits of precision sage: parent(err) Real Field with 24 bits of precision and rounding RNDU
Rank 2 and rank 3 elliptic curves:
sage: E = EllipticCurve('389a1') sage: E.lseries().deriv_at1() (0.0000000, 0.000000) sage: E = EllipticCurve((1, 0, 1, 131, 558)) # curve 59450i1 sage: E.lseries().deriv_at1() (0.00010911444, 0.142428) sage: E.lseries().deriv_at1(4000) (6.990...e50, 1.31318e43)

dokchitser
(prec=53, max_imaginary_part=0, max_asymp_coeffs=40, algorithm='gp')¶ Return interface to Tim Dokchitser’s program for computing with the \(L\)series of this elliptic curve; this provides a way to compute Taylor expansions and higher derivatives of \(L\)series.
INPUT:
prec
– integer (bits precision)max_imaginary_part
– real numbermax_asymp_coeffs
– integeralgorithm
– string: ‘gp’ or ‘magma’
Note
If algorithm=’magma’, then the precision is in digits rather than bits and the object returned is a Magma Lseries, which has different functionality from the Sage Lseries.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: L = E.lseries().dokchitser() sage: L(2) 0.381575408260711 sage: L = E.lseries().dokchitser(algorithm='magma') # optional  magma sage: L.Evaluate(2) # optional  magma 0.38157540826071121129371040958008663667709753398892116
If the curve has too large a conductor, it isn’t possible to compute with the \(L\)series using this command. Instead a
RuntimeError
is raised:sage: e = EllipticCurve([1,1,0,63900,1964465932632]) sage: L = e.lseries().dokchitser(15) Traceback (most recent call last): ... RuntimeError: Unable to create Lseries, due to precision or other limits in PARI.

elliptic_curve
()¶ Return the elliptic curve that this \(L\)series is attached to.
EXAMPLES:
sage: E = EllipticCurve('389a') sage: L = E.lseries() sage: L.elliptic_curve () Elliptic Curve defined by y^2 + y = x^3 + x^2  2*x over Rational Field

sympow
(n, prec)¶ Return \(L( Sym^{(n)}(E, \text{edge}))\) to
prec
digits of precision.INPUT:
n
– integerprec
– integer
OUTPUT:
 string – real number to prec digits of precision as a string.
Note
Before using this function for the first time for a given
n
, you may have to typesympow('new_data <n>')
, where<n>
is replaced by your value ofn
. This command takes a long time to run.EXAMPLES:
sage: E = EllipticCurve('37a') sage: a = E.lseries().sympow(2,16) # not tested  requires precomputing "sympow('new_data 2')" sage: a # not tested '2.492262044273650E+00' sage: RR(a) # not tested 2.49226204427365

sympow_derivs
(n, prec, d)¶ Return 0th to \(d\)th derivatives of \(L( Sym^{(n)}(E, \text{edge}))\) to
prec
digits of precision.INPUT:
 n – integer
 prec – integer
 d – integer
OUTPUT:
 a string, exactly as output by sympow
Note
To use this function you may have to run a few commands like
sympow('new_data 1d2')
, each which takes a few minutes. If this function fails it will indicate what commands have to be run.EXAMPLES:
sage: E = EllipticCurve('37a') sage: print(E.lseries().sympow_derivs(1,16,2)) # not tested  requires precomputing "sympow('new_data 2')" sympow 1.018 RELEASE (c) Mark Watkins  see README and COPYING for details Minimal model of curve is [0,0,1,1,0] At 37: Inertia Group is C1 MULTIPLICATIVE REDUCTION Conductor is 37 sp 1: Conductor at 37 is 1+0, root number is 1 sp 1: Euler factor at 37 is 1+1*x 1st sym power conductor is 37, global root number is 1 NT 1d0: 35 NT 1d1: 32 NT 1d2: 28 Maximal number of terms is 35 Done with small primes 1049 Computed: 1d0 1d1 1d2 Checked out: 1d1 1n0: 3.837774351482055E01 1w0: 3.777214305638848E01 1n1: 3.059997738340522E01 1w1: 3.059997738340524E01 1n2: 1.519054910249753E01 1w2: 1.545605024269432E01

taylor_series
(a=1, prec=53, series_prec=6, var='z')¶ Return the Taylor series of this \(L\)series about \(a\) to the given precision (in bits) and the number of terms.
The output is a series in
var
, where you should viewvar
as equal to \(sa\). Thus this function returns the formal power series whose coefficients are \(L^{(n)}(a)/n!\).INPUT:
a
– complex numberprec
– integer, precision in bits (default 53)series_prec
– integer (default 6)var
– variable (default ‘z’)
EXAMPLES:
sage: E = EllipticCurve('389a') sage: L = E.lseries() sage: L.taylor_series(series_prec=3) 1.27685190980159e23 + (7.23588070754027e24)*z + 0.759316500288427*z^2 + O(z^3) # 32bit 2.72911738151096e23 + (1.54658247036311e23)*z + 0.759316500288427*z^2 + O(z^3) # 64bit

twist_values
(s, dmin, dmax)¶ Return values of \(L(E, s, \chi_d)\) for each quadratic character \(\chi_d\) for \(d_{\min} \leq d \leq d_{\max}\).
Note
The Lseries is normalized so that the center of the critical strip is 1.
INPUT:
s
– complex numbersdmin
– integerdmax
– integer
OUTPUT:
 list of pairs \((d, L(E, s, \chi_d))\)
EXAMPLES:
sage: E = EllipticCurve('37a') sage: vals = E.lseries().twist_values(1, 12, 4) sage: vals # abs tol 1e15 [(11, 1.47824342), (8, 8.9590946e18), (7, 1.85307619), (4, 2.45138938)] sage: F = E.quadratic_twist(8) sage: F.rank() 1 sage: F = E.quadratic_twist(7) sage: F.rank() 0

twist_zeros
(n, dmin, dmax)¶ Return first \(n\) real parts of nontrivial zeros of \(L(E,s,\chi_d)\) for each quadratic character \(\chi_d\) with \(d_{\min} \leq d \leq d_{\max}\).
Note
The Lseries is normalized so that the center of the critical strip is 1.
INPUT:
n
– integerdmin
– integerdmax
– integer
OUTPUT:
 dict – keys are the discriminants \(d\), and
 values are list of corresponding zeros.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: E.lseries().twist_zeros(3, 4, 3) # long time {4: [1.60813783, 2.96144840, 3.89751747], 3: [2.06170900, 3.48216881, 4.45853219]}

values_along_line
(s0, s1, number_samples)¶ Return values of \(L(E, s)\) at
number_samples
equallyspaced sample points along the line from \(s_0\) to \(s_1\) in the complex plane.Note
The \(L\)series is normalized so that the center of the critical strip is 1.
INPUT:
s0
,s1
– complex numbersnumber_samples
– integer
OUTPUT:
 list – list of pairs (\(s\), \(L(E,s)\)), where the \(s\) are
 equally spaced sampled points on the line from
s0
tos1
.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: E.lseries().values_along_line(1, 0.5 + 20*I, 5) [(0.500000000, ...), (0.400000000 + 4.00000000*I, 3.31920245  2.60028054*I), (0.300000000 + 8.00000000*I, 0.886341185  0.422640337*I), (0.200000000 + 12.0000000*I, 3.50558936  0.108531690*I), (0.100000000 + 16.0000000*I, 3.87043288  1.88049411*I)]

zero_sums
(N=None)¶ Return an
LFunctionZeroSum
class object for efficient computation of sums over the zeros ofself
.This can be used to bound analytic rank from above without having to compute with the \(L\)series directly.
INPUT:
N
– (default:None
) If notNone
, the conductor of the elliptic curve attached toself
. This is passable so that zero sum computations can be done on curves for which the conductor has been precomputed.
OUTPUT:
A
LFunctionZeroSum_EllipticCurve
instance.EXAMPLES:
sage: E = EllipticCurve("5077a") sage: E.lseries().zero_sums() Zero sum estimator for Lfunction attached to Elliptic Curve defined by y^2 + y = x^3  7*x + 6 over Rational Field

zeros
(n)¶ Return the imaginary parts of the first \(n\) nontrivial zeros on the critical line of the \(L\)function in the upper half plane, as 32bit reals.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: E.lseries().zeros(2) [0.000000000, 5.00317001] sage: a = E.lseries().zeros(20) # long time sage: point([(1,x) for x in a]) # graph (long time) Graphics object consisting of 1 graphics primitive
 AUTHOR:
 – Uses Rubinstein’s Lfunctions calculator.

zeros_in_interval
(x, y, stepsize)¶ Return the imaginary parts of (most of) the nontrivial zeros on the critical line \(\Re(s)=1\) with positive imaginary part between
x
andy
, along with a technical quantity for each.INPUT:
x
– positive floating point numbery
– positive floating point numberstepsize
– positive floating point number
OUTPUT:
 list of pairs
(zero, S(T))
.
Rubinstein writes: The first column outputs the imaginary part of the zero, the second column a quantity related to
S(T)
(it increases roughly by 2 whenever a sign change, i.e. pair of zeros, is missed). Higher up the critical strip you should use a smaller stepsize so as not to miss zeros.EXAMPLES:
sage: E = EllipticCurve('37a') sage: E.lseries().zeros_in_interval(6, 10, 0.1) # long time [(6.87039122, 0.248922780), (8.01433081, 0.140168533), (9.93309835, 0.129943029)]
