\(L\)-series for elliptic curves - Elliptic curves

Skip to content
Back to top
View this page
Edit this page

# \(L\)-series for elliptic curves

AUTHORS:

- Simon Spicer (2014-08-15): Added LFunctionZeroSum class interface method

- Jeroen Demeyer (2013-10-17): 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: `SageObject`

  An elliptic curve \(L\)-series.

  L1_vanishes()

    Return 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

        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 (13-isogeny)
        sage: E.lseries().L1_vanishes()
        False

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)])   # 11A  = X_0(11)
        >>> E.lseries().L1_vanishes()
        False
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), Integer(0), Integer(0)])       # X_1(11)
        >>> E.lseries().L1_vanishes()
        False
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)])       # 37A  (rank 1)
        >>> E.lseries().L1_vanishes()
        True
        >>> E = EllipticCurve([Integer(0), Integer(1), Integer(1), -Integer(2), Integer(0)])       # 389A (rank 2)
        >>> E.lseries().L1_vanishes()
        True
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(38), Integer(90)])     # 361A (CM curve))
        >>> E.lseries().L1_vanishes()
        True
        >>> E = EllipticCurve([Integer(0),-Integer(1),Integer(1),-Integer(2),-Integer(1)])         # 141C (13-isogeny)
        >>> E.lseries().L1_vanishes()
        False

    AUTHORS: William Stein, 2005-04-20.

  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

        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 (13-isogeny)
        sage: E.lseries().L_ratio()
        1
        sage: E = EllipticCurve(RationalField(), [1, 0, 0, 1/24624, 1/886464])
        sage: E.lseries().L_ratio()
        2

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)])   # 11A  = X_0(11)
        >>> E.lseries().L_ratio()
        1/5
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), Integer(0), Integer(0)])       # X_1(11)
        >>> E.lseries().L_ratio()
        1/25
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)])       # 37A  (rank 1)
        >>> E.lseries().L_ratio()
        0
        >>> E = EllipticCurve([Integer(0), Integer(1), Integer(1), -Integer(2), Integer(0)])       # 389A (rank 2)
        >>> E.lseries().L_ratio()
        0
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(38), Integer(90)])     # 361A (CM curve))
        >>> E.lseries().L_ratio()
        0
        >>> E = EllipticCurve([Integer(0),-Integer(1),Integer(1),-Integer(2),-Integer(1)])         # 141C (13-isogeny)
        >>> E.lseries().L_ratio()
        1
        >>> E = EllipticCurve(RationalField(), [Integer(1), Integer(0), Integer(0), Integer(1)/Integer(24624), Integer(1)/Integer(886464)])
        >>> E.lseries().L_ratio()
        2

    See Issue #3651 and Issue #15299:

    Sage

        sage: EllipticCurve([0,0,0,-193^2,0]).sha().an()
        4
        sage: EllipticCurve([1, 0, 1, -131, 558]).sha().an()  # long time
        1.00000000000000

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([Integer(0),Integer(0),Integer(0),-Integer(193)**Integer(2),Integer(0)]).sha().an()
        4
        >>> EllipticCurve([Integer(1), Integer(0), Integer(1), -Integer(131), Integer(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\).

    AUTHORS: William Stein, 2005-04-20.

  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 or `None`, use \(k = \sqrt{N}\), where \(N\) is the conductor

    - `prec` – numerical precision in bits; if zero or `None`, use a reasonable automatic default

    OUTPUT:

    A tuple of real numbers `(L, err)` where `L` is an approximation for \(L(E,1)\) and `err` is a bound on the error in the approximation.

    This function is disjoint from the PARI pari:elllseries command, which is for a similar purpose. To use that command (via the PARI C library), simply type `E.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 [Grigov-Jorza-Patrascu-Patrikis-Stein].

    EXAMPLES:

    Sage

        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.52469e-45)
        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.70693e-37
        sage: parent(err)
        Real Field with 24 bits of precision and rounding RNDU

    Python

        >>> from sage.all import *
        >>> L, err = EllipticCurve('11a1').lseries().at1()
        >>> L, err
        (0.253804, 0.000181444)
        >>> parent(L)
        Real Field with 24 bits of precision
        >>> E = EllipticCurve('37b')
        >>> E.lseries().at1()
        (0.7257177, 0.000800697)
        >>> E.lseries().at1(Integer(100))
        (0.7256810619361527823362055410263965487367603361763, 1.52469e-45)
        >>> L,err = E.lseries().at1(Integer(100), prec=Integer(128))
        >>> L
        0.72568106193615278233620554102639654873
        >>> parent(L)
        Real Field with 128 bits of precision
        >>> err
        1.70693e-37
        >>> parent(err)
        Real Field with 24 bits of precision and rounding RNDU

    Rank 1 through 3 elliptic curves:

    Sage

        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)

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.lseries().at1()
        (0.0000000, 0.000000)
        >>> E = EllipticCurve('389a1')
        >>> E.lseries().at1()
        (-0.001769566, 0.00911776)
        >>> E = EllipticCurve('5077a1')
        >>> 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 or `None`, use \(k = \sqrt{N}\), where \(N\) is the conductor

    - `prec` – numerical precision in bits; if zero or `None`, use a reasonable automatic default

    OUTPUT:

    A tuple of real numbers `(L1, err)` where `L1` is an approximation for \(L'(E,1)\) and `err` 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 [Grigorov-Jorza-Patrascu-Patrikis-Stein]. This is exactly the same as the bound for the approximation to \(L(E,1)\) produced by `at1()`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.lseries().deriv_at1()                                               # needs sage.symbolic
        (0.3059866, 0.000801045)
        sage: E.lseries().deriv_at1(100)                                            # needs sage.symbolic
        (0.3059997738340523018204836833216764744526377745903, 1.52493e-45)
        sage: E.lseries().deriv_at1(1000)                                           # needs sage.symbolic
        (0.305999773834052301820483683321676474452637774590771998..., 2.75031e-449)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.lseries().deriv_at1()                                               # needs sage.symbolic
        (0.3059866, 0.000801045)
        >>> E.lseries().deriv_at1(Integer(100))                                            # needs sage.symbolic
        (0.3059997738340523018204836833216764744526377745903, 1.52493e-45)
        >>> E.lseries().deriv_at1(Integer(1000))                                           # needs sage.symbolic
        (0.305999773834052301820483683321676474452637774590771998..., 2.75031e-449)

    With less numerical precision, the error is bounded by numerical accuracy:

    Sage

        sage: # needs sage.symbolic
        sage: L, err = E.lseries().deriv_at1(100, prec=64)
        sage: L, err
        (0.305999773834052302, 5.55318e-18)
        sage: parent(L)
        Real Field with 64 bits of precision
        sage: parent(err)
        Real Field with 24 bits of precision and rounding RNDU

    [Python]

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> L, err = E.lseries().deriv_at1(Integer(100), prec=Integer(64))
        >>> L, err
        (0.305999773834052302, 5.55318e-18)
        >>> parent(L)
        Real Field with 64 bits of precision
        >>> parent(err)
        Real Field with 24 bits of precision and rounding RNDU

    Rank 2 and rank 3 elliptic curves:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: E.lseries().deriv_at1()                                               # needs sage.symbolic
        (0.0000000, 0.000000)
        sage: E = EllipticCurve((1, 0, 1, -131, 558))  # curve 59450i1
        sage: E.lseries().deriv_at1()                                               # needs sage.symbolic
        (-0.00010911444, 0.142428)
        sage: E.lseries().deriv_at1(4000)                                           # needs sage.symbolic
        (6.990...e-50, 1.31318e-43)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> E.lseries().deriv_at1()                                               # needs sage.symbolic
        (0.0000000, 0.000000)
        >>> E = EllipticCurve((Integer(1), Integer(0), Integer(1), -Integer(131), Integer(558)))  # curve 59450i1
        >>> E.lseries().deriv_at1()                                               # needs sage.symbolic
        (-0.00010911444, 0.142428)
        >>> E.lseries().deriv_at1(Integer(4000))                                           # needs sage.symbolic
        (6.990...e-50, 1.31318e-43)

  dokchitser(prec=53, max_imaginary_part=0, max_asymp_coeffs=40, algorithm=None)

    Return an interface 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 (default: 53); bits precision

    - `max_imaginary_part` – real number (default: 0)

    - `max_asymp_coeffs` – integer (default: 40)

    - `algorithm` – string; `'pari'` (default), or `'magma'`

    The default algorithm is “pari”, which returns an interface to Pari’s own general implementation of \(L\)-functions.

    Note

    If algorithm=’magma’, then the precision is in digits rather than bits and the object returned is a Magma \(L\)-series, which has different functionality from the Sage \(L\)-series.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> L = E.lseries().dokchitser()
        >>> L(Integer(2))
        0.381575408260711
        >>> L = E.lseries().dokchitser(algorithm='magma')         # optional - magma
        >>> L.Evaluate(Integer(2))                                         # optional - magma
        0.38157540826071121129371040958008663667709753398892116

    If the curve has too large a conductor, one can still define the \(L\)-series but some computations may not work:

    Sage

        sage: e = EllipticCurve([1,1,0,-63900,-1964465932632])
        sage: L = e.lseries().dokchitser(15)
        sage: L(2)
        0.8309

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve([Integer(1),Integer(1),Integer(0),-Integer(63900),-Integer(1964465932632)])
        >>> L = e.lseries().dokchitser(Integer(15))
        >>> L(Integer(2))
        0.8309

  elliptic_curve()

    Return the elliptic curve that this \(L\)-series is attached to.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> L = E.lseries()
        >>> 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` – integer

    - `prec` – 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 type `sympow('-new_data <n>')`, where `<n>` is replaced by your value of `n`. This command takes a long time to run.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> a = E.lseries().sympow(Integer(2),Integer(16))   # not tested - requires precomputing "sympow('-new_data 2')"
        >>> a                              # not tested
        '2.492262044273650E+00'
        >>> RR(a)                          # not tested
        2.49226204427365

  sympow_derivs(n, prec, d)

    Return \(0\)-th to \(d\)-th derivatives of \(L( Sym^{(n)}(E, \text{edge}))\) to `prec` digits of precision.

    INPUT:

    - `n` – integer

    - `prec` – integer

    - `d` – integer

    OUTPUT: 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

        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.837774351482055E-01
         1w0: 3.777214305638848E-01
         1n1: 3.059997738340522E-01
         1w1: 3.059997738340524E-01
         1n2: 1.519054910249753E-01
         1w2: 1.545605024269432E-01

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> print(E.lseries().sympow_derivs(Integer(1),Integer(16),Integer(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.837774351482055E-01
         1w0: 3.777214305638848E-01
         1n1: 3.059997738340522E-01
         1w1: 3.059997738340524E-01
         1n2: 1.519054910249753E-01
         1w2: 1.545605024269432E-01

  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 view `var` as equal to \(s-a\). Thus this function returns the formal power series whose coefficients are \(L^{(n)}(a)/n!\).

    INPUT:

    - `a` – complex number

    - `prec` – integer; precision in bits (default: 53)

    - `series_prec` – integer (default: 6)

    - `var` – variable (default: `'z'`)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a')
        sage: L = E.lseries()
        sage: L.taylor_series(series_prec=3)   # abs tol 1e-14
        1.34667664606157e-19 + (-7.63157535163667e-20)*z + 0.759316500288427*z^2 + O(z^3)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> L = E.lseries()
        >>> L.taylor_series(series_prec=Integer(3))   # abs tol 1e-14
        1.34667664606157e-19 + (-7.63157535163667e-20)*z + 0.759316500288427*z^2 + O(z^3)

  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 \(L\)-series is normalized so that the center of the critical strip is 1.

    INPUT:

    - `s` – complex numbers

    - `dmin` – integer

    - `dmax` – integer

    OUTPUT:

    - list of pairs \((d, L(E, s, \chi_d))\)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: vals = E.lseries().twist_values(1, -12, -4)
        sage: vals[0][0]
        -11
        sage: vals[0][1] # abs tol 1e-8
        1.47824342 + 0.0*I
        sage: vals[1][0]
        -8
        sage: vals[1][1] # abs tol 1e-8
        0.0 + 0.0*I
        sage: vals[2][0]
        -7
        sage: vals[2][1] # abs tol 1e-8
        1.85307619 + 0.0*I
        sage: vals[3][0]
        -4
        sage: vals[3][1] # abs tol 1e-8
        2.45138938 + 0.0*I
        sage: F = E.quadratic_twist(-8)
        sage: F.rank()
        1
        sage: F = E.quadratic_twist(-7)
        sage: F.rank()
        0

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> vals = E.lseries().twist_values(Integer(1), -Integer(12), -Integer(4))
        >>> vals[Integer(0)][Integer(0)]
        -11
        >>> vals[Integer(0)][Integer(1)] # abs tol 1e-8
        1.47824342 + 0.0*I
        >>> vals[Integer(1)][Integer(0)]
        -8
        >>> vals[Integer(1)][Integer(1)] # abs tol 1e-8
        0.0 + 0.0*I
        >>> vals[Integer(2)][Integer(0)]
        -7
        >>> vals[Integer(2)][Integer(1)] # abs tol 1e-8
        1.85307619 + 0.0*I
        >>> vals[Integer(3)][Integer(0)]
        -4
        >>> vals[Integer(3)][Integer(1)] # abs tol 1e-8
        2.45138938 + 0.0*I
        >>> F = E.quadratic_twist(-Integer(8))
        >>> F.rank()
        1
        >>> F = E.quadratic_twist(-Integer(7))
        >>> 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 \(L\)-series is normalized so that the center of the critical strip is 1.

    INPUT:

    - `n` – integer

    - `dmin` – integer

    - `dmax` – integer

    OUTPUT:

    - `dict` – keys are the discriminants \(d\), and values are list of corresponding zeros

    EXAMPLES:

    Sage

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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.lseries().twist_zeros(Integer(3), -Integer(4), -Integer(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` equally-spaced 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 numbers

    - `number_samples` – integer

    OUTPUT:

    list – list of pairs (\(s\), \(L(E,s)\)), where the \(s\) are

      equally spaced sampled points on the line from `s0` to `s1`.

    EXAMPLES:

    Sage

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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.lseries().values_along_line(Integer(1), RealNumber('0.5') + Integer(20)*I, Integer(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 of `self`.

    This can be used to bound analytic rank from above without having to compute with the \(L\)-series directly.

    INPUT:

    - `N` – (default: `None`) if not `None`, the conductor of the elliptic curve attached to `self`. 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

        sage: E = EllipticCurve("5077a")
        sage: E.lseries().zero_sums()
        Zero sum estimator for L-function attached to
         Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("5077a")
        >>> E.lseries().zero_sums()
        Zero sum estimator for L-function 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 32-bit reals.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.lseries().zeros(Integer(2))
        [0.000000000, 5.00317001]

        >>> a = E.lseries().zeros(Integer(20))             # long time
        >>> point([(Integer(1),x) for x in a])             # graph  (long time)
        Graphics object consisting of 1 graphics primitive

    AUTHORS: Uses Rubinstein’s L-functions 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` and `y`, along with a technical quantity for each.

    INPUT:

    - `x` – positive floating point number

    - `y` – positive floating point number

    - `stepsize` – 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

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

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.lseries().zeros_in_interval(Integer(6), Integer(10), RealNumber('0.1'))      # long time
        [(6.87039122, 0.248922780), (8.01433081, -0.140168533), (9.93309835, -0.129943029)]