Elliptic curves over the rational numbers - Elliptic curves

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

# Elliptic curves over the rational numbers

AUTHORS:

- William Stein (2005): first version

- William Stein (2006-02-26): fixed Lseries_extended which didn’t work because of changes elsewhere in Sage.

- David Harvey (2006-09): Added padic_E2, padic_sigma, padic_height, padic_regulator methods.

- David Harvey (2007-02): reworked padic-height related code

- Christian Wuthrich (2007): added padic sha computation

- David Roe (2007-09): moved sha, l-series and p-adic functionality to separate files.

- John Cremona (2008-01)

- Tobias Nagel and Michael Mardaus (2008-07): added integral_points

- John Cremona (2008-07): further work on integral_points

- Christian Wuthrich (2010-01): moved Galois reps and modular parametrization in a separate file

- Simon Spicer (2013-03): Added code for modular degrees and congruence numbers of higher level

- Simon Spicer (2014-08): Added new analytic rank computation functionality

class sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field(ainvs, **kwds)

  Bases: `EllipticCurve_number_field`

  Elliptic curve over the Rational Field.

  INPUT:

  - `ainvs` – list or tuple \([a_1, a_2, a_3, a_4, a_6]\) of Weierstrass coefficients

  Note

  This class should not be called directly; use `sage.constructor.EllipticCurve` to construct elliptic curves.

  EXAMPLES:

  Construction from Weierstrass coefficients (\(a\)-invariants), long form:

  Sage

      sage: E = EllipticCurve([1,2,3,4,5]); E
      Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field

  Python

      >>> from sage.all import *
      >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)]); E
      Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field

  Construction from Weierstrass coefficients (\(a\)-invariants), short form (sets \(a_1 = a_2 = a_3 = 0\)):

  Sage

      sage: EllipticCurve([4,5]).ainvs()
      (0, 0, 0, 4, 5)

  [Python]

      >>> from sage.all import *
      >>> EllipticCurve([Integer(4),Integer(5)]).ainvs()
      (0, 0, 0, 4, 5)

  Constructor from a Cremona label:

  Sage

      sage: EllipticCurve('389a1')
      Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

  Python

      >>> from sage.all import *
      >>> EllipticCurve('389a1')
      Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field

  Constructor from an LMFDB label:

  Sage

      sage: EllipticCurve('462.f3')
      Elliptic Curve defined by y^2 + x*y = x^3 - 363*x + 1305 over Rational Field

  [Python]

      >>> from sage.all import *
      >>> EllipticCurve('462.f3')
      Elliptic Curve defined by y^2 + x*y = x^3 - 363*x + 1305 over Rational Field

  CPS_height_bound()

    Return the Cremona-Prickett-Siksek height bound. This is a floating point number B such that if P is a rational point on the curve, then \(h(P) \le \hat{h}(P) + B\), where \(h(P)\) is the naive logarithmic height of \(P\) and \(\hat{h}(P)\) is the canonical height.

    See also

    `silverman_height_bound()` for a bound that also works for points over number fields.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("11a")
        sage: E.CPS_height_bound()
        2.8774743273580445
        sage: E = EllipticCurve("5077a")
        sage: E.CPS_height_bound()
        0.0
        sage: E = EllipticCurve([1,2,3,4,1])
        sage: E.CPS_height_bound()
        Traceback (most recent call last):
        ...
        RuntimeError: curve must be minimal.
        sage: F = E.quadratic_twist(-19)
        sage: F
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 1376*x - 130 over Rational Field
        sage: F.CPS_height_bound()
        0.6555158376972852

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("11a")
        >>> E.CPS_height_bound()
        2.8774743273580445
        >>> E = EllipticCurve("5077a")
        >>> E.CPS_height_bound()
        0.0
        >>> E = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(1)])
        >>> E.CPS_height_bound()
        Traceback (most recent call last):
        ...
        RuntimeError: curve must be minimal.
        >>> F = E.quadratic_twist(-Integer(19))
        >>> F
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 1376*x - 130 over Rational Field
        >>> F.CPS_height_bound()
        0.6555158376972852

    IMPLEMENTATION:

    Call the corresponding mwrank C++ library function. Note that the formula in the [CPS2006] paper is given for number fields. It is only the implementation in Sage that restricts to the rational field.

  Lambda(s, prec)

    Return the value of the Lambda-series of the elliptic curve \(E\) at `s`, where `s` can be any complex number.

    IMPLEMENTATION:

    Fairly slow computation using the definitions implemented in Python.

    Uses `prec` terms of the power series.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a')
        sage: E.Lambda(1.4 + 0.5*I, 50)
        -0.354172680517... + 0.874518681720...*I

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> E.Lambda(RealNumber('1.4') + RealNumber('0.5')*I, Integer(50))
        -0.354172680517... + 0.874518681720...*I

  Np(p)

    The number of points on \(E\) modulo \(p\).

    INPUT:

    - `p` – integer; a prime, not necessarily of good reduction

    OUTPUT:

    integer; the number of points on the reduction of \(E\) modulo \(p\) (including the singular point when \(p\) is a prime of bad reduction).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, -1, 1, -10, -20])
        sage: E.Np(2)
        5
        sage: E.Np(3)
        5
        sage: E.conductor()
        11
        sage: E.Np(11)
        11

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)])
        >>> E.Np(Integer(2))
        5
        >>> E.Np(Integer(3))
        5
        >>> E.conductor()
        11
        >>> E.Np(Integer(11))
        11

    This even works when the prime is large:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.Np(next_prime(10^30))
        1000000000000001426441464441649

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.Np(next_prime(Integer(10)**Integer(30)))
        1000000000000001426441464441649

  S_integral_points(S, mw_base='auto', both_signs=False, verbose=False, proof=None)

    Compute all S-integral points (up to sign) on this elliptic curve.

    INPUT:

    - `S` – list of primes

    - `mw_base` – (default: `'auto'` - calls `gens()`) list of EllipticCurvePoint generating the Mordell-Weil group of \(E\)

    - `both_signs` – boolean (default: `False`); if `True` the output contains both \(P\) and \(-P\), otherwise only one of each pair

    - `verbose` – boolean (default: `False`); if `True`, some details of the computation are output

    - `proof` – boolean (default: `True`); if `True` ALL S-integral points will be returned. If `False`, the MW basis will be computed with the `proof=False` flag, and also the time-consuming final call to S_integral_x_coords_with_abs_bounded_by(abs_bound) is omitted. Use this only if the computation takes too long, but be warned that then it cannot be guaranteed that all S-integral points will be found.

    OUTPUT:

    A sorted list of all the S-integral points on E (up to sign unless `both_signs` is `True`).

    Note

    The complexity increases exponentially in the rank of curve E and in the length of S. The computation time (but not the output!) depends on the Mordell-Weil basis. If mw_base is given but is not a basis for the Mordell-Weil group (modulo torsion), S-integral points which are not in the subgroup generated by the given points will almost certainly not be listed.

    EXAMPLES:

    A curve of rank 3 with no torsion points:

    Sage

        sage: E = EllipticCurve([0,0,1,-7,6])
        sage: P1 = E.point((2,0))
        sage: P2 = E.point((-1,3))
        sage: P3 = E.point((4,6))
        sage: a = E.S_integral_points(S=[2,3], mw_base=[P1,P2,P3], verbose=True); a
        max_S: 3 len_S: 3 len_tors: 1
        lambda 0.485997517468...
        k1,k2,k3,k4 7.65200453902598e234 1.31952866480763 3.54035317966420e9 2.42767548272846e17
        p= 2 : trying with p_prec =  30
        mw_base_p_log_val =  [2, 2, 1]
        min_psi =  2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)
        p= 3 : trying with p_prec =  30
        mw_base_p_log_val =  [1, 2, 1]
        min_psi =  3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)
        mw_base [(1 : -1 : 1), (2 : 0 : 1), (0 : -3 : 1)]
        mw_base_log [0.667789378224099, 0.552642660712417, 0.818477222895703]
        mp [5, 7]
        mw_base_p_log [[2^2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^14 + 2^15 + 2^18 + 2^19 + 2^24 + 2^29 + O(2^30), 2^2 + 2^3 + 2^5 + 2^6 + 2^9 + 2^11 + 2^12 + 2^14 + 2^15 + 2^16 + 2^18 + 2^20 + 2^22 + 2^23 + 2^26 + 2^27 + 2^29 + O(2^30), 2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)], [2*3^2 + 2*3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 3^12 + 2*3^14 + 3^15 + 3^17 + 2*3^19 + 2*3^23 + 3^25 + 3^28 + O(3^30), 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 2*3^7 + 2*3^8 + 3^10 + 2*3^12 + 3^13 + 2*3^14 + 3^15 + 3^18 + 3^22 + 3^25 + 2*3^26 + 3^27 + 3^28 + O(3^30), 3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)]]
        k5,k6,k7 0.321154513240... 1.55246328915... 0.161999172489...
        initial bound 2.8057927340...e117
        bound_list [58, 58, 58]
        bound_list [8, 9, 9]
        bound_list [9, 7, 7]
        starting search of points using coefficient bound  9
        x-coords of S-integral points via linear combination of mw_base and torsion:
        [-3, -26/9, -8159/2916, -2759/1024, -151/64, -1343/576, -2, -7/4, -1, -47/256, 0, 1/4, 4/9, 9/16, 58/81, 7/9, 6169/6561, 1, 17/16, 2, 33/16, 172/81, 9/4, 25/9, 3, 31/9, 4, 25/4, 1793/256, 8, 625/64, 11, 14, 21, 37, 52, 6142/81, 93, 4537/36, 342, 406, 816, 207331217/4096]
        starting search of extra S-integer points with absolute value bounded by 3.89321964979420
        x-coords of points with bounded absolute value
        [-3, -2, -1, 0, 1, 2]
        Total number of S-integral points: 43
        [(-3 : -1 : 1),
        (-26/9 : -55/27 : 1),
        (-8159/2916 : -390925/157464 : 1),
        (-2759/1024 : -93587/32768 : 1),
        (-151/64 : -1845/512 : 1),
        (-1343/576 : -50399/13824 : 1),
        (-2 : -4 : 1),
        (-7/4 : -33/8 : 1),
        (-1 : -4 : 1),
        (-47/256 : -13287/4096 : 1),
        (0 : -3 : 1),
        (1/4 : -21/8 : 1),
        (4/9 : -62/27 : 1),
        (9/16 : -133/64 : 1),
        (58/81 : -1288/729 : 1),
        (7/9 : -44/27 : 1),
        (6169/6561 : -641312/531441 : 1),
        (1 : -1 : 1),
        (17/16 : -39/64 : 1),
        (2 : -1 : 1),
        (33/16 : -81/64 : 1),
        (172/81 : -1079/729 : 1),
        (9/4 : -15/8 : 1),
        (25/9 : -91/27 : 1),
        (3 : -4 : 1),
        (31/9 : -143/27 : 1),
        (4 : -7 : 1),
        (25/4 : -119/8 : 1),
        (1793/256 : -73087/4096 : 1),
        (8 : -22 : 1),
        (625/64 : -15351/512 : 1),
        (11 : -36 : 1),
        (14 : -52 : 1),
        (21 : -96 : 1),
        (37 : -225 : 1),
        (52 : -375 : 1),
        (6142/81 : -481429/729 : 1),
        (93 : -897 : 1),
        (4537/36 : -305641/216 : 1),
        (342 : -6325 : 1),
        (406 : -8181 : 1),
        (816 : -23310 : 1),
        (207331217/4096 : -2985362435769/262144 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(7),Integer(6)])
        >>> P1 = E.point((Integer(2),Integer(0)))
        >>> P2 = E.point((-Integer(1),Integer(3)))
        >>> P3 = E.point((Integer(4),Integer(6)))
        >>> a = E.S_integral_points(S=[Integer(2),Integer(3)], mw_base=[P1,P2,P3], verbose=True); a
        max_S: 3 len_S: 3 len_tors: 1
        lambda 0.485997517468...
        k1,k2,k3,k4 7.65200453902598e234 1.31952866480763 3.54035317966420e9 2.42767548272846e17
        p= 2 : trying with p_prec =  30
        mw_base_p_log_val =  [2, 2, 1]
        min_psi =  2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)
        p= 3 : trying with p_prec =  30
        mw_base_p_log_val =  [1, 2, 1]
        min_psi =  3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)
        mw_base [(1 : -1 : 1), (2 : 0 : 1), (0 : -3 : 1)]
        mw_base_log [0.667789378224099, 0.552642660712417, 0.818477222895703]
        mp [5, 7]
        mw_base_p_log [[2^2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^14 + 2^15 + 2^18 + 2^19 + 2^24 + 2^29 + O(2^30), 2^2 + 2^3 + 2^5 + 2^6 + 2^9 + 2^11 + 2^12 + 2^14 + 2^15 + 2^16 + 2^18 + 2^20 + 2^22 + 2^23 + 2^26 + 2^27 + 2^29 + O(2^30), 2 + 2^3 + 2^6 + 2^7 + 2^8 + 2^9 + 2^11 + 2^12 + 2^13 + 2^16 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^24 + 2^28 + O(2^30)], [2*3^2 + 2*3^5 + 2*3^6 + 2*3^7 + 3^8 + 3^9 + 2*3^10 + 3^12 + 2*3^14 + 3^15 + 3^17 + 2*3^19 + 2*3^23 + 3^25 + 3^28 + O(3^30), 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 2*3^7 + 2*3^8 + 3^10 + 2*3^12 + 3^13 + 2*3^14 + 3^15 + 3^18 + 3^22 + 3^25 + 2*3^26 + 3^27 + 3^28 + O(3^30), 3 + 3^2 + 2*3^3 + 3^6 + 2*3^7 + 2*3^8 + 3^9 + 2*3^11 + 2*3^12 + 2*3^13 + 3^15 + 2*3^16 + 3^18 + 2*3^19 + 2*3^22 + 2*3^23 + 2*3^24 + 2*3^27 + 3^28 + 3^29 + O(3^30)]]
        k5,k6,k7 0.321154513240... 1.55246328915... 0.161999172489...
        initial bound 2.8057927340...e117
        bound_list [58, 58, 58]
        bound_list [8, 9, 9]
        bound_list [9, 7, 7]
        starting search of points using coefficient bound  9
        x-coords of S-integral points via linear combination of mw_base and torsion:
        [-3, -26/9, -8159/2916, -2759/1024, -151/64, -1343/576, -2, -7/4, -1, -47/256, 0, 1/4, 4/9, 9/16, 58/81, 7/9, 6169/6561, 1, 17/16, 2, 33/16, 172/81, 9/4, 25/9, 3, 31/9, 4, 25/4, 1793/256, 8, 625/64, 11, 14, 21, 37, 52, 6142/81, 93, 4537/36, 342, 406, 816, 207331217/4096]
        starting search of extra S-integer points with absolute value bounded by 3.89321964979420
        x-coords of points with bounded absolute value
        [-3, -2, -1, 0, 1, 2]
        Total number of S-integral points: 43
        [(-3 : -1 : 1),
        (-26/9 : -55/27 : 1),
        (-8159/2916 : -390925/157464 : 1),
        (-2759/1024 : -93587/32768 : 1),
        (-151/64 : -1845/512 : 1),
        (-1343/576 : -50399/13824 : 1),
        (-2 : -4 : 1),
        (-7/4 : -33/8 : 1),
        (-1 : -4 : 1),
        (-47/256 : -13287/4096 : 1),
        (0 : -3 : 1),
        (1/4 : -21/8 : 1),
        (4/9 : -62/27 : 1),
        (9/16 : -133/64 : 1),
        (58/81 : -1288/729 : 1),
        (7/9 : -44/27 : 1),
        (6169/6561 : -641312/531441 : 1),
        (1 : -1 : 1),
        (17/16 : -39/64 : 1),
        (2 : -1 : 1),
        (33/16 : -81/64 : 1),
        (172/81 : -1079/729 : 1),
        (9/4 : -15/8 : 1),
        (25/9 : -91/27 : 1),
        (3 : -4 : 1),
        (31/9 : -143/27 : 1),
        (4 : -7 : 1),
        (25/4 : -119/8 : 1),
        (1793/256 : -73087/4096 : 1),
        (8 : -22 : 1),
        (625/64 : -15351/512 : 1),
        (11 : -36 : 1),
        (14 : -52 : 1),
        (21 : -96 : 1),
        (37 : -225 : 1),
        (52 : -375 : 1),
        (6142/81 : -481429/729 : 1),
        (93 : -897 : 1),
        (4537/36 : -305641/216 : 1),
        (342 : -6325 : 1),
        (406 : -8181 : 1),
        (816 : -23310 : 1),
        (207331217/4096 : -2985362435769/262144 : 1)]

    It is not necessary to specify mw_base; if it is not provided, then the Mordell-Weil basis must be computed, which may take much longer.

    Sage

        sage: a = E.S_integral_points([2,3])
        sage: len(a)
        43

    [Python]

        >>> from sage.all import *
        >>> a = E.S_integral_points([Integer(2),Integer(3)])
        >>> len(a)
        43

    An example with negative discriminant:

    Sage

        sage: EllipticCurve('900d1').S_integral_points([17], both_signs=True)
        [(-11 : -27 : 1), (-11 : 27 : 1), (-4 : -34 : 1), (-4 : 34 : 1), (4 : -18 : 1),
         (4 : 18 : 1), (2636/289 : -98786/4913 : 1), (2636/289 : 98786/4913 : 1),
         (16 : -54 : 1), (16 : 54 : 1)]

    Python

        >>> from sage.all import *
        >>> EllipticCurve('900d1').S_integral_points([Integer(17)], both_signs=True)
        [(-11 : -27 : 1), (-11 : 27 : 1), (-4 : -34 : 1), (-4 : 34 : 1), (4 : -18 : 1),
         (4 : 18 : 1), (2636/289 : -98786/4913 : 1), (2636/289 : 98786/4913 : 1),
         (16 : -54 : 1), (16 : 54 : 1)]

    Output checked with Magma (corrected in 3 cases):

    Sage

        sage: [len(e.S_integral_points([2], both_signs=False)) for e in cremona_curves([11..100])] # long time (17s on sage.math, 2011)
        [2, 0, 2, 3, 3, 1, 3, 1, 3, 5, 3, 5, 4, 1, 1, 2, 2, 2, 3, 1, 2, 1, 0, 1, 3, 3, 1, 1, 5, 3, 4, 2, 1, 1, 5, 3, 2, 2, 1, 1, 1, 0, 1, 3, 0, 1, 0, 1, 1, 3, 7, 1, 3, 3, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 1, 3, 3, 1, 1, 1, 0, 1, 3, 3, 1, 1, 7, 1, 0, 1, 1, 0, 1, 2, 0, 3, 1, 2, 1, 3, 1, 2, 2, 4, 5, 3, 2, 1, 1, 6, 1, 0, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 3, 1, 5, 1, 2, 4, 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, 0, 0, 1, 0, 1, 1, 6, 1, 0, 1, 1, 0, 4, 3, 1, 2, 1, 2, 3, 1, 1, 1, 1, 8, 3, 1, 2, 1, 2, 0, 8, 2, 0, 6, 2, 3, 1, 1, 1, 3, 1, 3, 2, 1, 3, 1, 2, 1, 6, 9, 3, 3, 1, 1, 2, 3, 1, 1, 5, 5, 1, 1, 0, 1, 1, 2, 3, 1, 1, 2, 3, 1, 3, 1, 1, 1, 1, 0, 0, 1, 3, 3, 1, 3, 1, 1, 2, 2, 0, 0, 6, 1, 0, 1, 1, 1, 1, 3, 1, 2, 6, 3, 1, 2, 2, 1, 1, 1, 1, 7, 5, 4, 3, 3, 1, 1, 1, 1, 1, 1, 8, 5, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 2, 3, 6, 1, 1, 7, 3, 3, 4, 5, 9, 6, 1, 0, 7, 1, 1, 3, 1, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 7, 8, 2, 3, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1]

    [Python]

        >>> from sage.all import *
        >>> [len(e.S_integral_points([Integer(2)], both_signs=False)) for e in cremona_curves((ellipsis_range(Integer(11),Ellipsis,Integer(100))))] # long time (17s on sage.math, 2011)
        [2, 0, 2, 3, 3, 1, 3, 1, 3, 5, 3, 5, 4, 1, 1, 2, 2, 2, 3, 1, 2, 1, 0, 1, 3, 3, 1, 1, 5, 3, 4, 2, 1, 1, 5, 3, 2, 2, 1, 1, 1, 0, 1, 3, 0, 1, 0, 1, 1, 3, 7, 1, 3, 3, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 1, 3, 3, 1, 1, 1, 0, 1, 3, 3, 1, 1, 7, 1, 0, 1, 1, 0, 1, 2, 0, 3, 1, 2, 1, 3, 1, 2, 2, 4, 5, 3, 2, 1, 1, 6, 1, 0, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 3, 1, 5, 1, 2, 4, 1, 1, 1, 1, 1, 0, 1, 0, 2, 2, 0, 0, 1, 0, 1, 1, 6, 1, 0, 1, 1, 0, 4, 3, 1, 2, 1, 2, 3, 1, 1, 1, 1, 8, 3, 1, 2, 1, 2, 0, 8, 2, 0, 6, 2, 3, 1, 1, 1, 3, 1, 3, 2, 1, 3, 1, 2, 1, 6, 9, 3, 3, 1, 1, 2, 3, 1, 1, 5, 5, 1, 1, 0, 1, 1, 2, 3, 1, 1, 2, 3, 1, 3, 1, 1, 1, 1, 0, 0, 1, 3, 3, 1, 3, 1, 1, 2, 2, 0, 0, 6, 1, 0, 1, 1, 1, 1, 3, 1, 2, 6, 3, 1, 2, 2, 1, 1, 1, 1, 7, 5, 4, 3, 3, 1, 1, 1, 1, 1, 1, 8, 5, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 2, 3, 6, 1, 1, 7, 3, 3, 4, 5, 9, 6, 1, 0, 7, 1, 1, 3, 1, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 7, 8, 2, 3, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1]

    An example from [PZGH1999]:

    Sage

        sage: E = EllipticCurve([0,0,0,-172,505])
        sage: E.rank(), len(E.S_integral_points([3,5,7]))  # long time (5s on sage.math, 2011)
        (4, 72)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),-Integer(172),Integer(505)])
        >>> E.rank(), len(E.S_integral_points([Integer(3),Integer(5),Integer(7)]))  # long time (5s on sage.math, 2011)
        (4, 72)

    This is curve “7690e1” which failed until Issue #4805 was fixed:

    Sage

        sage: EllipticCurve([1,1,1,-301,-1821]).S_integral_points([13,2])
        [(-13 : -4 : 1), (-9 : -12 : 1), (-7 : 2 : 1), (21 : -52 : 1),
         (23 : -76 : 1), (63 : -516 : 1), (71 : -620 : 1), (87 : -844 : 1),
         (2711 : -142540 : 1), (7323 : -630376 : 1), (17687 : -2361164 : 1)]

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([Integer(1),Integer(1),Integer(1),-Integer(301),-Integer(1821)]).S_integral_points([Integer(13),Integer(2)])
        [(-13 : -4 : 1), (-9 : -12 : 1), (-7 : 2 : 1), (21 : -52 : 1),
         (23 : -76 : 1), (63 : -516 : 1), (71 : -620 : 1), (87 : -844 : 1),
         (2711 : -142540 : 1), (7323 : -630376 : 1), (17687 : -2361164 : 1)]

    - Some parts of this implementation are partially based on the function integral_points()

    AUTHORS:

    - Tobias Nagel (2008-12)

    - Michael Mardaus (2008-12)

    - John Cremona (2008-12)

  abelian_variety()

    Return `self` as a modular abelian variety.

    OUTPUT: a modular abelian variety

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.abelian_variety()
        Abelian variety J0(11) of dimension 1

        sage: E = EllipticCurve('33a')
        sage: E.abelian_variety()
        Abelian subvariety of dimension 1 of J0(33)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.abelian_variety()
        Abelian variety J0(11) of dimension 1

        >>> E = EllipticCurve('33a')
        >>> E.abelian_variety()
        Abelian subvariety of dimension 1 of J0(33)

  an(n)

    The `n`-th Fourier coefficient of the modular form corresponding to this elliptic curve, where `n` is a positive integer.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: [E.an(n) for n in range(20) if n>0]
        [1, -2, -3, 2, -2, 6, -1, 0, 6, 4, -5, -6, -2, 2, 6, -4, 0, -12, 0]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> [E.an(n) for n in range(Integer(20)) if n>Integer(0)]
        [1, -2, -3, 2, -2, 6, -1, 0, 6, 4, -5, -6, -2, 2, 6, -4, 0, -12, 0]

  analytic_rank(algorithm='pari', leading_coefficient=False)

    Return an integer that is probably the analytic rank of this elliptic curve.

    INPUT:

    - `algorithm` – string (default: `'pari'`):

      - `'pari'` – use the PARI library function

      - `'sympow'` – use Watkins’s program sympow

      - `'rubinstein'` – use Rubinstein’s \(L\)-function C++ program lcalc

      - `'magma'` – use MAGMA

      - `'zero_sum'` – use the rank bounding zero sum method implemented in `analytic_rank_upper_bound()`

      - `'all'` – compute with PARI, sympow and lcalc, check that the answers agree, and return the common answer

    - `leading_coefficient` – boolean (default: `False`); if set to `True`, return a tuple `(rank, lead)` where `lead` is the value of the first nonzero derivative of the \(L\)-function of the elliptic curve. Only implemented for `algorithm='pari'`.

    Note

    If the curve is loaded from the large Cremona database, then the modular degree is taken from the database.

    Of the first three algorithms above, probably Rubinstein’s is the most efficient (in some limited testing done). The zero sum method is often much faster, but can return a value which is strictly larger than the analytic rank. For curves with conductor <=10^9 using default parameters, testing indicates that for 99.75% of curves the returned rank bound is the true rank.

    Note

    If you use `set_verbose(1)`, extra information about the computation will be printed when `algorithm='zero_sum'`.

    Note

    It is an open problem to prove that any particular elliptic curve has analytic rank \(\geq 4\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a')
        sage: E.analytic_rank(algorithm='pari')
        2
        sage: E.analytic_rank(algorithm='rubinstein')
        2
        sage: E.analytic_rank(algorithm='sympow')
        2
        sage: E.analytic_rank(algorithm='magma')    # optional - magma
        2
        sage: E.analytic_rank(algorithm='zero_sum')
        2
        sage: E.analytic_rank(algorithm='all')
        2

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> E.analytic_rank(algorithm='pari')
        2
        >>> E.analytic_rank(algorithm='rubinstein')
        2
        >>> E.analytic_rank(algorithm='sympow')
        2
        >>> E.analytic_rank(algorithm='magma')    # optional - magma
        2
        >>> E.analytic_rank(algorithm='zero_sum')
        2
        >>> E.analytic_rank(algorithm='all')
        2

    With the optional parameter leading_coefficient set to `True`, a tuple of both the analytic rank and the leading term of the \(L\)-series at \(s = 1\) is returned. This only works for `algorithm=='pari'`:

    Sage

        sage: EllipticCurve([0,-1,1,-10,-20]).analytic_rank(leading_coefficient=True)
        (0, 0.25384186085591068...)
        sage: EllipticCurve([0,0,1,-1,0]).analytic_rank(leading_coefficient=True)
        (1, 0.30599977383405230...)
        sage: EllipticCurve([0,1,1,-2,0]).analytic_rank(leading_coefficient=True)
        (2, 1.518633000576853...)
        sage: EllipticCurve([0,0,1,-7,6]).analytic_rank(leading_coefficient=True)
        (3, 10.39109940071580...)
        sage: EllipticCurve([0,0,1,-7,36]).analytic_rank(leading_coefficient=True)
        (4, 196.170903794579...)

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([Integer(0),-Integer(1),Integer(1),-Integer(10),-Integer(20)]).analytic_rank(leading_coefficient=True)
        (0, 0.25384186085591068...)
        >>> EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(1),Integer(0)]).analytic_rank(leading_coefficient=True)
        (1, 0.30599977383405230...)
        >>> EllipticCurve([Integer(0),Integer(1),Integer(1),-Integer(2),Integer(0)]).analytic_rank(leading_coefficient=True)
        (2, 1.518633000576853...)
        >>> EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(7),Integer(6)]).analytic_rank(leading_coefficient=True)
        (3, 10.39109940071580...)
        >>> EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(7),Integer(36)]).analytic_rank(leading_coefficient=True)
        (4, 196.170903794579...)

  analytic_rank_upper_bound(max_Delta=None, adaptive=True, N=None, root_number='compute', bad_primes=None, ncpus=None)

    Return an upper bound for the analytic rank of `self`, conditional on the Generalized Riemann Hypothesis, via computing the zero sum \(\sum_{\gamma} f(\Delta\gamma),\) where \(\gamma\) ranges over the imaginary parts of the zeros of \(L(E,s)\) along the critical strip, \(f(x) = (\sin(\pi x)/(\pi x))^2\), and \(\Delta\) is the tightness parameter whose maximum value is specified by `max_Delta`. This computation can be run on curves with very large conductor (so long as the conductor is known or quickly computable) when \(\Delta\) is not too large (see below). Uses Bober’s rank bounding method as described in [Bob2013].

    INPUT:

    - `max_Delta` – (default: `None`) if not `None`, a positive real value specifying the maximum Delta value used in the zero sum; larger values of Delta yield better bounds - but runtime is exponential in Delta. If left as `None`, Delta is set to \(\min\{\frac{1}{\pi}(\log(N+1000)/2-\log(2\pi)-\eta), 2.5\}\), where \(N\) is the conductor of the curve attached to `self`, and \(\eta\) is the Euler-Mascheroni constant \(= 0.5772...\); the crossover point is at conductor around \(8.3 \cdot 10^8\). For the former value, empirical results show that for about 99.7% of all curves the returned value is the actual analytic rank.

    - `adaptive` – boolean (default: `True`):

      - `True` – the computation is first run with small and then successively larger \(\Delta\) values up to max_Delta. If at any point the computed bound is 0 (or 1 when root_number is -1 or True), the computation halts and that value is returned; otherwise the minimum of the computed bounds is returned.

      - `False` – the computation is run a single time with \(\Delta\) equal to `max_Delta`, and the resulting bound returned

    - `N` – (default: `None`) if not `None`, a positive integer equal to the conductor of `self`. This is passable so that rank estimation can be done for curves whose (large) conductor has been precomputed.

    - `root_number` – (default: `'compute'`) string or integer:

      - `'compute'` – the root number of `self` is computed and used to (possibly) lower the analytic rank estimate by 1.

      - `'ignore'` – the above step is omitted

      - `1` – this value is assumed to be the root number of `self`. This is passable so that rank estimation can be done for curves whose root number has been precomputed.

      - `-1` – this value is assumed to be the root number of `self`. This is passable so that rank estimation can be done for curves whose root number has been precomputed.

    - `bad_primes` – (default: `None`) if not `None`, a list of the primes of bad reduction for the curve attached to `self`. This is passable so that rank estimation can be done for curves of large conductor whose bad primes have been precomputed.

    - `ncpus` – (default: `None`) if not `None`, a positive integer defining the maximum number of CPUs to be used for the computation. If left as None, the maximum available number of CPUs will be used. Note: Due to parallelization overhead, multiple processors will only be used for Delta values \(\ge 1.75\).

    Note

    Output will be incorrect if the incorrect conductor or root number is specified.

    Warning

    Zero sum computation time is exponential in the tightness parameter \(\Delta\), roughly doubling for every increase of 0.1 thereof. Using \(\Delta=1\) (and adaptive=False) will yield a runtime of a few milliseconds; \(\Delta=2\) takes a few seconds, and \(\Delta=3\) may take upwards of an hour. Increase beyond this at your own risk!

    OUTPUT:

    A nonnegative integer greater than or equal to the analytic rank of `self`.

    Note

    If you use set_verbose(1), extra information about the computation will be printed.

    See also

    `LFunctionZeroSum()` `root_number()` `set_verbose()`

    EXAMPLES:

    For most elliptic curves with small conductor the central zero(s) of \(L_E(s)\) are fairly isolated, so small values of \(\Delta\) will yield tight rank estimates.

    Sage

        sage: E = EllipticCurve("11a")
        sage: E.rank()
        0
        sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=False)
        0
        sage: E = EllipticCurve([-39,123])
        sage: E.rank()
        1
        sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=True)
        1

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("11a")
        >>> E.rank()
        0
        >>> E.analytic_rank_upper_bound(max_Delta=Integer(1), adaptive=False)
        0
        >>> E = EllipticCurve([-Integer(39),Integer(123)])
        >>> E.rank()
        1
        >>> E.analytic_rank_upper_bound(max_Delta=Integer(1), adaptive=True)
        1

    This is especially true for elliptic curves with large rank.

    Sage

        sage: for r in range(9):
        ....:     E = elliptic_curves.rank(r)[0]
        ....:     print((r, E.analytic_rank_upper_bound(max_Delta=1,
        ....:                                           adaptive=False,
        ....:                                           root_number='ignore')))
        (0, 0)
        (1, 1)
        (2, 2)
        (3, 3)
        (4, 4)
        (5, 5)
        (6, 6)
        (7, 7)
        (8, 8)

    [Python]

        >>> from sage.all import *
        >>> for r in range(Integer(9)):
        ...     E = elliptic_curves.rank(r)[Integer(0)]
        ...     print((r, E.analytic_rank_upper_bound(max_Delta=Integer(1),
        ...                                           adaptive=False,
        ...                                           root_number='ignore')))
        (0, 0)
        (1, 1)
        (2, 2)
        (3, 3)
        (4, 4)
        (5, 5)
        (6, 6)
        (7, 7)
        (8, 8)

    However, some curves have \(L\)-functions with low-lying zeroes, and for these larger values of \(\Delta\) must be used to get tight estimates.

    Sage

        sage: E = EllipticCurve("974b1")
        sage: r = E.rank(); r
        0
        sage: E.analytic_rank_upper_bound(max_Delta=1, root_number='ignore')
        1
        sage: E.analytic_rank_upper_bound(max_Delta=1.3, root_number='ignore')
        0

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("974b1")
        >>> r = E.rank(); r
        0
        >>> E.analytic_rank_upper_bound(max_Delta=Integer(1), root_number='ignore')
        1
        >>> E.analytic_rank_upper_bound(max_Delta=RealNumber('1.3'), root_number='ignore')
        0

    Knowing the root number of \(E\) allows us to use smaller Delta values to get tight bounds, thus speeding up runtime considerably.

    Sage

        sage: E.analytic_rank_upper_bound(max_Delta=0.6, root_number='compute')
        0

    [Python]

        >>> from sage.all import *
        >>> E.analytic_rank_upper_bound(max_Delta=RealNumber('0.6'), root_number='compute')
        0

    There are a small number of curves which have pathologically low-lying zeroes. For these curves, this method will produce a bound that is strictly larger than the analytic rank, unless very large values of Delta are used. The following curve (“256944c1” in the Cremona tables) is a rank 0 curve with a zero at 0.0256…; the smallest Delta value for which the zero sum is strictly less than 2 is ~2.815.

    Sage

        sage: E = EllipticCurve([0, -1, 0, -7460362000712, -7842981500851012704])
        sage: N, r = E.conductor(), E.analytic_rank(); N, r
        (256944, 0)
        sage: E.analytic_rank_upper_bound(max_Delta=1, adaptive=False)
        2
        sage: E.analytic_rank_upper_bound(max_Delta=2, adaptive=False)
        2

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(0), -Integer(7460362000712), -Integer(7842981500851012704)])
        >>> N, r = E.conductor(), E.analytic_rank(); N, r
        (256944, 0)
        >>> E.analytic_rank_upper_bound(max_Delta=Integer(1), adaptive=False)
        2
        >>> E.analytic_rank_upper_bound(max_Delta=Integer(2), adaptive=False)
        2

    This method is can be called on curves with large conductor.

    Sage

        sage: E = EllipticCurve([-2934,19238])
        sage: E.analytic_rank_upper_bound()
        1

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(2934),Integer(19238)])
        >>> E.analytic_rank_upper_bound()
        1

    And it can bound rank on curves with very large conductor, so long as you know beforehand/can easily compute the conductor and primes of bad reduction less than \(e^{2\pi\Delta}\). The example below is of the rank 28 curve discovered by Elkies that is the elliptic curve of (currently) largest known rank.

    Sage

        sage: a4 = -20067762415575526585033208209338542750930230312178956502
        sage: a6 = 34481611795030556467032985690390720374855944359319180361266008296291939448732243429
        sage: E = EllipticCurve([1, -1, 1, a4, a6])
        sage: bad_primes = [2, 3, 5, 7, 11, 13, 17, 19, 48463]
        sage: N = 3455601108357547341532253864901605231198511505793733138900595189472144724781456635380154149870961231592352897621963802238155192936274322687070
        sage: E.analytic_rank_upper_bound(max_Delta=2.37, adaptive=False,  # long time
        ....:                             N=N, root_number=1,
        ....:                             bad_primes=bad_primes, ncpus=2)
        32

    Python

        >>> from sage.all import *
        >>> a4 = -Integer(20067762415575526585033208209338542750930230312178956502)
        >>> a6 = Integer(34481611795030556467032985690390720374855944359319180361266008296291939448732243429)
        >>> E = EllipticCurve([Integer(1), -Integer(1), Integer(1), a4, a6])
        >>> bad_primes = [Integer(2), Integer(3), Integer(5), Integer(7), Integer(11), Integer(13), Integer(17), Integer(19), Integer(48463)]
        >>> N = Integer(3455601108357547341532253864901605231198511505793733138900595189472144724781456635380154149870961231592352897621963802238155192936274322687070)
        >>> E.analytic_rank_upper_bound(max_Delta=RealNumber('2.37'), adaptive=False,  # long time
        ...                             N=N, root_number=Integer(1),
        ...                             bad_primes=bad_primes, ncpus=Integer(2))
        32

  anlist(n, python_ints=False)

    The Fourier coefficients up to and including \(a_n\) of the modular form attached to this elliptic curve. The \(i\)-th element of the return list is `a[i]`.

    INPUT:

    - `n` – integer

    - `python_ints` – boolean (default: `False`); if `True` return a list of Python ints instead of Sage integers

    OUTPUT: list of integers

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, -1, 1, -10, -20])
        sage: E.anlist(3)
        [0, 1, -2, -1]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)])
        >>> E.anlist(Integer(3))
        [0, 1, -2, -1]

    Sage

        sage: E = EllipticCurve([0,1])
        sage: E.anlist(20)
        [0, 1, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 8, 0]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(1)])
        >>> E.anlist(Integer(20))
        [0, 1, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 8, 0]

  antilogarithm(z, max_denominator=None)

    Return the rational point (if any) associated to this complex number; the inverse of the elliptic logarithm function.

    INPUT:

    - `z` – a complex number representing an element of \(\CC/L\) where \(L\) is the period lattice of the elliptic curve

    - `max_denominator` – integer (optional); parameter controlling the attempted conversion of real numbers to rationals. If not given, `simplest_rational()` will be used; otherwise, `nearby_rational()` will be used with this value of `max_denominator`.

    OUTPUT:

    A point on the curve: the rational point which is the image of \(z\) under the Weierstrass parametrization, if it exists and can be determined from \(z\) and the given value of max_denominator (if any); otherwise a `ValueError` exception is raised.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a')
        sage: P = E(-1,1)
        sage: z = P.elliptic_logarithm()
        sage: E.antilogarithm(z)
        (-1 : 1 : 1)
        sage: Q = E(0,-1)
        sage: z = Q.elliptic_logarithm()
        sage: E.antilogarithm(z)
        Traceback (most recent call last):
        ...
        ValueError: approximated point not on the curve
        sage: E.antilogarithm(z, max_denominator=10)
        (0 : -1 : 1)

        sage: E = EllipticCurve('11a1')
        sage: w1,w2 = E.period_lattice().basis()
        sage: [E.antilogarithm(a*w1/5,1) for a in range(5)]
        [(0 : 1 : 0), (16 : -61 : 1), (5 : -6 : 1), (5 : 5 : 1), (16 : 60 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> P = E(-Integer(1),Integer(1))
        >>> z = P.elliptic_logarithm()
        >>> E.antilogarithm(z)
        (-1 : 1 : 1)
        >>> Q = E(Integer(0),-Integer(1))
        >>> z = Q.elliptic_logarithm()
        >>> E.antilogarithm(z)
        Traceback (most recent call last):
        ...
        ValueError: approximated point not on the curve
        >>> E.antilogarithm(z, max_denominator=Integer(10))
        (0 : -1 : 1)

        >>> E = EllipticCurve('11a1')
        >>> w1,w2 = E.period_lattice().basis()
        >>> [E.antilogarithm(a*w1/Integer(5),Integer(1)) for a in range(Integer(5))]
        [(0 : 1 : 0), (16 : -61 : 1), (5 : -6 : 1), (5 : 5 : 1), (16 : 60 : 1)]

  ap(p)

    The `p`-th Fourier coefficient of the modular form corresponding to this elliptic curve, where `p` is prime.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: [E.ap(p) for p in prime_range(50)]
        [-2, -3, -2, -1, -5, -2, 0, 0, 2, 6, -4, -1, -9, 2, -9]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> [E.ap(p) for p in prime_range(Integer(50))]
        [-2, -3, -2, -1, -5, -2, 0, 0, 2, 6, -4, -1, -9, 2, -9]

  aplist(n, python_ints=False)

    The Fourier coefficients \(a_p\) of the modular form attached to this elliptic curve, for all primes \(p\leq n\).

    INPUT:

    - `n` – integer

    - `python_ints` – boolean (default: `False`); if `True` return a list of Python ints instead of Sage integers

    OUTPUT: list of integers

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('37a')
        sage: e.aplist(1)
        []
        sage: e.aplist(2)
        [-2]
        sage: e.aplist(10)
        [-2, -3, -2, -1]
        sage: v = e.aplist(13); v
        [-2, -3, -2, -1, -5, -2]
        sage: type(v[0])
        <... 'sage.rings.integer.Integer'>
        sage: type(e.aplist(13, python_ints=True)[0])
        <... 'int'>

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('37a')
        >>> e.aplist(Integer(1))
        []
        >>> e.aplist(Integer(2))
        [-2]
        >>> e.aplist(Integer(10))
        [-2, -3, -2, -1]
        >>> v = e.aplist(Integer(13)); v
        [-2, -3, -2, -1, -5, -2]
        >>> type(v[Integer(0)])
        <... 'sage.rings.integer.Integer'>
        >>> type(e.aplist(Integer(13), python_ints=True)[Integer(0)])
        <... 'int'>

  cm_discriminant()

    Return the associated quadratic discriminant if this elliptic curve has Complex Multiplication over the algebraic closure.

    A `ValueError` is raised if the curve does not have CM (see the function `has_cm()`).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('32a1')
        sage: E.cm_discriminant()
        -4
        sage: E = EllipticCurve('121b1')
        sage: E.cm_discriminant()
        -11
        sage: E = EllipticCurve('37a1')
        sage: E.cm_discriminant()
        Traceback (most recent call last):
        ...
        ValueError: Elliptic Curve defined by y^2 + y = x^3 - x
        over Rational Field does not have CM

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('32a1')
        >>> E.cm_discriminant()
        -4
        >>> E = EllipticCurve('121b1')
        >>> E.cm_discriminant()
        -11
        >>> E = EllipticCurve('37a1')
        >>> E.cm_discriminant()
        Traceback (most recent call last):
        ...
        ValueError: Elliptic Curve defined by y^2 + y = x^3 - x
        over Rational Field does not have CM

  conductor(algorithm='pari')

    Return the conductor of the elliptic curve.

    INPUT:

    - `algorithm` – string (default: `'pari'`)

      - `'pari'` – use the PARI C-library pari:ellglobalred implementation of Tate’s algorithm

      - `'mwrank'` – use Cremona’s mwrank implementation of Tate’s algorithm; can be faster if the curve has integer coefficients (TODO: limited to small conductor until mwrank gets integer factorization)

      - `'gp'` – use the GP interpreter

      - `'generic'` – use the general number field implementation

      - `'all'` – use all four implementations, verify that the results are the same (or raise an error), and output the common value

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([1, -1, 1, -29372, -1932937])
        sage: E.conductor(algorithm='pari')
        3006
        sage: E.conductor(algorithm='mwrank')
        3006
        sage: E.conductor(algorithm='gp')
        3006
        sage: E.conductor(algorithm='generic')
        3006
        sage: E.conductor(algorithm='all')
        3006

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), -Integer(1), Integer(1), -Integer(29372), -Integer(1932937)])
        >>> E.conductor(algorithm='pari')
        3006
        >>> E.conductor(algorithm='mwrank')
        3006
        >>> E.conductor(algorithm='gp')
        3006
        >>> E.conductor(algorithm='generic')
        3006
        >>> E.conductor(algorithm='all')
        3006

    Note

    The conductor computed using each algorithm is cached separately. Thus calling `E.conductor('pari')`, then `E.conductor('mwrank')` and getting the same result checks that both systems compute the same answer.

  congruence_number(M=1)

    The case \(M==1\) corresponds to the classical definition of congruence number: Let \(X\) be the subspace of \(S_2(\Gamma_0(N))\) spanned by the newform associated with this elliptic curve, and \(Y\) be orthogonal complement of \(X\) under the Petersson inner product. Let \(S_X\) and \(S_Y\) be the intersections of \(X\) and \(Y\) with \(S_2(\Gamma_0(N), \ZZ)\). The congruence number is defined to be \([S_X \oplus S_Y : S_2(\Gamma_0(N),\ZZ)]\). It measures congruences between \(f\) and elements of \(S_2(\Gamma_0(N),\ZZ)\) orthogonal to \(f\).

    The congruence number for higher levels, when M>1, is defined as above, but instead considers \(X\) to be the subspace of \(S_2(\Gamma_0(MN))\) spanned by embeddings into \(S_2(\Gamma_0(MN))\) of the newform associated with this elliptic curve; this subspace has dimension \(\sigma_0(M)\), i.e. the number of divisors of \(M\). Let \(Y\) be the orthogonal complement in \(S_2(\Gamma_0(MN))\) of \(X\) under the Petersson inner product, and \(S_X\) and \(S_Y\) the intersections of \(X\) and \(Y\) with \(S_2(\Gamma_0(MN), \ZZ)\) respectively. Then the congruence number at level \(MN\) is \([S_X \oplus S_Y : S_2(\Gamma_0(MN),\ZZ)]\).

    INPUT:

    - `M` – nonnegative integer; congruence number is computed at level \(MN\), where \(N\) is the conductor of `self`

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.congruence_number()
        2
        sage: E.congruence_number()
        2
        sage: E = EllipticCurve('54b')
        sage: E.congruence_number()
        6
        sage: E.modular_degree()
        2
        sage: E = EllipticCurve('242a1')
        sage: E.modular_degree()
        16
        sage: E.congruence_number()  # long time (4s on sage.math, 2011)
        176

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.congruence_number()
        2
        >>> E.congruence_number()
        2
        >>> E = EllipticCurve('54b')
        >>> E.congruence_number()
        6
        >>> E.modular_degree()
        2
        >>> E = EllipticCurve('242a1')
        >>> E.modular_degree()
        16
        >>> E.congruence_number()  # long time (4s on sage.math, 2011)
        176

    Higher level cases:

    Sage

        sage: E = EllipticCurve('11a')
        sage: for M in range(1,11): print(E.congruence_number(M)) # long time (20s on 2009 MBP)
        1
        1
        3
        2
        7
        45
        12
        4
        18
        245

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> for M in range(Integer(1),Integer(11)): print(E.congruence_number(M)) # long time (20s on 2009 MBP)
        1
        1
        3
        2
        7
        45
        12
        4
        18
        245

    It is a theorem of Ribet that the congruence number (at level \(N\)) is equal to the modular degree in the case of square free conductor. It is a conjecture of Agashe, Ribet, and Stein that \(ord_p(c_f/m_f) \le ord_p(N)/2\).

  cremona_label(space=False)

    Return the Cremona label associated to (the minimal model) of this curve, if it is known. If not, raise a `LookupError` exception.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: E.cremona_label()
        '389a1'

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> E.cremona_label()
        '389a1'

    The default database only contains conductors up to 10000, so any curve with conductor greater than that will cause an error to be raised. The optional package `database_cremona_ellcurve` contains many more curves.

    Sage

        sage: E = EllipticCurve([1, -1, 0, -79, 289])
        sage: E.conductor()
        234446
        sage: E.cremona_label()  # optional - database_cremona_ellcurve
        '234446a1'
        sage: E = EllipticCurve((0, 0, 1, -79, 342))
        sage: E.conductor()
        19047851
        sage: E.cremona_label()
        Traceback (most recent call last):
        ...
        LookupError: Cremona database does not contain entry for
        Elliptic Curve defined by y^2 + y = x^3 - 79*x + 342 over Rational Field

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), -Integer(1), Integer(0), -Integer(79), Integer(289)])
        >>> E.conductor()
        234446
        >>> E.cremona_label()  # optional - database_cremona_ellcurve
        '234446a1'
        >>> E = EllipticCurve((Integer(0), Integer(0), Integer(1), -Integer(79), Integer(342)))
        >>> E.conductor()
        19047851
        >>> E.cremona_label()
        Traceback (most recent call last):
        ...
        LookupError: Cremona database does not contain entry for
        Elliptic Curve defined by y^2 + y = x^3 - 79*x + 342 over Rational Field

  database_attributes()

    Return a dictionary containing information about `self` in the elliptic curve database.

    If there is no elliptic curve isomorphic to `self` in the database, a `LookupError` is raised.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve((0, 0, 1, -1, 0))
        sage: data = E.database_attributes()
        sage: data['conductor']
        37
        sage: data['cremona_label']
        '37a1'
        sage: data['rank']
        1
        sage: data['torsion_order']
        1

        sage: E = EllipticCurve((8, 13, 21, 34, 55))
        sage: E.database_attributes()
        Traceback (most recent call last):
        ...
        LookupError: Cremona database does not contain entry for Elliptic Curve
        defined by y^2 + 8*x*y + 21*y = x^3 + 13*x^2 + 34*x + 55 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve((Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)))
        >>> data = E.database_attributes()
        >>> data['conductor']
        37
        >>> data['cremona_label']
        '37a1'
        >>> data['rank']
        1
        >>> data['torsion_order']
        1

        >>> E = EllipticCurve((Integer(8), Integer(13), Integer(21), Integer(34), Integer(55)))
        >>> E.database_attributes()
        Traceback (most recent call last):
        ...
        LookupError: Cremona database does not contain entry for Elliptic Curve
        defined by y^2 + 8*x*y + 21*y = x^3 + 13*x^2 + 34*x + 55 over Rational Field

  database_curve()

    Return the curve in the elliptic curve database isomorphic to this curve, if possible. Otherwise raise a `LookupError` exception.

    Since Issue #11474, this returns exactly the same curve as `minimal_model()`; the only difference is the additional work of checking whether the curve is in the database.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0,1,2,3,4])
        sage: E.database_curve()
        Elliptic Curve defined by y^2  = x^3 + x^2 + 3*x + 5 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(1),Integer(2),Integer(3),Integer(4)])
        >>> E.database_curve()
        Elliptic Curve defined by y^2  = x^3 + x^2 + 3*x + 5 over Rational Field

    Note

    The model of the curve in the database can be different from the Weierstrass model for this curve, e.g., database models are always minimal.

  elliptic_exponential(z, embedding=None)

    Compute the elliptic exponential of a complex number with respect to the elliptic curve.

    INPUT:

    - `z` – a complex number

    - `embedding` – ignored (for compatibility with the period_lattice function for elliptic_curve_number_field)

    OUTPUT:

    The image of \(z\) modulo \(L\) under the Weierstrass parametrization \(\CC/L \to E(\CC)\).

    Note

    The precision is that of the input `z`, or the default precision of 53 bits if `z` is exact.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([1,1,1,-8,6])
        sage: P = E([1,-2])
        sage: z = P.elliptic_logarithm() # default precision is 100 here
        sage: E.elliptic_exponential(z)
        (1.0000000000000000000000000000 : -2.0000000000000000000000000000 : 1.0000000000000000000000000000)
        sage: z = E([1,-2]).elliptic_logarithm(precision=201)
        sage: E.elliptic_exponential(z)
        (1.00000000000000000000000000000000000000000000000000000000000 : -2.00000000000000000000000000000000000000000000000000000000000 : 1.00000000000000000000000000000000000000000000000000000000000)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1),Integer(1),Integer(1),-Integer(8),Integer(6)])
        >>> P = E([Integer(1),-Integer(2)])
        >>> z = P.elliptic_logarithm() # default precision is 100 here
        >>> E.elliptic_exponential(z)
        (1.0000000000000000000000000000 : -2.0000000000000000000000000000 : 1.0000000000000000000000000000)
        >>> z = E([Integer(1),-Integer(2)]).elliptic_logarithm(precision=Integer(201))
        >>> E.elliptic_exponential(z)
        (1.00000000000000000000000000000000000000000000000000000000000 : -2.00000000000000000000000000000000000000000000000000000000000 : 1.00000000000000000000000000000000000000000000000000000000000)

    Sage

        sage: E = EllipticCurve('389a')
        sage: Q = E([3,5])
        sage: E.elliptic_exponential(Q.elliptic_logarithm())
        (3.0000000000000000000000000000 : 5.0000000000000000000000000000 : 1.0000000000000000000000000000)
        sage: P = E([-1,1])
        sage: P.elliptic_logarithm()
        0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
        sage: E.elliptic_exponential(P.elliptic_logarithm())
        (-1.0000000000000000000000000000 : 1.0000000000000000000000000000 : 1.0000000000000000000000000000)

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> Q = E([Integer(3),Integer(5)])
        >>> E.elliptic_exponential(Q.elliptic_logarithm())
        (3.0000000000000000000000000000 : 5.0000000000000000000000000000 : 1.0000000000000000000000000000)
        >>> P = E([-Integer(1),Integer(1)])
        >>> P.elliptic_logarithm()
        0.47934825019021931612953301006 + 0.98586885077582410221120384908*I
        >>> E.elliptic_exponential(P.elliptic_logarithm())
        (-1.0000000000000000000000000000 : 1.0000000000000000000000000000 : 1.0000000000000000000000000000)

    Some torsion examples:

    Sage

        sage: w1,w2 = E.period_lattice().basis()
        sage: E.two_division_polynomial().roots(CC,multiplicities=False)
        [-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]
        sage: [E.elliptic_exponential((a*w1+b*w2)/2)[0] for a,b in [(0,1),(1,1),(1,0)]]
        [-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]

        sage: E.division_polynomial(3).roots(CC,multiplicities=False)
        [-2.88288879135...,
         1.39292799513...,
         0.078313731444316... - 0.492840991709...*I,
         0.078313731444316... + 0.492840991709...*I]
        sage: [E.elliptic_exponential((a*w1+b*w2)/3)[0] for a,b in [(0,1),(1,0),(1,1),(2,1)]]
        [-2.8828887913533..., 1.39292799513138,
         0.0783137314443... - 0.492840991709...*I,
         0.0783137314443... + 0.492840991709...*I]

    Python

        >>> from sage.all import *
        >>> w1,w2 = E.period_lattice().basis()
        >>> E.two_division_polynomial().roots(CC,multiplicities=False)
        [-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]
        >>> [E.elliptic_exponential((a*w1+b*w2)/Integer(2))[Integer(0)] for a,b in [(Integer(0),Integer(1)),(Integer(1),Integer(1)),(Integer(1),Integer(0))]]
        [-2.0403022002854..., 0.13540924022175..., 0.90489296006371...]

        >>> E.division_polynomial(Integer(3)).roots(CC,multiplicities=False)
        [-2.88288879135...,
         1.39292799513...,
         0.078313731444316... - 0.492840991709...*I,
         0.078313731444316... + 0.492840991709...*I]
        >>> [E.elliptic_exponential((a*w1+b*w2)/Integer(3))[Integer(0)] for a,b in [(Integer(0),Integer(1)),(Integer(1),Integer(0)),(Integer(1),Integer(1)),(Integer(2),Integer(1))]]
        [-2.8828887913533..., 1.39292799513138,
         0.0783137314443... - 0.492840991709...*I,
         0.0783137314443... + 0.492840991709...*I]

    Observe that this is a group homomorphism (modulo rounding error):

    Sage

        sage: z = CC.random_element()
        sage: v = 2 * E.elliptic_exponential(z)
        sage: w = E.elliptic_exponential(2 * z)
        sage: def err(a, b):
        ....:     err = abs(a - b)
        ....:     if a + b:
        ....:         err = min(err, err / abs(a + b))
        ....:     return err
        sage: err(v[0], w[0]) + err(v[1], w[1])  # abs tol 1e-13
        0.0

    [Python]

        >>> from sage.all import *
        >>> z = CC.random_element()
        >>> v = Integer(2) * E.elliptic_exponential(z)
        >>> w = E.elliptic_exponential(Integer(2) * z)
        >>> def err(a, b):
        ...     err = abs(a - b)
        ...     if a + b:
        ...         err = min(err, err / abs(a + b))
        ...     return err
        >>> err(v[Integer(0)], w[Integer(0)]) + err(v[Integer(1)], w[Integer(1)])  # abs tol 1e-13
        0.0

  eval_modular_form(points, order)

    Evaluate the modular form of this elliptic curve at points in \(\CC\).

    INPUT:

    - `points` – list of points in the upper half-plane

    - `order` – nonnegative integer

    The `order` parameter is the number of terms used in the summation.

    OUTPUT: list of values for \(s\) in `points`

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.eval_modular_form([1.5+I,2.0+I,2.5+I],100)
        [-0.0018743978548152085...,
         0.0018604485340371083...,
        -0.0018743978548152085...]

        sage: E.eval_modular_form(2.1+I, 100) # abs tol 1e-16
        [0.00150864362757267079 + 0.00109100341113449845*I]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.eval_modular_form([RealNumber('1.5')+I,RealNumber('2.0')+I,RealNumber('2.5')+I],Integer(100))
        [-0.0018743978548152085...,
         0.0018604485340371083...,
        -0.0018743978548152085...]

        >>> E.eval_modular_form(RealNumber('2.1')+I, Integer(100)) # abs tol 1e-16
        [0.00150864362757267079 + 0.00109100341113449845*I]

  faltings_height(stable=False, prec=None)

    Return the Faltings height (stable or unstable) of this elliptic curve.

    INPUT:

    - `stable` – boolean (default: `False`); if `True`, return the stable Faltings height, otherwise the unstable height

    - `prec` – integer (default: `None`); bit precision of output; if `None`, use standard precision (53 bits)

    OUTPUT: real; the Faltings height of this elliptic curve

    Note

    Different authors normalise the Faltings height differently. We use the formula \(-\frac{1}{2}\log(A)\), where \(A\) is the area of the fundamental period parallelogram; some authors use \(-\frac{1}{2\pi}\log(A)\) instead.

    The unstable Faltings height does depend on the model. The stable Faltings height is defined to be

    \[\frac{1}{12}\log\mathrm{denom}(j) - \frac{1}{12}\log|\Delta| -\frac{1}{2}\log A,\]

    This is independent of the model. For the minimal model of a semistable elliptic curve, we have \(\mathrm{denom}(j)=|\Delta|\), and the stable and unstable heights agree.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('32a1')
        sage: E.faltings_height()
        -0.617385745351564
        sage: E.faltings_height(stable=True)
        -1.31053292591151

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('32a1')
        >>> E.faltings_height()
        -0.617385745351564
        >>> E.faltings_height(stable=True)
        -1.31053292591151

    These differ since the curve is not semistable:

    Sage

        sage: E.is_semistable()
        False

    [Python]

        >>> from sage.all import *
        >>> E.is_semistable()
        False

    If the model is changed, the Faltings height changes but the stable height does not. It is reduced by \(\log(u)\) where \(u\) is the scale factor:

    Sage

        sage: E1 = E.change_weierstrass_model([10,0,0,0])
        sage: E1.faltings_height()
        -2.91997083834561
        sage: E1.faltings_height(stable=True)
        -1.31053292591151
        sage: E.faltings_height() - log(10.0)
        -2.91997083834561

    Python

        >>> from sage.all import *
        >>> E1 = E.change_weierstrass_model([Integer(10),Integer(0),Integer(0),Integer(0)])
        >>> E1.faltings_height()
        -2.91997083834561
        >>> E1.faltings_height(stable=True)
        -1.31053292591151
        >>> E.faltings_height() - log(RealNumber('10.0'))
        -2.91997083834561

    For a semistable curve (that is, one with squarefree conductor), the stable and unstable heights are equal. Here we also show that one can specify the (bit) precision of the result:

    Sage

        sage: E = EllipticCurve('210a1')
        sage: E.is_semistable()
        True
        sage: E.faltings_height(prec=100)
        -0.043427311858075396288912139225
        sage: E.faltings_height(stable=True, prec=100)
        -0.043427311858075396288912139225

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('210a1')
        >>> E.is_semistable()
        True
        >>> E.faltings_height(prec=Integer(100))
        -0.043427311858075396288912139225
        >>> E.faltings_height(stable=True, prec=Integer(100))
        -0.043427311858075396288912139225

  galois_representation()

    The compatible family of the Galois representation attached to this elliptic curve.

    Given an elliptic curve \(E\) over \(\QQ\) and a rational prime number \(p\), the \(p^n\)-torsion \(E[p^n]\) points of \(E\) is a representation of the absolute Galois group of \(\QQ\). As \(n\) varies we obtain the Tate module \(T_p E\) which is a a representation of \(G_K\) on a free \(\ZZ_p\)-module of rank \(2\). As \(p\) varies the representations are compatible.

    EXAMPLES:

    Sage

        sage: rho = EllipticCurve('11a1').galois_representation()
        sage: rho
        Compatible family of Galois representations associated to the
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        sage: rho.is_irreducible(7)
        True
        sage: rho.is_irreducible(5)
        False
        sage: rho.is_surjective(11)
        True
        sage: rho.non_surjective()
        [5]
        sage: rho = EllipticCurve('37a1').galois_representation()
        sage: rho.non_surjective()
        []
        sage: rho = EllipticCurve('27a1').galois_representation()
        sage: rho.is_irreducible(7)
        True
        sage: rho.non_surjective()   # cm-curve
        [0]

    Python

        >>> from sage.all import *
        >>> rho = EllipticCurve('11a1').galois_representation()
        >>> rho
        Compatible family of Galois representations associated to the
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        >>> rho.is_irreducible(Integer(7))
        True
        >>> rho.is_irreducible(Integer(5))
        False
        >>> rho.is_surjective(Integer(11))
        True
        >>> rho.non_surjective()
        [5]
        >>> rho = EllipticCurve('37a1').galois_representation()
        >>> rho.non_surjective()
        []
        >>> rho = EllipticCurve('27a1').galois_representation()
        >>> rho.is_irreducible(Integer(7))
        True
        >>> rho.non_surjective()   # cm-curve
        [0]

  gens(proof=None, **kwds)

    Return generators for the Mordell-Weil group \(E(Q)\) modulo torsion.

    INPUT:

    - `proof` – boolean or `None` (default: `None`), see `proof.elliptic_curve` or `sage.structure.proof`

    - `verbose` – (default: `None`) if specified changes the verbosity of mwrank computations

    - `rank1_search` – (default: 10), if the curve has analytic rank 1, try to find a generator by a direct search up to this logarithmic height. If this fails, the usual mwrank procedure is called.

    - `algorithm` – one of the following:

      - `'mwrank_lib'` – default; call mwrank C library

      - `'mwrank_shell'` – call mwrank shell command

      - `'pari'` – use ellrank in pari

    - `only_use_mwrank` – boolean (default: `True`); if `False`, first attempts to use more naive, natively implemented methods

    - `use_database` – boolean (default: `True`); if `True`, attempts to find curve and gens in the (optional) database

    - `descent_second_limit` – (default: 12); logarithmic height bound on second point search on quartic homogeneous spaces (after testing local solubility; sieve-assisted search). Used in 2-descent. See also `second_limit` in `two_descent()`

    - `sat_bound` – (default: 1000) bound on primes used in saturation. If the computed bound on the index of the points found by two-descent in the Mordell-Weil group is greater than this, a warning message will be displayed.

    - `pari_effort` – (default: 0) parameter used in when the algorithm `pari` is chosen. It measure of the effort done to find rational points. Values up to 10 can be chosen, the running times increase roughly like the cube of the effort value.

    OUTPUT:

    - `generators` – list of generators for the Mordell-Weil group modulo torsion

    Note

    If you call this with `proof=False`, then you can use the `gens_certain()` method to find out afterwards whether the generators were proved.

    IMPLEMENTATION: Uses Cremona’s mwrank C++ library or ellrank in pari.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a')
        sage: E.gens()                 # random output
        [(-1 : 1 : 1), (0 : 0 : 1)]
        sage: E.gens(algorithm='pari')    # random output
        [(5/4 : 5/8 : 1), (0 : 0 : 1)]
        sage: E = EllipticCurve([0,2429469980725060,0,275130703388172136833647756388,0])
        sage: len(E.gens(algorithm='pari'))  # not tested (takes too long)
        14

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> E.gens()                 # random output
        [(-1 : 1 : 1), (0 : 0 : 1)]
        >>> E.gens(algorithm='pari')    # random output
        [(5/4 : 5/8 : 1), (0 : 0 : 1)]
        >>> E = EllipticCurve([Integer(0),Integer(2429469980725060),Integer(0),Integer(275130703388172136833647756388),Integer(0)])
        >>> len(E.gens(algorithm='pari'))  # not tested (takes too long)
        14

    A non-integral example:

    Sage

        sage: E = EllipticCurve([-3/8,-2/3])
        sage: E.gens() # random (up to sign)
        [(10/9 : 29/54 : 1)]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(3)/Integer(8),-Integer(2)/Integer(3)])
        >>> E.gens() # random (up to sign)
        [(10/9 : 29/54 : 1)]

    A non-minimal example:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: E1 = E.change_weierstrass_model([1/20,0,0,0]); E1
        Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x
         over Rational Field
        sage: E1.gens() # random (if database not used)
        [(-400 : 8000 : 1), (0 : -8000 : 1)]
        sage: E1.gens(algorithm='pari')   # random
        [(-400 : 8000 : 1), (0 : -8000 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> E1 = E.change_weierstrass_model([Integer(1)/Integer(20),Integer(0),Integer(0),Integer(0)]); E1
        Elliptic Curve defined by y^2 + 8000*y = x^3 + 400*x^2 - 320000*x
         over Rational Field
        >>> E1.gens() # random (if database not used)
        [(-400 : 8000 : 1), (0 : -8000 : 1)]
        >>> E1.gens(algorithm='pari')   # random
        [(-400 : 8000 : 1), (0 : -8000 : 1)]

  gens_certain()

    Return `True` if the generators have been proven correct.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.gens()                   # random (up to sign)
        [(0 : -1 : 1)]
        sage: E.gens_certain()
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.gens()                   # random (up to sign)
        [(0 : -1 : 1)]
        >>> E.gens_certain()
        True

  global_integral_model()

    Return a model of `self` which is integral at all primes.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, 0, 1/216, -7/1296, 1/7776])
        sage: F = E.global_integral_model(); F
        Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
        sage: F == EllipticCurve('5077a1')
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1)/Integer(216), -Integer(7)/Integer(1296), Integer(1)/Integer(7776)])
        >>> F = E.global_integral_model(); F
        Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
        >>> F == EllipticCurve('5077a1')
        True

  has_cm()

    Return whether or not this curve has a CM \(j\)-invariant.

    OUTPUT:

    `True` if the \(j\)-invariant of this curve is the \(j\)-invariant of an imaginary quadratic order, otherwise `False`.

    See also

    `cm_discriminant()` and `has_rational_cm()`

    Note

    Even if \(E\) has CM in this sense (that its \(j\)-invariant is a CM \(j\)-invariant), since the associated negative discriminant \(D\) is not a square in \(\QQ\), the extra endomorphisms will not be defined over \(\QQ\). See also the method `has_rational_cm()` which tests whether \(E\) has extra endomorphisms defined over \(\QQ\) or a given extension of \(\QQ\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.has_cm()
        False
        sage: E = EllipticCurve('32a1')
        sage: E.has_cm()
        True
        sage: E.j_invariant()
        1728

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.has_cm()
        False
        >>> E = EllipticCurve('32a1')
        >>> E.has_cm()
        True
        >>> E.j_invariant()
        1728

  has_good_reduction_outside_S(S=None)

    Test if this elliptic curve has good reduction outside `S`.

    INPUT:

    - `S` – list of primes (default: `[]`)

    Note

    Primality of elements of `S` is not checked, and the output is undefined if `S` is not a list or contains non-primes.

    This only tests the given model, so should only be applied to minimal models.

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a1').has_good_reduction_outside_S([11])
        True
        sage: EllipticCurve('11a1').has_good_reduction_outside_S([2])
        False
        sage: EllipticCurve('2310a1').has_good_reduction_outside_S([2,3,5,7])
        False
        sage: EllipticCurve('2310a1').has_good_reduction_outside_S([2,3,5,7,11])
        True

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a1').has_good_reduction_outside_S([Integer(11)])
        True
        >>> EllipticCurve('11a1').has_good_reduction_outside_S([Integer(2)])
        False
        >>> EllipticCurve('2310a1').has_good_reduction_outside_S([Integer(2),Integer(3),Integer(5),Integer(7)])
        False
        >>> EllipticCurve('2310a1').has_good_reduction_outside_S([Integer(2),Integer(3),Integer(5),Integer(7),Integer(11)])
        True

  has_rational_cm(field=None)

    Return whether or not this curve has CM defined over \(\QQ\) or the given field.

    INPUT:

    - `field` – (default: \(\QQ\)) a field, which should be an extension of \(\QQ\);

    OUTPUT:

    `True` if the ring of endomorphisms of this curve over the given field is larger than \(\ZZ\); otherwise `False`. If `field` is `None` the output will always be `False`. See also `cm_discriminant()` and `has_cm()`.

    Note

    If \(E\) has CM but the discriminant \(D\) is not a square in the given field \(K\), which will certainly be the case for \(K=\QQ\) since \(D<0\), then the extra endomorphisms will not be defined over \(K\), and this function will return `False`. See also `has_cm()`. To obtain the CM discriminant, use `cm_discriminant()`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve(j=0)
        sage: E.has_cm()
        True
        sage: E.has_rational_cm()
        False
        sage: D = E.cm_discriminant(); D
        -3

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve(j=Integer(0))
        >>> E.has_cm()
        True
        >>> E.has_rational_cm()
        False
        >>> D = E.cm_discriminant(); D
        -3

    If we extend scalars to a field in which the discriminant is a square, the CM becomes rational:

    Sage

        sage: E.has_rational_cm(QuadraticField(-3))                                 # needs sage.rings.number_field
        True

        sage: E = EllipticCurve(j=8000)
        sage: E.has_cm()
        True
        sage: E.has_rational_cm()
        False
        sage: D = E.cm_discriminant(); D
        -8

    [Python]

        >>> from sage.all import *
        >>> E.has_rational_cm(QuadraticField(-Integer(3)))                                 # needs sage.rings.number_field
        True

        >>> E = EllipticCurve(j=Integer(8000))
        >>> E.has_cm()
        True
        >>> E.has_rational_cm()
        False
        >>> D = E.cm_discriminant(); D
        -8

    Again, we may extend scalars to a field in which the discriminant is a square, where the CM becomes rational:

    Sage

        sage: E.has_rational_cm(QuadraticField(-2))                                 # needs sage.rings.number_field
        True

    Python

        >>> from sage.all import *
        >>> E.has_rational_cm(QuadraticField(-Integer(2)))                                 # needs sage.rings.number_field
        True

    The field need not be a number field provided that it is an extension of \(\QQ\):

    Sage

        sage: E.has_rational_cm(RR)
        False
        sage: E.has_rational_cm(CC)
        True

    [Python]

        >>> from sage.all import *
        >>> E.has_rational_cm(RR)
        False
        >>> E.has_rational_cm(CC)
        True

    An error is raised if a field is given which is not an extension of \(\QQ\), i.e., not of characteristic \(0\):

    Sage

        sage: E.has_rational_cm(GF(2))
        Traceback (most recent call last):
        ...
        ValueError: Error in has_rational_cm: Finite Field of size 2
        is not an extension field of QQ

    Python

        >>> from sage.all import *
        >>> E.has_rational_cm(GF(Integer(2)))
        Traceback (most recent call last):
        ...
        ValueError: Error in has_rational_cm: Finite Field of size 2
        is not an extension field of QQ

  heegner_discriminants(bound)

    alias of `ell_heegner_discriminants()`.

  heegner_discriminants_list(n)

    alias of `ell_heegner_discriminants_list()`.

  heegner_index(D, min_p=2, prec=5, descent_second_limit=12, verbose_mwrank=False, check_rank=True)

    Return an interval that contains the index of the Heegner point \(y_K\) in the group of \(K\)-rational points modulo torsion on this elliptic curve, computed using the Gross-Zagier formula and/or a point search, or possibly half the index if the rank is greater than one.

    If the curve has rank > 1, then the returned index is infinity.

    Note

    If `min_p` is bigger than 2 then the index can be off by any prime less than `min_p`. This function returns the index divided by \(2\) exactly when the rank of \(E(K)\) is greater than 1 and \(E(\QQ)_{/tor} \oplus E^D(\QQ)_{/tor}\) has index \(2\) in \(E(K)_{/tor}\), where the second factor undergoes a twist.

    INPUT:

    - `D` – integer; Heegner discriminant

    - `min_p` – integer (default: 2); only rule out primes = min_p dividing the index

    - `verbose_mwrank` – boolean (default: `False`); print lots of mwrank search status information when computing regulator

    - `prec` – integer (default: 5);, use prec*sqrt(N) + 20 terms of \(L\)-series in computations, where N is the conductor

    - `descent_second_limit` – (default: 12)- used in 2-descent when computing regulator of the twist

    - `check_rank` – whether to check if the rank is at least 2 by computing the Mordell-Weil rank directly

    OUTPUT: an interval that contains the index, or half the index

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.heegner_discriminants(50)
        [-7, -8, -19, -24, -35, -39, -40, -43]
        sage: E.heegner_index(-7)
        1.00000?

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.heegner_discriminants(Integer(50))
        [-7, -8, -19, -24, -35, -39, -40, -43]
        >>> E.heegner_index(-Integer(7))
        1.00000?

    Sage

        sage: E = EllipticCurve('37b')
        sage: E.heegner_discriminants(100)
        [-3, -4, -7, -11, -40, -47, -67, -71, -83, -84, -95]
        sage: E.heegner_index(-95)          # long time (1 second)
        2.00000?

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('37b')
        >>> E.heegner_discriminants(Integer(100))
        [-3, -4, -7, -11, -40, -47, -67, -71, -83, -84, -95]
        >>> E.heegner_index(-Integer(95))          # long time (1 second)
        2.00000?

    This tests doing direct computation of the Mordell-Weil group.

    Sage

        sage: EllipticCurve('675b').heegner_index(-11)
        3.0000?

    Python

        >>> from sage.all import *
        >>> EllipticCurve('675b').heegner_index(-Integer(11))
        3.0000?

    Currently discriminants -3 and -4 are not supported:

    Sage

        sage: E.heegner_index(-3)
        Traceback (most recent call last):
        ...
        ArithmeticError: Discriminant (=-3) must not be -3 or -4.

    [Python]

        >>> from sage.all import *
        >>> E.heegner_index(-Integer(3))
        Traceback (most recent call last):
        ...
        ArithmeticError: Discriminant (=-3) must not be -3 or -4.

    The curve 681b returns the true index, which is \(3\):

    Sage

        sage: E = EllipticCurve('681b')
        sage: I = E.heegner_index(-8); I
        3.0000?

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('681b')
        >>> I = E.heegner_index(-Integer(8)); I
        3.0000?

    In fact, whenever the returned index has a denominator of \(2\), the true index is got by multiplying the returned index by \(2\). Unfortunately, this is not an if and only if condition, i.e., sometimes the index must be multiplied by \(2\) even though the denominator is not \(2\).

    This example demonstrates the `descent_second_limit` option, which can be used to fine tune the 2-descent used to compute the regulator of the twist:

    Sage

        sage: E = EllipticCurve([1,-1,0,-1228,-16267])
        sage: E.heegner_index(-8)
        Traceback (most recent call last):
        ...
        RuntimeError: ...

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1),-Integer(1),Integer(0),-Integer(1228),-Integer(16267)])
        >>> E.heegner_index(-Integer(8))
        Traceback (most recent call last):
        ...
        RuntimeError: ...

    However when we search higher, we find the points we need:

    Sage

        sage: E.heegner_index(-8, descent_second_limit=16, check_rank=False)  # long time
        2.00000?

    Python

        >>> from sage.all import *
        >>> E.heegner_index(-Integer(8), descent_second_limit=Integer(16), check_rank=False)  # long time
        2.00000?

    Two higher rank examples (of ranks 2 and 3):

    Sage

        sage: E = EllipticCurve('389a')
        sage: E.heegner_index(-7)
        +Infinity
        sage: E = EllipticCurve('5077a')
        sage: E.heegner_index(-7)
        +Infinity
        sage: E.heegner_index(-7, check_rank=False)
        0.001?
        sage: E.heegner_index(-7, check_rank=False).lower() == 0
        True

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> E.heegner_index(-Integer(7))
        +Infinity
        >>> E = EllipticCurve('5077a')
        >>> E.heegner_index(-Integer(7))
        +Infinity
        >>> E.heegner_index(-Integer(7), check_rank=False)
        0.001?
        >>> E.heegner_index(-Integer(7), check_rank=False).lower() == Integer(0)
        True

  heegner_index_bound(D=0, prec=5, max_height=None)

    Assume `self` has rank 0.

    Return a list \(v\) of primes such that if an odd prime \(p\) divides the index of the Heegner point in the group of rational points modulo torsion, then \(p\) is in \(v\).

    If 0 is in the interval of the height of the Heegner point computed to the given prec, then this function returns \(v = 0\). This does not mean that the Heegner point is torsion, just that it is very likely torsion.

    If we obtain no information from a search up to `max_height`, e.g., if the Siksek et al. bound is bigger than `max_height`, then we return \(v = -1\).

    INPUT:

    - `D` – integer (default: 0); Heegner discriminant; if 0, use the first discriminant -4 that satisfies the Heegner hypothesis

    - `verbose` – boolean (default: `True`)

    - `prec` – integer (default: 5); use \(prec \cdot \sqrt(N) + 20\) terms of \(L\)-series in computations, where \(N\) is the conductor

    - `max_height (float)` – should be = 21; bound on logarithmic naive height used in point searches. Make smaller to make this function faster, at the expense of possibly obtaining a worse answer. A good range is between 13 and 21.

    OUTPUT:

    - `v` – list or int (bad primes or 0 or -1)

    - `D` – the discriminant that was used (this is useful if \(D\) was automatically selected)

    - `exact` – either False, or the exact Heegner index (up to factors of 2)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a1')
        sage: E.heegner_index_bound()
        ([2], -7, 2)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a1')
        >>> E.heegner_index_bound()
        ([2], -7, 2)

  heegner_point(D, c=1, f=None, check=True)

    alias of `ell_heegner_point()`.

  heegner_point_height(D, prec=2, check_rank=True)

    Use the Gross-Zagier formula to compute the Neron-Tate canonical height over \(K\) of the Heegner point corresponding to \(D\), as an interval (it is computed to some precision using \(L\)-functions).

    If the curve has rank at least 2, then the returned height is the exact Sage integer 0.

    INPUT:

    - `D` – integer; fundamental discriminant (=/= -3, -4)

    - `prec` – integer (default: 2); use \(prec \cdot \sqrt(N) + 20\) terms of \(L\)-series in computations, where \(N\) is the conductor

    - `check_rank` – whether to check if the rank is at least 2 by computing the Mordell-Weil rank directly

    OUTPUT: interval that contains the height of the Heegner point

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.heegner_point_height(-7)
        0.22227?

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.heegner_point_height(-Integer(7))
        0.22227?

    Some higher rank examples:

    Sage

        sage: E = EllipticCurve('389a')
        sage: E.heegner_point_height(-7)
        0
        sage: E = EllipticCurve('5077a')
        sage: E.heegner_point_height(-7)
        0
        sage: E.heegner_point_height(-7, check_rank=False)
        0.0000?

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')
        >>> E.heegner_point_height(-Integer(7))
        0
        >>> E = EllipticCurve('5077a')
        >>> E.heegner_point_height(-Integer(7))
        0
        >>> E.heegner_point_height(-Integer(7), check_rank=False)
        0.0000?

  heegner_sha_an(D, prec=53)

    Return the conjectural (analytic) order of Sha for E over the field \(K=\QQ(\sqrt{D})\).

    INPUT:

    - `D` – negative integer; the Heegner discriminant

    - `prec` – integer (default: 53); bits of precision to compute analytic order of Sha

    OUTPUT:

    (floating point number) an approximation to the conjectural order of Sha.

    Note

    Often you’ll want to do `proof.elliptic_curve(False)` when using this function, since often the twisted elliptic curves that come up have enormous conductor, and Sha is nontrivial, which makes provably finding the Mordell-Weil group using 2-descent difficult.

    EXAMPLES:

    An example where E has conductor 11:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.heegner_sha_an(-7)                                  # long time
        1.00000000000000

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.heegner_sha_an(-Integer(7))                                  # long time
        1.00000000000000

    The cache works:

    Sage

        sage: E.heegner_sha_an(-7) is E.heegner_sha_an(-7)          # long time
        True

    [Python]

        >>> from sage.all import *
        >>> E.heegner_sha_an(-Integer(7)) is E.heegner_sha_an(-Integer(7))          # long time
        True

    Lower precision:

    Sage

        sage: E.heegner_sha_an(-7,10)                               # long time
        1.0

    Python

        >>> from sage.all import *
        >>> E.heegner_sha_an(-Integer(7),Integer(10))                               # long time
        1.0

    Checking that the cache works for any precision:

    Sage

        sage: E.heegner_sha_an(-7,10) is E.heegner_sha_an(-7,10)    # long time
        True

    [Python]

        >>> from sage.all import *
        >>> E.heegner_sha_an(-Integer(7),Integer(10)) is E.heegner_sha_an(-Integer(7),Integer(10))    # long time
        True

    Next we consider a rank 1 curve with nontrivial Sha over the quadratic imaginary field \(K\); however, there is no Sha for \(E\) over \(\QQ\) or for the quadratic twist of \(E\):

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.heegner_sha_an(-40)                                 # long time
        4.00000000000000
        sage: E.quadratic_twist(-40).sha().an()                     # long time
        1
        sage: E.sha().an()                                          # long time
        1

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.heegner_sha_an(-Integer(40))                                 # long time
        4.00000000000000
        >>> E.quadratic_twist(-Integer(40)).sha().an()                     # long time
        1
        >>> E.sha().an()                                          # long time
        1

    A rank 2 curve:

    Sage

        sage: E = EllipticCurve('389a')                             # long time
        sage: E.heegner_sha_an(-7)                                  # long time
        1.00000000000000

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')                             # long time
        >>> E.heegner_sha_an(-Integer(7))                                  # long time
        1.00000000000000

    If we remove the hypothesis that \(E(K)\) has rank 1 in Conjecture 2.3 in [GZ1986] page 311, then that conjecture is false, as the following example shows:

    Sage

        sage: # long time
        sage: E = EllipticCurve('65a')
        sage: E.heegner_sha_an(-56)
        1.00000000000000
        sage: E.torsion_order()
        2
        sage: E.tamagawa_product()
        1
        sage: E.quadratic_twist(-56).rank()
        2

    Python

        >>> from sage.all import *
        >>> # long time
        >>> E = EllipticCurve('65a')
        >>> E.heegner_sha_an(-Integer(56))
        1.00000000000000
        >>> E.torsion_order()
        2
        >>> E.tamagawa_product()
        1
        >>> E.quadratic_twist(-Integer(56)).rank()
        2

  height(precision=None)

    Return the real height of this elliptic curve.

    This is used in `integral_points()`.

    INPUT:

    - `precision` – desired real precision of the result (default real precision if `None`)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('5077a1')
        sage: E.height()
        17.4513334798896
        sage: E.height(100)
        17.451333479889612702508579399
        sage: E = EllipticCurve([0,0,0,0,1])
        sage: E.height()
        1.38629436111989
        sage: E = EllipticCurve([0,0,0,1,0])
        sage: E.height()
        7.45471994936400

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('5077a1')
        >>> E.height()
        17.4513334798896
        >>> E.height(Integer(100))
        17.451333479889612702508579399
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(1)])
        >>> E.height()
        1.38629436111989
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(1),Integer(0)])
        >>> E.height()
        7.45471994936400

  integral_model()

    alias of `global_integral_model()`.

  integral_points(mw_base='auto', both_signs=False, verbose=False)

    Compute all integral points (up to sign) on this elliptic curve.

    INPUT:

    - `mw_base` – (default: `'auto'` - calls `gens()`) list of EllipticCurvePoint generating the Mordell-Weil group of \(E\)

    - `both_signs` – boolean (default: `False`); if `True` the output contains both \(P\) and \(-P\), otherwise only one of each pair

    - `verbose` – boolean (default: `False`); if `True`, some details of the computation are output

    OUTPUT: a sorted list of all the integral points on \(E\) (up to sign unless `both_signs` is `True`)

    Note

    The complexity increases exponentially in the rank of curve \(E\). The computation time (but not the output!) depends on the Mordell-Weil basis. If `mw_base` is given but is not a basis for the Mordell-Weil group (modulo torsion), integral points which are not in the subgroup generated by the given points will almost certainly not be listed.

    EXAMPLES: A curve of rank 3 with no torsion points:

    Sage

        sage: E = EllipticCurve([0,0,1,-7,6])
        sage: P1 = E.point((2,0)); P2 = E.point((-1,3)); P3 = E.point((4,6))
        sage: a = E.integral_points([P1,P2,P3]); a
        [(-3 : -1 : 1), (-2 : -4 : 1), (-1 : -4 : 1), (0 : -3 : 1),
         (1 : -1 : 1), (2 : -1 : 1), (3 : -4 : 1), (4 : -7 : 1),
         (8 : -22 : 1), (11 : -36 : 1), (14 : -52 : 1), (21 : -96 : 1),
         (37 : -225 : 1), (52 : -375 : 1), (93 : -897 : 1),
         (342 : -6325 : 1), (406 : -8181 : 1), (816 : -23310 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(7),Integer(6)])
        >>> P1 = E.point((Integer(2),Integer(0))); P2 = E.point((-Integer(1),Integer(3))); P3 = E.point((Integer(4),Integer(6)))
        >>> a = E.integral_points([P1,P2,P3]); a
        [(-3 : -1 : 1), (-2 : -4 : 1), (-1 : -4 : 1), (0 : -3 : 1),
         (1 : -1 : 1), (2 : -1 : 1), (3 : -4 : 1), (4 : -7 : 1),
         (8 : -22 : 1), (11 : -36 : 1), (14 : -52 : 1), (21 : -96 : 1),
         (37 : -225 : 1), (52 : -375 : 1), (93 : -897 : 1),
         (342 : -6325 : 1), (406 : -8181 : 1), (816 : -23310 : 1)]

    Sage

        sage: a = E.integral_points([P1,P2,P3], verbose=True)
        Using mw_basis  [(2 : 0 : 1), (3 : -4 : 1), (8 : -22 : 1)]
        e1,e2,e3:  -3.0124303725933... 1.0658205476962... 1.94660982489710
        Minimal and maximal eigenvalues of height pairing matrix: 0.637920814585005,2.31982967525725
        x-coords of points on compact component with  -3 <=x<= 1
        [-3, -2, -1, 0, 1]
        x-coords of points on non-compact component with  2 <=x<= 6
        [2, 3, 4]
        starting search of remaining points using coefficient bound 5 and |x| bound 1.53897183921009e25
        x-coords of extra integral points:
        [2, 3, 4, 8, 11, 14, 21, 37, 52, 93, 342, 406, 816]
        Total number of integral points: 18

    [Python]

        >>> from sage.all import *
        >>> a = E.integral_points([P1,P2,P3], verbose=True)
        Using mw_basis  [(2 : 0 : 1), (3 : -4 : 1), (8 : -22 : 1)]
        e1,e2,e3:  -3.0124303725933... 1.0658205476962... 1.94660982489710
        Minimal and maximal eigenvalues of height pairing matrix: 0.637920814585005,2.31982967525725
        x-coords of points on compact component with  -3 <=x<= 1
        [-3, -2, -1, 0, 1]
        x-coords of points on non-compact component with  2 <=x<= 6
        [2, 3, 4]
        starting search of remaining points using coefficient bound 5 and |x| bound 1.53897183921009e25
        x-coords of extra integral points:
        [2, 3, 4, 8, 11, 14, 21, 37, 52, 93, 342, 406, 816]
        Total number of integral points: 18

    It is not necessary to specify `mw_base`; if it is not provided, then the Mordell-Weil basis must be computed, which may take much longer.

    Sage

        sage: E = EllipticCurve([0,0,1,-7,6])
        sage: a = E.integral_points(both_signs=True); a
        [(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1),
         (-1 : 3 : 1), (0 : -3 : 1), (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1),
         (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 : -7 : 1),
         (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1),
         (14 : -52 : 1), (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1),
         (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52 : 374 : 1),
         (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1),
         (406 : -8181 : 1), (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(1),-Integer(7),Integer(6)])
        >>> a = E.integral_points(both_signs=True); a
        [(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1),
         (-1 : 3 : 1), (0 : -3 : 1), (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1),
         (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 : -7 : 1),
         (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1),
         (14 : -52 : 1), (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1),
         (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52 : 374 : 1),
         (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1),
         (406 : -8181 : 1), (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)]

    An example with negative discriminant:

    Sage

        sage: EllipticCurve('900d1').integral_points()
        [(-11 : -27 : 1), (-4 : -34 : 1), (4 : -18 : 1), (16 : -54 : 1)]

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve('900d1').integral_points()
        [(-11 : -27 : 1), (-4 : -34 : 1), (4 : -18 : 1), (16 : -54 : 1)]

    Another example with rank 5 and no torsion points:

    Sage

        sage: E = EllipticCurve([-879984,319138704])
        sage: P1 = E.point((540,1188)); P2 = E.point((576,1836))
        sage: P3 = E.point((468,3132)); P4 = E.point((612,3132))
        sage: P5 = E.point((432,4428))
        sage: a = E.integral_points([P1,P2,P3,P4,P5]); len(a)  # long time (18s on sage.math, 2011)
        54

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(879984),Integer(319138704)])
        >>> P1 = E.point((Integer(540),Integer(1188))); P2 = E.point((Integer(576),Integer(1836)))
        >>> P3 = E.point((Integer(468),Integer(3132))); P4 = E.point((Integer(612),Integer(3132)))
        >>> P5 = E.point((Integer(432),Integer(4428)))
        >>> a = E.integral_points([P1,P2,P3,P4,P5]); len(a)  # long time (18s on sage.math, 2011)
        54

    ALGORITHM:

    This function uses the algorithm given in [Coh2007I].

    AUTHORS:

    - Michael Mardaus (2008-07)

    - Tobias Nagel (2008-07)

    - John Cremona (2008-07)

  integral_short_weierstrass_model()

    Return a model of the form \(y^2 = x^3 + ax + b\) for this curve with \(a,b\in\ZZ\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('17a1')
        sage: E.integral_short_weierstrass_model()
        Elliptic Curve defined by y^2  = x^3 - 11*x - 890 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('17a1')
        >>> E.integral_short_weierstrass_model()
        Elliptic Curve defined by y^2  = x^3 - 11*x - 890 over Rational Field

  integral_x_coords_in_interval(xmin, xmax)

    Return the set of integers \(x\) with \(xmin\le x\le xmax\) which are \(x\)-coordinates of rational points on this curve.

    INPUT:

    - `xmin`, `xmax` – two integers

    OUTPUT:

    The set of integers \(x\) with \(xmin\le x\le xmax\) which are \(x\)-coordinates of rational points on the elliptic curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, 0, 1, -7, 6])
        sage: xset = E.integral_x_coords_in_interval(-100,100)
        sage: sorted(xset)
        [-3, -2, -1, 0, 1, 2, 3, 4, 8, 11, 14, 21, 37, 52, 93]
        sage: xset = E.integral_x_coords_in_interval(-100, 0)
        sage: sorted(xset)
        [-3, -2, -1, 0]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(7), Integer(6)])
        >>> xset = E.integral_x_coords_in_interval(-Integer(100),Integer(100))
        >>> sorted(xset)
        [-3, -2, -1, 0, 1, 2, 3, 4, 8, 11, 14, 21, 37, 52, 93]
        >>> xset = E.integral_x_coords_in_interval(-Integer(100), Integer(0))
        >>> sorted(xset)
        [-3, -2, -1, 0]

  is_global_integral_model()

    Return `True` iff `self` is integral at all primes.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([1/2, 1/5, 1/5, 1/5, 1/5])
        sage: E.is_global_integral_model()
        False
        sage: Emin=E.global_integral_model()
        sage: Emin.is_global_integral_model()
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1)/Integer(2), Integer(1)/Integer(5), Integer(1)/Integer(5), Integer(1)/Integer(5), Integer(1)/Integer(5)])
        >>> E.is_global_integral_model()
        False
        >>> Emin=E.global_integral_model()
        >>> Emin.is_global_integral_model()
        True

  is_good(p, check=True)

    Return `True` if `p` is a prime of good reduction for \(E\).

    INPUT:

    - `p` – a prime

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('11a')
        sage: e.is_good(-8)
        Traceback (most recent call last):
        ...
        ValueError: p must be prime
        sage: e.is_good(-8, check=False)
        True

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> e.is_good(-Integer(8))
        Traceback (most recent call last):
        ...
        ValueError: p must be prime
        >>> e.is_good(-Integer(8), check=False)
        True

  is_integral()

    Return `True` if this elliptic curve has integral coefficients (in Z).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve(QQ,[1,1]); E
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
        sage: E.is_integral()
        True
        sage: E2=E.change_weierstrass_model(2,0,0,0); E2
        Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field
        sage: E2.is_integral()
        False

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve(QQ,[Integer(1),Integer(1)]); E
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
        >>> E.is_integral()
        True
        >>> E2=E.change_weierstrass_model(Integer(2),Integer(0),Integer(0),Integer(0)); E2
        Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field
        >>> E2.is_integral()
        False

  is_isogenous(other, proof=True, maxp=200)

    Return whether or not `self` is isogenous to other.

    INPUT:

    - `other` – another elliptic curve

    - `proof` – boolean (default: `True`); if `False`, the function will return `True` whenever the two curves have the same conductor and are isogenous modulo \(p\) for \(p\) up to `maxp`; otherwise this test is followed by a rigorous test (which may be more time-consuming)

    - `maxp` – (default: 200) the maximum prime \(p\) for which isogeny modulo \(p\) will be checked

    OUTPUT:

    boolean; `True` if there is an isogeny from curve `self` to curve `other`.

    ALGORITHM:

    First the conductors are compared as well as the Traces of Frobenius for good primes up to `maxp`. If any of these tests fail, `False` is returned. If they all pass and `proof` is `False` then `True` is returned, otherwise a complete set of curves isogenous to `self` is computed and `other` is checked for isomorphism with any of these,

    EXAMPLES:

    Sage

        sage: E1 = EllipticCurve('14a1')
        sage: E6 = EllipticCurve('14a6')
        sage: E1.is_isogenous(E6)
        True
        sage: E1.is_isogenous(EllipticCurve('11a1'))
        False

    Python

        >>> from sage.all import *
        >>> E1 = EllipticCurve('14a1')
        >>> E6 = EllipticCurve('14a6')
        >>> E1.is_isogenous(E6)
        True
        >>> E1.is_isogenous(EllipticCurve('11a1'))
        False

    Sage

        sage: EllipticCurve('37a1').is_isogenous(EllipticCurve('37b1'))
        False

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve('37a1').is_isogenous(EllipticCurve('37b1'))
        False

    Sage

        sage: E = EllipticCurve([2, 16])
        sage: EE = EllipticCurve([87, 45])
        sage: E.is_isogenous(EE)
        False

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(2), Integer(16)])
        >>> EE = EllipticCurve([Integer(87), Integer(45)])
        >>> E.is_isogenous(EE)
        False

  is_local_integral_model(*p)

    Test if `self` is integral at the prime \(p\), or at all the primes if \(p\) is a list or tuple of primes.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([1/2, 1/5, 1/5, 1/5, 1/5])
        sage: [E.is_local_integral_model(p) for p in (2,3,5)]
        [False, True, False]
        sage: E.is_local_integral_model(2,3,5)
        False
        sage: Eint2=E.local_integral_model(2)
        sage: Eint2.is_local_integral_model(2)
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1)/Integer(2), Integer(1)/Integer(5), Integer(1)/Integer(5), Integer(1)/Integer(5), Integer(1)/Integer(5)])
        >>> [E.is_local_integral_model(p) for p in (Integer(2),Integer(3),Integer(5))]
        [False, True, False]
        >>> E.is_local_integral_model(Integer(2),Integer(3),Integer(5))
        False
        >>> Eint2=E.local_integral_model(Integer(2))
        >>> Eint2.is_local_integral_model(Integer(2))
        True

  is_minimal()

    Return `True` iff this elliptic curve is a reduced minimal model.

    The unique minimal Weierstrass equation for this elliptic curve. This is the model with minimal discriminant and \(a_1,a_2,a_3 \in \{0,\pm 1\}\).

    Todo

    This is not very efficient since it just computes the minimal model and compares. A better implementation using the Kraus conditions would be preferable.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([10,100,1000,10000,1000000])
        sage: E.is_minimal()
        False
        sage: E = E.minimal_model()
        sage: E.is_minimal()
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(10),Integer(100),Integer(1000),Integer(10000),Integer(1000000)])
        >>> E.is_minimal()
        False
        >>> E = E.minimal_model()
        >>> E.is_minimal()
        True

  is_ordinary(p, ell=None)

    Return `True` precisely when the mod-`p` representation attached to this elliptic curve is ordinary at `ell`.

    INPUT:

    - `p` – a prime

    - `ell` – a prime (default: `p`)

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.is_ordinary(37)
        True
        sage: E = EllipticCurve('32a1')
        sage: E.is_ordinary(2)
        False
        sage: [p for p in prime_range(50) if E.is_ordinary(p)]
        [5, 13, 17, 29, 37, 41]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.is_ordinary(Integer(37))
        True
        >>> E = EllipticCurve('32a1')
        >>> E.is_ordinary(Integer(2))
        False
        >>> [p for p in prime_range(Integer(50)) if E.is_ordinary(p)]
        [5, 13, 17, 29, 37, 41]

  is_p_integral(p)

    Return `True` if this elliptic curve has \(p\)-integral coefficients.

    INPUT:

    - `p` – prime integer

    EXAMPLES:

    Sage

        sage: E = EllipticCurve(QQ,[1,1]); E
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
        sage: E.is_p_integral(2)
        True
        sage: E2=E.change_weierstrass_model(2,0,0,0); E2
        Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field
        sage: E2.is_p_integral(2)
        False
        sage: E2.is_p_integral(3)
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve(QQ,[Integer(1),Integer(1)]); E
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
        >>> E.is_p_integral(Integer(2))
        True
        >>> E2=E.change_weierstrass_model(Integer(2),Integer(0),Integer(0),Integer(0)); E2
        Elliptic Curve defined by y^2 = x^3 + 1/16*x + 1/64 over Rational Field
        >>> E2.is_p_integral(Integer(2))
        False
        >>> E2.is_p_integral(Integer(3))
        True

  is_p_minimal(p)

    Test if curve is \(p\)-minimal at a given prime \(p\).

    INPUT:

    - `p` – a prime

    OUTPUT:

    - `True` – if curve is \(p\)-minimal

    - `False` – if curve is not \(p\)-minimal

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('441a2')
        sage: E.is_p_minimal(7)
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('441a2')
        >>> E.is_p_minimal(Integer(7))
        True

    Sage

        sage: E = EllipticCurve([0,0,0,0,(2*5*11)**10])
        sage: [E.is_p_minimal(p) for p in prime_range(2,24)]
        [False, True, False, True, False, True, True, True, True]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),(Integer(2)*Integer(5)*Integer(11))**Integer(10)])
        >>> [E.is_p_minimal(p) for p in prime_range(Integer(2),Integer(24))]
        [False, True, False, True, False, True, True, True, True]

  is_semistable()

    Return `True` iff this elliptic curve is semi-stable at all primes.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.is_semistable()
        True
        sage: E = EllipticCurve('90a1')
        sage: E.is_semistable()
        False

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.is_semistable()
        True
        >>> E = EllipticCurve('90a1')
        >>> E.is_semistable()
        False

  is_supersingular(p, ell=None)

    Return `True` precisely when \(p\) is a prime of good reduction and the mod-\(p\) representation attached to this elliptic curve is supersingular at ell.

    INPUT:

    - `p` – a prime

    - `ell` – a prime (default: `p`)

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.is_supersingular(37)
        False
        sage: E = EllipticCurve('32a1')
        sage: E.is_supersingular(2)
        False
        sage: E.is_supersingular(7)
        True
        sage: [p for p in prime_range(50) if E.is_supersingular(p)]
        [3, 7, 11, 19, 23, 31, 43, 47]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.is_supersingular(Integer(37))
        False
        >>> E = EllipticCurve('32a1')
        >>> E.is_supersingular(Integer(2))
        False
        >>> E.is_supersingular(Integer(7))
        True
        >>> [p for p in prime_range(Integer(50)) if E.is_supersingular(p)]
        [3, 7, 11, 19, 23, 31, 43, 47]

  isogenies_prime_degree(l=None)

    Return a list of \(\ell\)-isogenies from self, where \(\ell\) is a prime.

    INPUT:

    - `l` – either `None` or a prime or a list of primes

    OUTPUT:

    (list) \(\ell\)-isogenies for the given \(\ell\) or if \(\ell\) is None, all \(\ell\)-isogenies.

    Note

    The codomains of the isogenies returned are standard minimal models. This is because the functions `isogenies_prime_degree_genus_0()` and `isogenies_sporadic_Q()` are implemented that way for curves defined over \(\QQ\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([45,32])
        sage: E.isogenies_prime_degree()
        []
        sage: E = EllipticCurve(j = -262537412640768000)
        sage: E.isogenies_prime_degree()
        [Isogeny of degree 163
          from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field
            to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field]
        sage: E1 = E.quadratic_twist(6584935282)
        sage: E1.isogenies_prime_degree()
        [Isogeny of degree 163
          from Elliptic Curve defined by y^2 = x^3 - 94285835957031797981376080*x + 352385311612420041387338054224547830898 over Rational Field
            to Elliptic Curve defined by y^2 = x^3 - 2505080375542377840567181069520*x - 1526091631109553256978090116318797845018020806 over Rational Field]

        sage: E = EllipticCurve('14a1')
        sage: E.isogenies_prime_degree(2)
        [Isogeny of degree 2
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field]
        sage: E.isogenies_prime_degree(3)
        [Isogeny of degree 3
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field,
         Isogeny of degree 3
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field]
        sage: E.isogenies_prime_degree(5)
        []
        sage: E.isogenies_prime_degree(11)
        []
        sage: E.isogenies_prime_degree(29)
        []
        sage: E.isogenies_prime_degree(4)
        Traceback (most recent call last):
        ...
        ValueError: 4 is not prime.

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(45),Integer(32)])
        >>> E.isogenies_prime_degree()
        []
        >>> E = EllipticCurve(j = -Integer(262537412640768000))
        >>> E.isogenies_prime_degree()
        [Isogeny of degree 163
          from Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field
            to Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field]
        >>> E1 = E.quadratic_twist(Integer(6584935282))
        >>> E1.isogenies_prime_degree()
        [Isogeny of degree 163
          from Elliptic Curve defined by y^2 = x^3 - 94285835957031797981376080*x + 352385311612420041387338054224547830898 over Rational Field
            to Elliptic Curve defined by y^2 = x^3 - 2505080375542377840567181069520*x - 1526091631109553256978090116318797845018020806 over Rational Field]

        >>> E = EllipticCurve('14a1')
        >>> E.isogenies_prime_degree(Integer(2))
        [Isogeny of degree 2
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field]
        >>> E.isogenies_prime_degree(Integer(3))
        [Isogeny of degree 3
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field,
         Isogeny of degree 3
          from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
            to Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field]
        >>> E.isogenies_prime_degree(Integer(5))
        []
        >>> E.isogenies_prime_degree(Integer(11))
        []
        >>> E.isogenies_prime_degree(Integer(29))
        []
        >>> E.isogenies_prime_degree(Integer(4))
        Traceback (most recent call last):
        ...
        ValueError: 4 is not prime.

  isogeny_class(algorithm='sage', order=None)

    Return the \(\QQ\)-isogeny class of this elliptic curve.

    INPUT:

    - `algorithm` – string; one of

      - `'database'` – use the Cremona database (only works if curve is isomorphic to a curve in the database)

      - `'sage'` (default) – use the native Sage implementation

    - `order` – `None`, string, or list of curves (default: `None`); if not `None` then the curves in the class are reordered after being computed. Note that if the order is `None` then the resulting order will depend on the algorithm.

      - If `order` is `'database'` or `'sage'`, then the reordering is so that the order of curves matches the order produced by that algorithm.

      - If `order` is `'lmfdb'` then the curves are sorted lexicographically by a-invariants, in the LMFDB database.

      - If `order` is a list of curves, then the curves in the class are reordered to be isomorphic with the specified list of curves.

    OUTPUT:

    An instance of the class `sage.schemes.elliptic_curves.isogeny_class.IsogenyClass_EC_Rational`. This object models a list of minimal models (with containment, index, etc based on isomorphism classes). It also has methods for computing the isogeny matrix and the list of isogenies between curves in this class.

    Note

    The curves in the isogeny class will all be standard minimal models.

    EXAMPLES:

    Sage

        sage: isocls = EllipticCurve('37b').isogeny_class(order='lmfdb')
        sage: isocls
        Elliptic curve isogeny class 37b
        sage: isocls.curves
        (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)
        sage: isocls.matrix()
        [1 3 9]
        [3 1 3]
        [9 3 1]

    Python

        >>> from sage.all import *
        >>> isocls = EllipticCurve('37b').isogeny_class(order='lmfdb')
        >>> isocls
        Elliptic curve isogeny class 37b
        >>> isocls.curves
        (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)
        >>> isocls.matrix()
        [1 3 9]
        [3 1 3]
        [9 3 1]

    Sage

        sage: isocls = EllipticCurve('37b').isogeny_class('database', order='lmfdb'); isocls.curves
        (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)

    [Python]

        >>> from sage.all import *
        >>> isocls = EllipticCurve('37b').isogeny_class('database', order='lmfdb'); isocls.curves
        (Elliptic Curve defined by y^2 + y = x^3 + x^2 - 1873*x - 31833 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 23*x - 50 over Rational Field,
         Elliptic Curve defined by y^2 + y = x^3 + x^2 - 3*x + 1 over Rational Field)

    This is an example of a curve with a \(37\)-isogeny:

    Sage

        sage: E = EllipticCurve([1,1,1,-8,6])
        sage: isocls = E.isogeny_class(); isocls
        Isogeny class of Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field
        sage: isocls.matrix()
        [ 1 37]
        [37  1]
        sage: print("\n".join(repr(E) for E in isocls.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 208083*x - 36621194 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1),Integer(1),Integer(1),-Integer(8),Integer(6)])
        >>> isocls = E.isogeny_class(); isocls
        Isogeny class of Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field
        >>> isocls.matrix()
        [ 1 37]
        [37  1]
        >>> print("\n".join(repr(E) for E in isocls.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 8*x + 6 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 208083*x - 36621194 over Rational Field

    This curve had numerous \(2\)-isogenies:

    Sage

        sage: e = EllipticCurve([1,0,0,-39,90])
        sage: isocls = e.isogeny_class(); isocls.matrix()
        [1 2 4 4 8 8]
        [2 1 2 2 4 4]
        [4 2 1 4 8 8]
        [4 2 4 1 2 2]
        [8 4 8 2 1 4]
        [8 4 8 2 4 1]

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve([Integer(1),Integer(0),Integer(0),-Integer(39),Integer(90)])
        >>> isocls = e.isogeny_class(); isocls.matrix()
        [1 2 4 4 8 8]
        [2 1 2 2 4 4]
        [4 2 1 4 8 8]
        [4 2 4 1 2 2]
        [8 4 8 2 1 4]
        [8 4 8 2 4 1]

    See http://math.harvard.edu/~elkies/nature.html for more interesting examples of isogeny structures.

    Sage

        sage: E = EllipticCurve(j = -262537412640768000)
        sage: isocls = E.isogeny_class(); isocls.matrix()
        [  1 163]
        [163   1]
        sage: print("\n".join(repr(C) for C in isocls.curves))
        Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field
        Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve(j = -Integer(262537412640768000))
        >>> isocls = E.isogeny_class(); isocls.matrix()
        [  1 163]
        [163   1]
        >>> print("\n".join(repr(C) for C in isocls.curves))
        Elliptic Curve defined by y^2 + y = x^3 - 2174420*x + 1234136692 over Rational Field
        Elliptic Curve defined by y^2 + y = x^3 - 57772164980*x - 5344733777551611 over Rational Field

    The degrees of isogenies are invariant under twists:

    Sage

        sage: E = EllipticCurve(j = -262537412640768000)
        sage: E1 = E.quadratic_twist(6584935282)
        sage: isocls = E1.isogeny_class(); isocls.matrix()
        [  1 163]
        [163   1]
        sage: E1.conductor()
        18433092966712063653330496

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve(j = -Integer(262537412640768000))
        >>> E1 = E.quadratic_twist(Integer(6584935282))
        >>> isocls = E1.isogeny_class(); isocls.matrix()
        [  1 163]
        [163   1]
        >>> E1.conductor()
        18433092966712063653330496

    Sage

        sage: E = EllipticCurve('14a1')
        sage: isocls = E.isogeny_class(); isocls.matrix()
        [ 1  2  3  3  6  6]
        [ 2  1  6  6  3  3]
        [ 3  6  1  9  2 18]
        [ 3  6  9  1 18  2]
        [ 6  3  2 18  1  9]
        [ 6  3 18  2  9  1]
        sage: print("\n".join(repr(C) for C in isocls.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field
        sage: isocls2 = isocls.reorder('lmfdb'); isocls2.matrix()
        [ 1  2  3  9 18  6]
        [ 2  1  6 18  9  3]
        [ 3  6  1  3  6  2]
        [ 9 18  3  1  2  6]
        [18  9  6  2  1  3]
        [ 6  3  2  6  3  1]
        sage: print("\n".join(repr(C) for C in isocls2.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('14a1')
        >>> isocls = E.isogeny_class(); isocls.matrix()
        [ 1  2  3  3  6  6]
        [ 2  1  6  6  3  3]
        [ 3  6  1  9  2 18]
        [ 3  6  9  1 18  2]
        [ 6  3  2 18  1  9]
        [ 6  3 18  2  9  1]
        >>> print("\n".join(repr(C) for C in isocls.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field
        >>> isocls2 = isocls.reorder('lmfdb'); isocls2.matrix()
        [ 1  2  3  9 18  6]
        [ 2  1  6 18  9  3]
        [ 3  6  1  3  6  2]
        [ 9 18  3  1  2  6]
        [18  9  6  2  1  3]
        [ 6  3  2  6  3  1]
        >>> print("\n".join(repr(C) for C in isocls2.curves))
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 2731*x - 55146 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 171*x - 874 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 36*x - 70 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - 11*x + 12 over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x over Rational Field
        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field

    Sage

        sage: E = EllipticCurve('11a1')
        sage: isocls = E.isogeny_class(); isocls.matrix()
        [ 1  5  5]
        [ 5  1 25]
        [ 5 25  1]
        sage: f = isocls.isogenies()[0][1]; f.kernel_polynomial()
        x^2 + x - 29/5

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('11a1')
        >>> isocls = E.isogeny_class(); isocls.matrix()
        [ 1  5  5]
        [ 5  1 25]
        [ 5 25  1]
        >>> f = isocls.isogenies()[Integer(0)][Integer(1)]; f.kernel_polynomial()
        x^2 + x - 29/5

  isogeny_degree(other)

    Return the minimal degree of an isogeny between `self` and `other`.

    INPUT:

    - `other` – another elliptic curve

    OUTPUT:

    The minimal degree of an isogeny from `self` to `other`, or \(0\) if the curves are not isogenous.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([-1056, 13552])
        sage: E2 = EllipticCurve([-127776, -18037712])
        sage: E.isogeny_degree(E2)
        11

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(1056), Integer(13552)])
        >>> E2 = EllipticCurve([-Integer(127776), -Integer(18037712)])
        >>> E.isogeny_degree(E2)
        11

    Sage

        sage: E1 = EllipticCurve('14a1')
        sage: E2 = EllipticCurve('14a2')
        sage: E3 = EllipticCurve('14a3')
        sage: E4 = EllipticCurve('14a4')
        sage: E5 = EllipticCurve('14a5')
        sage: E6 = EllipticCurve('14a6')
        sage: E3.isogeny_degree(E1)
        3
        sage: E3.isogeny_degree(E2)
        6
        sage: E3.isogeny_degree(E3)
        1
        sage: E3.isogeny_degree(E4)
        9
        sage: E3.isogeny_degree(E5)
        2
        sage: E3.isogeny_degree(E6)
        18

    [Python]

        >>> from sage.all import *
        >>> E1 = EllipticCurve('14a1')
        >>> E2 = EllipticCurve('14a2')
        >>> E3 = EllipticCurve('14a3')
        >>> E4 = EllipticCurve('14a4')
        >>> E5 = EllipticCurve('14a5')
        >>> E6 = EllipticCurve('14a6')
        >>> E3.isogeny_degree(E1)
        3
        >>> E3.isogeny_degree(E2)
        6
        >>> E3.isogeny_degree(E3)
        1
        >>> E3.isogeny_degree(E4)
        9
        >>> E3.isogeny_degree(E5)
        2
        >>> E3.isogeny_degree(E6)
        18

    Sage

        sage: E1 = EllipticCurve('30a1')
        sage: E2 = EllipticCurve('30a2')
        sage: E3 = EllipticCurve('30a3')
        sage: E4 = EllipticCurve('30a4')
        sage: E5 = EllipticCurve('30a5')
        sage: E6 = EllipticCurve('30a6')
        sage: E7 = EllipticCurve('30a7')
        sage: E8 = EllipticCurve('30a8')
        sage: E1.isogeny_degree(E1)
        1
        sage: E1.isogeny_degree(E2)
        2
        sage: E1.isogeny_degree(E3)
        3
        sage: E1.isogeny_degree(E4)
        4
        sage: E1.isogeny_degree(E5)
        4
        sage: E1.isogeny_degree(E6)
        6
        sage: E1.isogeny_degree(E7)
        12
        sage: E1.isogeny_degree(E8)
        12

    Python

        >>> from sage.all import *
        >>> E1 = EllipticCurve('30a1')
        >>> E2 = EllipticCurve('30a2')
        >>> E3 = EllipticCurve('30a3')
        >>> E4 = EllipticCurve('30a4')
        >>> E5 = EllipticCurve('30a5')
        >>> E6 = EllipticCurve('30a6')
        >>> E7 = EllipticCurve('30a7')
        >>> E8 = EllipticCurve('30a8')
        >>> E1.isogeny_degree(E1)
        1
        >>> E1.isogeny_degree(E2)
        2
        >>> E1.isogeny_degree(E3)
        3
        >>> E1.isogeny_degree(E4)
        4
        >>> E1.isogeny_degree(E5)
        4
        >>> E1.isogeny_degree(E6)
        6
        >>> E1.isogeny_degree(E7)
        12
        >>> E1.isogeny_degree(E8)
        12

    Sage

        sage: E1 = EllipticCurve('15a1')
        sage: E2 = EllipticCurve('15a2')
        sage: E3 = EllipticCurve('15a3')
        sage: E4 = EllipticCurve('15a4')
        sage: E5 = EllipticCurve('15a5')
        sage: E6 = EllipticCurve('15a6')
        sage: E7 = EllipticCurve('15a7')
        sage: E8 = EllipticCurve('15a8')
        sage: E1.isogeny_degree(E1)
        1
        sage: E7.isogeny_degree(E2)
        8
        sage: E7.isogeny_degree(E3)
        2
        sage: E7.isogeny_degree(E4)
        8
        sage: E7.isogeny_degree(E5)
        16
        sage: E7.isogeny_degree(E6)
        16
        sage: E7.isogeny_degree(E8)
        4

    [Python]

        >>> from sage.all import *
        >>> E1 = EllipticCurve('15a1')
        >>> E2 = EllipticCurve('15a2')
        >>> E3 = EllipticCurve('15a3')
        >>> E4 = EllipticCurve('15a4')
        >>> E5 = EllipticCurve('15a5')
        >>> E6 = EllipticCurve('15a6')
        >>> E7 = EllipticCurve('15a7')
        >>> E8 = EllipticCurve('15a8')
        >>> E1.isogeny_degree(E1)
        1
        >>> E7.isogeny_degree(E2)
        8
        >>> E7.isogeny_degree(E3)
        2
        >>> E7.isogeny_degree(E4)
        8
        >>> E7.isogeny_degree(E5)
        16
        >>> E7.isogeny_degree(E6)
        16
        >>> E7.isogeny_degree(E8)
        4

    0 is returned when the curves are not isogenous:

    Sage

        sage: A = EllipticCurve('37a1')
        sage: B = EllipticCurve('37b1')
        sage: A.isogeny_degree(B)
        0
        sage: A.is_isogenous(B)
        False

    Python

        >>> from sage.all import *
        >>> A = EllipticCurve('37a1')
        >>> B = EllipticCurve('37b1')
        >>> A.isogeny_degree(B)
        0
        >>> A.is_isogenous(B)
        False

  isogeny_graph(order=None)

    Return a graph representing the isogeny class of this elliptic curve, where the vertices are isogenous curves over \(\QQ\) and the edges are prime degree isogenies.

    Note

    The vertices are labeled \(1\) to \(n\) rather than \(0\) to \(n-1\) to correspond to LMFDB and Cremona labels.

    EXAMPLES:

    Sage

        sage: LL = []
        sage: for e in cremona_optimal_curves(range(1, 38)):  # long time
        ....:  G = e.isogeny_graph()
        ....:  already = False
        ....:  for H in LL:
        ....:      if G.is_isomorphic(H):
        ....:          already = True
        ....:          break
        ....:  if not already:
        ....:      LL.append(G)
        sage: graphs_list.show_graphs(LL)  # long time

    Python

        >>> from sage.all import *
        >>> LL = []
        >>> for e in cremona_optimal_curves(range(Integer(1), Integer(38))):  # long time
        ...  G = e.isogeny_graph()
        ...  already = False
        ...  for H in LL:
        ...      if G.is_isomorphic(H):
        ...          already = True
        ...          break
        ...  if not already:
        ...      LL.append(G)
        >>> graphs_list.show_graphs(LL)  # long time

    Sage

        sage: E = EllipticCurve('195a')
        sage: G = E.isogeny_graph()
        sage: for v in G: print("{} {}".format(v, G.get_vertex(v)))
        1 Elliptic Curve defined by y^2 + x*y  = x^3 - 110*x + 435 over Rational Field
        2 Elliptic Curve defined by y^2 + x*y  = x^3 - 115*x + 392 over Rational Field
        3 Elliptic Curve defined by y^2 + x*y  = x^3 + 210*x + 2277 over Rational Field
        4 Elliptic Curve defined by y^2 + x*y  = x^3 - 520*x - 4225 over Rational Field
        5 Elliptic Curve defined by y^2 + x*y  = x^3 + 605*x - 19750 over Rational Field
        6 Elliptic Curve defined by y^2 + x*y  = x^3 - 8125*x - 282568 over Rational Field
        7 Elliptic Curve defined by y^2 + x*y  = x^3 - 7930*x - 296725 over Rational Field
        8 Elliptic Curve defined by y^2 + x*y  = x^3 - 130000*x - 18051943 over Rational Field
        sage: G.plot(edge_labels=True)                                              # needs sage.plot
        Graphics object consisting of 23 graphics primitives

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('195a')
        >>> G = E.isogeny_graph()
        >>> for v in G: print("{} {}".format(v, G.get_vertex(v)))
        1 Elliptic Curve defined by y^2 + x*y  = x^3 - 110*x + 435 over Rational Field
        2 Elliptic Curve defined by y^2 + x*y  = x^3 - 115*x + 392 over Rational Field
        3 Elliptic Curve defined by y^2 + x*y  = x^3 + 210*x + 2277 over Rational Field
        4 Elliptic Curve defined by y^2 + x*y  = x^3 - 520*x - 4225 over Rational Field
        5 Elliptic Curve defined by y^2 + x*y  = x^3 + 605*x - 19750 over Rational Field
        6 Elliptic Curve defined by y^2 + x*y  = x^3 - 8125*x - 282568 over Rational Field
        7 Elliptic Curve defined by y^2 + x*y  = x^3 - 7930*x - 296725 over Rational Field
        8 Elliptic Curve defined by y^2 + x*y  = x^3 - 130000*x - 18051943 over Rational Field
        >>> G.plot(edge_labels=True)                                              # needs sage.plot
        Graphics object consisting of 23 graphics primitives

  kodaira_symbol(p)

    alias of `kodaira_type()`.

  kodaira_type(p)

    Local Kodaira type of the elliptic curve at `p`.

    INPUT:

    - `p` – an integral prime

    OUTPUT:

    - the Kodaira type of this elliptic curve at `p`, as a `KodairaSymbol`

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('124a')
        sage: E.kodaira_type(2)
        IV

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('124a')
        >>> E.kodaira_type(Integer(2))
        IV

  kodaira_type_old(p)

    Local Kodaira type of the elliptic curve at `p`.

    INPUT:

    - `p` – an integral prime

    OUTPUT:

    - the Kodaira type of this elliptic curve at `p`, as a `KodairaSymbol`

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('124a')
        sage: E.kodaira_type_old(2)
        IV

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('124a')
        >>> E.kodaira_type_old(Integer(2))
        IV

  kolyvagin_point(D, c=1, check=True)

    Return the Kolyvagin point on this curve associated to the quadratic imaginary field \(K=\QQ(\sqrt{D})\) and conductor \(c\).

    INPUT:

    - `D` – a Heegner discriminant

    - `c` – (default: 1) conductor, must be coprime to \(DN\)

    - `check` – boolean (default: `True`)

    OUTPUT: the Kolyvagin point \(P\) of conductor \(c\)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: P = E.kolyvagin_point(-67); P
        Kolyvagin point of discriminant -67 on elliptic curve of conductor 37
        sage: P.numerical_approx()  # abs tol 1e-14
        (6.00000000000000 : -15.0000000000000 : 1.00000000000000)
        sage: P.index()
        6
        sage: g = E((0,-1,1)) # a generator
        sage: E.regulator() == E.regulator_of_points([g])
        True
        sage: 6*g
        (6 : -15 : 1)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> P = E.kolyvagin_point(-Integer(67)); P
        Kolyvagin point of discriminant -67 on elliptic curve of conductor 37
        >>> P.numerical_approx()  # abs tol 1e-14
        (6.00000000000000 : -15.0000000000000 : 1.00000000000000)
        >>> P.index()
        6
        >>> g = E((Integer(0),-Integer(1),Integer(1))) # a generator
        >>> E.regulator() == E.regulator_of_points([g])
        True
        >>> Integer(6)*g
        (6 : -15 : 1)

  label(space=False)

    alias of `cremona_label()`.

  lmfdb_page()

    Open the LMFDB web page of the elliptic curve in a browser.

    See http://www.lmfdb.org

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('5077a1')
        sage: E.lmfdb_page()  # optional -- webbrowser

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('5077a1')
        >>> E.lmfdb_page()  # optional -- webbrowser

  local_integral_model(p)

    Return a model of `self` which is integral at the prime \(p\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, 0, 1/216, -7/1296, 1/7776])
        sage: E.local_integral_model(2)
        Elliptic Curve defined by y^2 + 1/27*y = x^3 - 7/81*x + 2/243 over Rational Field
        sage: E.local_integral_model(3)
        Elliptic Curve defined by y^2 + 1/8*y = x^3 - 7/16*x + 3/32 over Rational Field
        sage: E.local_integral_model(2).local_integral_model(3) == EllipticCurve('5077a1')
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1)/Integer(216), -Integer(7)/Integer(1296), Integer(1)/Integer(7776)])
        >>> E.local_integral_model(Integer(2))
        Elliptic Curve defined by y^2 + 1/27*y = x^3 - 7/81*x + 2/243 over Rational Field
        >>> E.local_integral_model(Integer(3))
        Elliptic Curve defined by y^2 + 1/8*y = x^3 - 7/16*x + 3/32 over Rational Field
        >>> E.local_integral_model(Integer(2)).local_integral_model(Integer(3)) == EllipticCurve('5077a1')
        True

  lseries()

    Return the \(L\)-series of this elliptic curve.

    Further documentation is available for the functions which apply to the \(L\)-series.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.lseries()
        Complex L-series of the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.lseries()
        Complex L-series of the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

  lseries_gross_zagier(A)

    Return the Gross-Zagier \(L\)-series attached to `self` and an ideal class \(A\).

    INPUT:

    - `A` – an ideal class in an imaginary quadratic number field \(K\)

    This \(L\)-series \(L(E,A,s)\) is defined as the product of a shifted \(L\)-function of the quadratic character associated to \(K\) and the Dirichlet series whose \(n\)-th coefficient is the product of the \(n\)-th factor of the \(L\)-series of \(E\) and the number of integral ideal in \(A\) of norm \(n\). For any character \(\chi\) on the class group of \(K\), one gets \(L_K(E,\chi,s) = \sum_{A} \chi(A) L(E,A,s)\) where \(A\) runs through the class group of \(K\).

    For the exact definition see section IV of [GZ1986].

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: K.<a> = QuadraticField(-40)
        sage: A = K.class_group().gen(0); A
        Fractional ideal class (2, 1/2*a)
        sage: L = E.lseries_gross_zagier(A)  ; L
        Gross Zagier L-series attached to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
         with ideal class Fractional ideal class (2, 1/2*a)
        sage: L(1)
        0.000000000000000
        sage: L.taylor_series(1, 5)
        0.000000000000000 - 5.51899839494458*z + 13.6297841350649*z^2 - 16.2292417817675*z^3 + 7.94788823722712*z^4 + O(z^5)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> K = QuadraticField(-Integer(40), names=('a',)); (a,) = K._first_ngens(1)
        >>> A = K.class_group().gen(Integer(0)); A
        Fractional ideal class (2, 1/2*a)
        >>> L = E.lseries_gross_zagier(A)  ; L
        Gross Zagier L-series attached to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
         with ideal class Fractional ideal class (2, 1/2*a)
        >>> L(Integer(1))
        0.000000000000000
        >>> L.taylor_series(Integer(1), Integer(5))
        0.000000000000000 - 5.51899839494458*z + 13.6297841350649*z^2 - 16.2292417817675*z^3 + 7.94788823722712*z^4 + O(z^5)

    These should be equal:

    Sage

        sage: L(2) + E.lseries_gross_zagier(A^2)(2) # rel tol 5e-14
        0.502803417587467
        sage: E.lseries()(2) * E.quadratic_twist(-40).lseries()(2)
        0.502803417587467

    [Python]

        >>> from sage.all import *
        >>> L(Integer(2)) + E.lseries_gross_zagier(A**Integer(2))(Integer(2)) # rel tol 5e-14
        0.502803417587467
        >>> E.lseries()(Integer(2)) * E.quadratic_twist(-Integer(40)).lseries()(Integer(2))
        0.502803417587467

  manin_constant()

    Return the Manin constant of this elliptic curve.

    If \(\phi: X_0(N) \to E\) is the modular parametrization of minimal degree, then the Manin constant \(c\) is defined to be the rational number \(c\) such that \(\phi^*(\omega_E) = c\cdot \omega_f\) where \(\omega_E\) is a Néron differential and \(\omega_f = f(q) dq/q\) is the differential on \(X_0(N)\) corresponding to the newform \(f\) attached to the isogeny class of \(E\).

    It is known that the Manin constant is an integer. It is conjectured that in each class there is at least one, more precisely the so-called strong Weil curve or \(X_0(N)\)-optimal curve, that has Manin constant \(1\).

    OUTPUT: integer

    This function only works if the curve is in the installed Cremona database. Sage includes by default a small database; for the full database you have to install an optional package.

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a1').manin_constant()
        1
        sage: EllipticCurve('11a2').manin_constant()
        1
        sage: EllipticCurve('11a3').manin_constant()
        5

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a1').manin_constant()
        1
        >>> EllipticCurve('11a2').manin_constant()
        1
        >>> EllipticCurve('11a3').manin_constant()
        5

    Check that it works even if the curve is non-minimal:

    Sage

        sage: EllipticCurve('11a3').change_weierstrass_model([1/35,0,0,0]).manin_constant()
        5

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve('11a3').change_weierstrass_model([Integer(1)/Integer(35),Integer(0),Integer(0),Integer(0)]).manin_constant()
        5

    Rather complicated examples (see Issue #12080)

    Sage

        sage: [ EllipticCurve('27a%s'%i).manin_constant() for i in [1,2,3,4]]
        [1, 1, 3, 3]
        sage: [ EllipticCurve('80b%s'%i).manin_constant() for i in [1,2,3,4]]
        [1, 2, 1, 2]

    Python

        >>> from sage.all import *
        >>> [ EllipticCurve('27a%s'%i).manin_constant() for i in [Integer(1),Integer(2),Integer(3),Integer(4)]]
        [1, 1, 3, 3]
        >>> [ EllipticCurve('80b%s'%i).manin_constant() for i in [Integer(1),Integer(2),Integer(3),Integer(4)]]
        [1, 2, 1, 2]

  matrix_of_frobenius(p, prec=20, check=False, check_hypotheses=True, algorithm='auto')

    Return the matrix of Frobenius on the Monsky Washnitzer cohomology of the short Weierstrass model of the minimal model of the elliptic curve.

    INPUT:

    - `p` – prime (>= 3) for which \(E\) is good and ordinary

    - `prec` – (relative) \(p\)-adic precision for result (default: 20)

    - `check` – boolean (default: `False`); whether to perform a consistency check. This will slow down the computation by a constant factor 2. (The consistency check is to verify that its trace is correct to the specified precision. Otherwise, the trace is used to compute one column from the other one (possibly after a change of basis).)

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic sigma function makes sense

    - `algorithm` – one of `'standard'`, `'sqrtp'`, or `'auto'`. This selects which version of Kedlaya’s algorithm is used. The `'standard'` one is the one described in Kedlaya’s paper. The `'sqrtp'` one has better performance for large \(p\), but only works when \(p > 6N\) (\(N=\) prec). The `'auto'` option selects `'sqrtp'` whenever possible.

      Note that if the `'sqrtp'` algorithm is used, a consistency check will automatically be applied, regardless of the setting of the `check` flag.

    OUTPUT: a matrix of \(p\)-adic number to precision `prec`

    See also the documentation of padic_E2.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.matrix_of_frobenius(7)
        [             2*7 + 4*7^2 + 5*7^4 + 6*7^5 + 6*7^6 + 7^8 + 4*7^9 + 3*7^10 + 2*7^11 + 5*7^12 + 4*7^14 + 7^16 + 2*7^17 + 3*7^18 + 4*7^19 + 3*7^20 + O(7^21)                                   2 + 3*7 + 6*7^2 + 7^3 + 3*7^4 + 5*7^5 + 3*7^7 + 7^8 + 3*7^9 + 6*7^13 + 7^14 + 7^16 + 5*7^17 + 4*7^18 + 7^19 + O(7^20)]
        [    2*7 + 3*7^2 + 7^3 + 3*7^4 + 6*7^5 + 2*7^6 + 3*7^7 + 5*7^8 + 3*7^9 + 2*7^11 + 6*7^12 + 5*7^13 + 4*7^16 + 4*7^17 + 6*7^18 + 6*7^19 + 4*7^20 + O(7^21) 6 + 4*7 + 2*7^2 + 6*7^3 + 7^4 + 6*7^7 + 5*7^8 + 2*7^9 + 3*7^10 + 4*7^11 + 7^12 + 6*7^13 + 2*7^14 + 6*7^15 + 5*7^16 + 4*7^17 + 3*7^18 + 2*7^19 + O(7^20)]
        sage: M = E.matrix_of_frobenius(11,prec=3); M
        [   9*11 + 9*11^3 + O(11^4)          10 + 11 + O(11^3)]
        [     2*11 + 11^2 + O(11^4) 6 + 11 + 10*11^2 + O(11^3)]
        sage: M.det()
        11 + O(11^4)
        sage: M.trace()
        6 + 10*11 + 10*11^2 + O(11^3)
        sage: E.ap(11)
        -5
        sage: E = EllipticCurve('83a1')
        sage: E.matrix_of_frobenius(3,6)
        [                      2*3 + 3^5 + O(3^6)             2*3 + 2*3^2 + 2*3^3 + O(3^6)]
        [              2*3 + 3^2 + 2*3^5 + O(3^6) 2 + 2*3^2 + 2*3^3 + 2*3^4 + 3^5 + O(3^6)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.matrix_of_frobenius(Integer(7))
        [             2*7 + 4*7^2 + 5*7^4 + 6*7^5 + 6*7^6 + 7^8 + 4*7^9 + 3*7^10 + 2*7^11 + 5*7^12 + 4*7^14 + 7^16 + 2*7^17 + 3*7^18 + 4*7^19 + 3*7^20 + O(7^21)                                   2 + 3*7 + 6*7^2 + 7^3 + 3*7^4 + 5*7^5 + 3*7^7 + 7^8 + 3*7^9 + 6*7^13 + 7^14 + 7^16 + 5*7^17 + 4*7^18 + 7^19 + O(7^20)]
        [    2*7 + 3*7^2 + 7^3 + 3*7^4 + 6*7^5 + 2*7^6 + 3*7^7 + 5*7^8 + 3*7^9 + 2*7^11 + 6*7^12 + 5*7^13 + 4*7^16 + 4*7^17 + 6*7^18 + 6*7^19 + 4*7^20 + O(7^21) 6 + 4*7 + 2*7^2 + 6*7^3 + 7^4 + 6*7^7 + 5*7^8 + 2*7^9 + 3*7^10 + 4*7^11 + 7^12 + 6*7^13 + 2*7^14 + 6*7^15 + 5*7^16 + 4*7^17 + 3*7^18 + 2*7^19 + O(7^20)]
        >>> M = E.matrix_of_frobenius(Integer(11),prec=Integer(3)); M
        [   9*11 + 9*11^3 + O(11^4)          10 + 11 + O(11^3)]
        [     2*11 + 11^2 + O(11^4) 6 + 11 + 10*11^2 + O(11^3)]
        >>> M.det()
        11 + O(11^4)
        >>> M.trace()
        6 + 10*11 + 10*11^2 + O(11^3)
        >>> E.ap(Integer(11))
        -5
        >>> E = EllipticCurve('83a1')
        >>> E.matrix_of_frobenius(Integer(3),Integer(6))
        [                      2*3 + 3^5 + O(3^6)             2*3 + 2*3^2 + 2*3^3 + O(3^6)]
        [              2*3 + 3^2 + 2*3^5 + O(3^6) 2 + 2*3^2 + 2*3^3 + 2*3^4 + 3^5 + O(3^6)]

  minimal_model()

    Return the unique minimal Weierstrass equation for this elliptic curve.

    This is the model with minimal discriminant and \(a_1,a_2,a_3 \in \{0,\pm 1\}\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([10,100,1000,10000,1000000])
        sage: E.minimal_model()
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(10),Integer(100),Integer(1000),Integer(10000),Integer(1000000)])
        >>> E.minimal_model()
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Rational Field

  minimal_quadratic_twist()

    Determine a quadratic twist with minimal conductor. Return a global minimal model of the twist and the fundamental discriminant of the quadratic field over which they are isomorphic.

    Note

    If there is more than one curve with minimal conductor, the one returned is the one with smallest label (if in the database), or the one with minimal \(a\)-invariant list (otherwise).

    Note

    For curves with \(j\)-invariant 0 or 1728 the curve returned is the minimal quadratic twist, not necessarily the minimal twist (which would have conductor 27 or 32 respectively).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('121d1')
        sage: E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field, -11)
        sage: Et, D = EllipticCurve('32a1').minimal_quadratic_twist()
        sage: D
        1

        sage: E = EllipticCurve('11a1')
        sage: Et, D = E.quadratic_twist(-24).minimal_quadratic_twist()
        sage: E == Et
        True
        sage: D
        -24

        sage: E = EllipticCurve([0,0,0,0,1000])
        sage: E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field, 40)
        sage: E = EllipticCurve([0,0,0,1600,0])
        sage: E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, 5)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('121d1')
        >>> E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 + y = x^3 - x^2 over Rational Field, -11)
        >>> Et, D = EllipticCurve('32a1').minimal_quadratic_twist()
        >>> D
        1

        >>> E = EllipticCurve('11a1')
        >>> Et, D = E.quadratic_twist(-Integer(24)).minimal_quadratic_twist()
        >>> E == Et
        True
        >>> D
        -24

        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(1000)])
        >>> E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 = x^3 + 1 over Rational Field, 40)
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(1600),Integer(0)])
        >>> E.minimal_quadratic_twist()
        (Elliptic Curve defined by y^2 = x^3 + 4*x over Rational Field, 5)

    If the curve has square-free conductor then it is already minimal (see Issue #14060):

    Sage

        sage: E = next(cremona_optimal_curves([2*3*5*7*11]))
        sage: (E, 1) == E.minimal_quadratic_twist()
        True

    [Python]

        >>> from sage.all import *
        >>> E = next(cremona_optimal_curves([Integer(2)*Integer(3)*Integer(5)*Integer(7)*Integer(11)]))
        >>> (E, Integer(1)) == E.minimal_quadratic_twist()
        True

    An example where the minimal quadratic twist is not the minimal twist (which has conductor 27):

    Sage

        sage: E = EllipticCurve([0,0,0,0,7])
        sage: E.j_invariant()
        0
        sage: E.minimal_quadratic_twist()[0].conductor()
        5292

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(7)])
        >>> E.j_invariant()
        0
        >>> E.minimal_quadratic_twist()[Integer(0)].conductor()
        5292

  mod5family()

    Return the family of all elliptic curves with the same mod-5 representation as `self`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('32a1')
        sage: E.mod5family()
        Elliptic Curve defined by y^2 = x^3 + 4*x
         over Fraction Field of Univariate Polynomial Ring in t over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('32a1')
        >>> E.mod5family()
        Elliptic Curve defined by y^2 = x^3 + 4*x
         over Fraction Field of Univariate Polynomial Ring in t over Rational Field

  modular_degree(algorithm='sympow', M=1)

    Return the modular degree at level \(MN\) of this elliptic curve. The case \(M==1\) corresponds to the classical definition of modular degree.

    When \(M>1\), the function returns the degree of the map from \(X_0(MN) \to A\), where A is the abelian variety generated by embeddings of \(E\) into \(J_0(MN)\).

    The result is cached. Subsequent calls, even with a different algorithm, just returned the cached result. The algorithm argument is ignored when \(M>1\).

    INPUT:

    - `algorithm` – string; one of

      - `'sympow'` – (default) use Mark Watkin’s (newer) C program sympow

      - `'magma'` – requires that MAGMA be installed (also implemented by Mark Watkins)

    - `M` – nonnegative integer; the modular degree at level \(MN\) is returned (see above)

    Note

    On 64-bit computers ec does not work, so Sage uses sympow even if ec is selected on a 64-bit computer.

    The correctness of this function when called with algorithm “sympow” is subject to the following three hypothesis:

    - Manin’s conjecture: the Manin constant is 1

    - Steven’s conjecture: the \(X_1(N)\)-optimal quotient is the curve with minimal Faltings height. (This is proved in most cases.)

    - The modular degree fits in a machine double, so it better be less than about 50-some bits. (If you use sympow this constraint does not apply.)

    Moreover for all algorithms, computing a certain value of an \(L\)-function ‘uses a heuristic method that discerns when the real-number approximation to the modular degree is within epsilon [=0.01 for algorithm=’sympow’] of the same integer for 3 consecutive trials (which occur maybe every 25000 coefficients or so). Probably it could just round at some point. For rigour, you would need to bound the tail by assuming (essentially) that all the \(a_n\) are as large as possible, but in practice they exhibit significant (square root) cancellation. One difficulty is that it doesn’t do the sum in 1-2-3-4 order; it uses 1-2-4-8–3-6-12-24-9-18- (Euler product style) instead, and so you have to guess ahead of time at what point to curtail this expansion.’ (Quote from an email of Mark Watkins.)

    Note

    If the curve is loaded from the large Cremona database, then the modular degree is taken from the database.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, -1, 1, -10, -20])
        sage: E
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        sage: E.modular_degree()
        1
        sage: E = EllipticCurve('5077a')
        sage: E.modular_degree()
        1984
        sage: factor(1984)
        2^6 * 31

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(10), -Integer(20)])
        >>> E
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        >>> E.modular_degree()
        1
        >>> E = EllipticCurve('5077a')
        >>> E.modular_degree()
        1984
        >>> factor(Integer(1984))
        2^6 * 31

    Sage

        sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree()
        1984
        sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree(algorithm='sympow')
        1984
        sage: EllipticCurve([0, 0, 1, -7, 6]).modular_degree(algorithm='magma')  # optional - magma
        1984

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(7), Integer(6)]).modular_degree()
        1984
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(7), Integer(6)]).modular_degree(algorithm='sympow')
        1984
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(7), Integer(6)]).modular_degree(algorithm='magma')  # optional - magma
        1984

    We compute the modular degree of the curve with rank 4 having smallest (known) conductor:

    Sage

        sage: E = EllipticCurve([1, -1, 0, -79, 289])
        sage: factor(E.conductor())  # conductor is 234446
        2 * 117223
        sage: factor(E.modular_degree())
        2^7 * 2617

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), -Integer(1), Integer(0), -Integer(79), Integer(289)])
        >>> factor(E.conductor())  # conductor is 234446
        2 * 117223
        >>> factor(E.modular_degree())
        2^7 * 2617

    Higher level cases:

    Sage

        sage: E = EllipticCurve('11a')
        sage: for M in range(1,11): print(E.modular_degree(M=M)) # long time (20s on 2009 MBP)
        1
        1
        3
        2
        7
        45
        12
        16
        54
        245

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> for M in range(Integer(1),Integer(11)): print(E.modular_degree(M=M)) # long time (20s on 2009 MBP)
        1
        1
        3
        2
        7
        45
        12
        16
        54
        245

  modular_form()

    Return the cuspidal modular form associated to this elliptic curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: f = E.modular_form()
        sage: f
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> f = E.modular_form()
        >>> f
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)

    If you need to see more terms in the \(q\)-expansion:

    Sage

        sage: f.q_expansion(20)
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10
         - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)

    [Python]

        >>> from sage.all import *
        >>> f.q_expansion(Integer(20))
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10
         - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)

    Note

    If you just want the \(q\)-expansion, use `q_expansion()`.

  modular_parametrization()

    Return the modular parametrization of this elliptic curve, which is a map from \(X_0(N)\) to self, where \(N\) is the conductor of `self`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('15a')
        sage: phi = E.modular_parametrization(); phi
        Modular parameterization
         from the upper half plane
           to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10
              over Rational Field
        sage: z = 0.1 + 0.2j
        sage: phi(z)
        (8.20822465478531 - 13.1562816054682*I : -8.79855099049364 + 69.4006129342200*I : 1.00000000000000)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('15a')
        >>> phi = E.modular_parametrization(); phi
        Modular parameterization
         from the upper half plane
           to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10
              over Rational Field
        >>> z = RealNumber('0.1') + ComplexNumber(0, '0.2')
        >>> phi(z)
        (8.20822465478531 - 13.1562816054682*I : -8.79855099049364 + 69.4006129342200*I : 1.00000000000000)

    This map is actually a map on \(X_0(N)\), so equivalent representatives in the upper half plane map to the same point:

    Sage

        sage: phi((-7*z-1)/(15*z+2))
        (8.20822465478524 - 13.1562816054681*I : -8.79855099049... + 69.4006129342...*I : 1.00000000000000)

    [Python]

        >>> from sage.all import *
        >>> phi((-Integer(7)*z-Integer(1))/(Integer(15)*z+Integer(2)))
        (8.20822465478524 - 13.1562816054681*I : -8.79855099049... + 69.4006129342...*I : 1.00000000000000)

    We can also get a series expansion of this modular parameterization:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: X, Y = E.modular_parametrization().power_series()
        sage: X
        q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18)
        sage: Y
        -q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 - 861*q^7 - 1383*q^8 - 2218*q^9 - 3472*q^10 - 5451*q^11 - 8447*q^12 - 13020*q^13 - 19923*q^14 - 30403*q^15 - 46003*q^16 + O(q^17)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> X, Y = E.modular_parametrization().power_series()
        >>> X
        q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18)
        >>> Y
        -q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 - 861*q^7 - 1383*q^8 - 2218*q^9 - 3472*q^10 - 5451*q^11 - 8447*q^12 - 13020*q^13 - 19923*q^14 - 30403*q^15 - 46003*q^16 + O(q^17)

    The following should give 0, but only approximately:

    Sage

        sage: q = X.parent().gen()
        sage: E.defining_polynomial()(X,Y,1) + O(q^11) == 0
        True

    [Python]

        >>> from sage.all import *
        >>> q = X.parent().gen()
        >>> E.defining_polynomial()(X,Y,Integer(1)) + O(q**Integer(11)) == Integer(0)
        True

  modular_symbol(sign=1, normalize=None, implementation='eclib', nap=0)

    Return the modular symbol map associated to this elliptic curve with given sign.

    INPUT:

    - `sign` – +1 (default) or -1

    - `normalize` – (default: `None`) either `'L_ratio'`, `'period'`, or `'none'`; ignored unless `implementation` is `'sage'`. For `'L_ratio'`, the modular symbol tries to normalize correctly as explained below by comparing it to `L_ratio` for the curve and some small twists. The normalization `'period'` uses the `integral_period_map` for modular symbols which is known to be equal to the desired normalization, up to the sign and a possible power of 2. With normalization `'none'`, the modular symbol is almost certainly not correctly normalized, i.e. all values will be a fixed scalar multiple of what they should be.

    - `implementation` – either `'eclib'` (default), `'sage'` or `'num'`. Here, `'eclib'` uses Cremona’s `C++` implementation in the `eclib` library, `'sage'` uses an implementation within Sage which is often quite a bit slower, and `'num'` uses Wuthrich’s implementation of numerical modular symbols.

    - `nap` – integer (default: 0); ignored unless implementation is `'eclib'`. The number of ap of E to use in determining the normalisation of the modular symbols. If 0 (the default), then the value of `100*E.conductor().isqrt()` is used. Using too small a value can lead to incorrect normalisation.

    DEFINITION:

    The modular symbol map sends any rational number \(r\) to the rational number whichis the ratio of the real or imaginary part (depending on the sign) of the integral of \(2 \pi i f(z) dz\) from \(\infty\) to \(r\), where \(f\) is the newform attached to \(E\), to the real or imaginary period of \(E\).

    More precisely: If the sign is +1, then the value returned is the quotient of the real part of this integral by the least positive period \(\Omega_E^{+}\) of \(E\). In particular for \(r=0\), the value is equal to \(L(E,1)/\Omega_E^{+}\) (unlike in `L_ratio` of `lseries()`, where the value is also divided by the number of connected components of \(E(\RR)\)). In particular the modular symbol depends on \(E\) and not only the isogeny class of \(E\). For sign \(-1\), it is the quotient of the imaginary part of the integral divided by the purely imaginary period of \(E\) with smallest positive imaginary part. Note however there is an issue about these normalizations, hence the optional argument `normalize` explained below

    ALGORITHM:

    For the implementations `'sage'` and `'eclib'`, the used algorithm starts by finding the space of modular symbols within the full space of all modular symbols of that level. This initial step will take a very long time if the conductor is large (e.g. minutes for five digit conductors). Once the space is determined, each evaluation is very fast (logarithmic in the denominator of \(r\)).

    The implementation `'num'` uses a different algorithm. It uses numerical integration along paths in the upper half plane. The bounds are rigorously proved so that the outcome is known to be correct. The initial step costs no time, instead each evaluation will take more time than in the above. More information in the documentation of the class `ModularSymbolNumerical`.

    See also

    `modular_symbol_numerical()`

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: M = E.modular_symbol(); M
        Modular symbol with sign 1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
        sage: M(1/2)
        0
        sage: M(1/5)
        1

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> M = E.modular_symbol(); M
        Modular symbol with sign 1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
        >>> M(Integer(1)/Integer(2))
        0
        >>> M(Integer(1)/Integer(5))
        1

    Sage

        sage: E = EllipticCurve('121b1')
        sage: M = E.modular_symbol(implementation='sage')
        Warning : Could not normalize the modular symbols, maybe all further results
        will be multiplied by -1 and a power of 2
        sage: M(1/7)
        -1/2

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('121b1')
        >>> M = E.modular_symbol(implementation='sage')
        Warning : Could not normalize the modular symbols, maybe all further results
        will be multiplied by -1 and a power of 2
        >>> M(Integer(1)/Integer(7))
        -1/2

    With the numerical version, rather high conductors can be computed:

    Sage

        sage: E = EllipticCurve([999,997])
        sage: E.conductor()
        16059400956
        sage: m = E.modular_symbol(implementation='num')
        sage: m(0) # long time
        16

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(999),Integer(997)])
        >>> E.conductor()
        16059400956
        >>> m = E.modular_symbol(implementation='num')
        >>> m(Integer(0)) # long time
        16

    Different curves in an isogeny class have modular symbols which differ by a nonzero rational factor:

    Sage

        sage: E1 = EllipticCurve('11a1')
        sage: M1 = E1.modular_symbol()
        sage: M1(0)
        1/5
        sage: E2 = EllipticCurve('11a2')
        sage: M2 = E2.modular_symbol()
        sage: M2(0)
        1
        sage: E3 = EllipticCurve('11a3')
        sage: M3 = E3.modular_symbol()
        sage: M3(0)
        1/25
        sage: all(5*M1(r)==M2(r)==25*M3(r) for r in QQ.range_by_height(10))
        True

    [Python]

        >>> from sage.all import *
        >>> E1 = EllipticCurve('11a1')
        >>> M1 = E1.modular_symbol()
        >>> M1(Integer(0))
        1/5
        >>> E2 = EllipticCurve('11a2')
        >>> M2 = E2.modular_symbol()
        >>> M2(Integer(0))
        1
        >>> E3 = EllipticCurve('11a3')
        >>> M3 = E3.modular_symbol()
        >>> M3(Integer(0))
        1/25
        >>> all(Integer(5)*M1(r)==M2(r)==Integer(25)*M3(r) for r in QQ.range_by_height(Integer(10)))
        True

    With the default implementation using `eclib`, the symbols are correctly normalized automatically. With the `Sage` implementation we can choose to normalize using the L-ratio, unless that is 0 (for curves of positive rank) or using periods. Here is an example where the symbol is already normalized:

    Sage

        sage: E = EllipticCurve('11a2')
        sage: E.modular_symbol(implementation = 'eclib')(0)
        1
        sage: E.modular_symbol(implementation = 'sage', normalize='L_ratio')(0)
        1
        sage: E.modular_symbol(implementation = 'sage', normalize='none')(0)
        1
        sage: E.modular_symbol(implementation = 'sage', normalize='period')(0)
        1

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a2')
        >>> E.modular_symbol(implementation = 'eclib')(Integer(0))
        1
        >>> E.modular_symbol(implementation = 'sage', normalize='L_ratio')(Integer(0))
        1
        >>> E.modular_symbol(implementation = 'sage', normalize='none')(Integer(0))
        1
        >>> E.modular_symbol(implementation = 'sage', normalize='period')(Integer(0))
        1

    Here is an example where both normalization methods work, while the non-normalized symbol is incorrect:

    Sage

        sage: E = EllipticCurve('11a3')
        sage: E.modular_symbol(implementation = 'eclib')(0)
        1/25
        sage: E.modular_symbol(implementation = 'sage', normalize='none')(0)
        1
        sage: E.modular_symbol(implementation = 'sage', normalize='L_ratio')(0)
        1/25
        sage: E.modular_symbol(implementation = 'sage', normalize='period')(0)
        1/25

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('11a3')
        >>> E.modular_symbol(implementation = 'eclib')(Integer(0))
        1/25
        >>> E.modular_symbol(implementation = 'sage', normalize='none')(Integer(0))
        1
        >>> E.modular_symbol(implementation = 'sage', normalize='L_ratio')(Integer(0))
        1/25
        >>> E.modular_symbol(implementation = 'sage', normalize='period')(Integer(0))
        1/25

    Since Issue #10256, the interface for negative modular symbols in eclib is available:

    Sage

        sage: E = EllipticCurve('11a1')
        sage: Mplus = E.modular_symbol(+1); Mplus
        Modular symbol with sign 1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        sage: [Mplus(1/i) for i in [1..11]]
        [1/5, -4/5, -3/10, 7/10, 6/5, 6/5, 7/10, -3/10, -4/5, 1/5, 0]
        sage: Mminus = E.modular_symbol(-1); Mminus
        Modular symbol with sign -1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        sage: [Mminus(1/i) for i in [1..11]]
        [0, 0, 1/2, 1/2, 0, 0, -1/2, -1/2, 0, 0, 0]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a1')
        >>> Mplus = E.modular_symbol(+Integer(1)); Mplus
        Modular symbol with sign 1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        >>> [Mplus(Integer(1)/i) for i in (ellipsis_range(Integer(1),Ellipsis,Integer(11)))]
        [1/5, -4/5, -3/10, 7/10, 6/5, 6/5, 7/10, -3/10, -4/5, 1/5, 0]
        >>> Mminus = E.modular_symbol(-Integer(1)); Mminus
        Modular symbol with sign -1 over Rational Field attached to
         Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        >>> [Mminus(Integer(1)/i) for i in (ellipsis_range(Integer(1),Ellipsis,Integer(11)))]
        [0, 0, 1/2, 1/2, 0, 0, -1/2, -1/2, 0, 0, 0]

    With older version of eclib, in the default ‘eclib’ implementation, if `nap` is too small, the normalization may be computed incorrectly (see Issue #31317). This was fixed in eclib version v20210310, since now eclib increase `nap` automatically. The following used to give incorrect results. See Issue #31443:

    Sage

        sage: E = EllipticCurve('1590g1')
        sage: m = E.modular_symbol(nap=300)     # long time
        sage: [m(a/5) for a in [1..4]]          # long time
        [13/2, -13/2, -13/2, 13/2]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('1590g1')
        >>> m = E.modular_symbol(nap=Integer(300))     # long time
        >>> [m(a/Integer(5)) for a in (ellipsis_range(Integer(1),Ellipsis,Integer(4)))]          # long time
        [13/2, -13/2, -13/2, 13/2]

    These values are correct, as verified by the numerical implementation:

    Sage

        sage: m = E.modular_symbol(implementation='num')
        sage: [m(a/5) for a in [1..4]]
        [13/2, -13/2, -13/2, 13/2]

    Python

        >>> from sage.all import *
        >>> m = E.modular_symbol(implementation='num')
        >>> [m(a/Integer(5)) for a in (ellipsis_range(Integer(1),Ellipsis,Integer(4)))]
        [13/2, -13/2, -13/2, 13/2]

  modular_symbol_numerical(sign=1, prec=20)

    Return the modular symbol as a numerical function.

    Just as in `modular_symbol()` this returns a function that maps any rational \(r\) to a real number that should be equal to the rational number with an error smaller than the given binary precision. In practice the precision is often much higher. See the examples below. The normalisation is the same.

    INPUT:

    - `sign` – either +1 (default) or -1

    - `prec` – integer (default: 20)

    OUTPUT: a real number

    ALGORITHM:

    This method does not compute spaces of modular symbols, so it is suitable for curves of larger conductor than can be handled by `modular_symbol()`. It is essentially the same implementation as `modular_symbol` with implementation set to ‘num’. However the precision is not automatically chosen to be certain that the output is equal to the rational number it approximates.

    For large conductors one should set the `prec` very small.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('19a1')
        sage: f = E.modular_symbol_numerical(1)
        sage: g = E.modular_symbol(1)
        sage: f(0), g(0)  # abs tol 1e-11
        (0.333333333333333, 1/3)

        sage: E = EllipticCurve('5077a1')
        sage: f = E.modular_symbol_numerical(-1, prec=2)
        sage: f(0)        # abs tol 1e-11
        0.000000000000000
        sage: f(1/7)      # abs tol 1e-11
        0.999844176260303

        sage: E = EllipticCurve([123,456])
        sage: E.conductor()
        104461920
        sage: f = E.modular_symbol_numerical(prec=2)
        sage: f(0)        # abs tol 1e-11
        2.00001004772210

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('19a1')
        >>> f = E.modular_symbol_numerical(Integer(1))
        >>> g = E.modular_symbol(Integer(1))
        >>> f(Integer(0)), g(Integer(0))  # abs tol 1e-11
        (0.333333333333333, 1/3)

        >>> E = EllipticCurve('5077a1')
        >>> f = E.modular_symbol_numerical(-Integer(1), prec=Integer(2))
        >>> f(Integer(0))        # abs tol 1e-11
        0.000000000000000
        >>> f(Integer(1)/Integer(7))      # abs tol 1e-11
        0.999844176260303

        >>> E = EllipticCurve([Integer(123),Integer(456)])
        >>> E.conductor()
        104461920
        >>> f = E.modular_symbol_numerical(prec=Integer(2))
        >>> f(Integer(0))        # abs tol 1e-11
        2.00001004772210

  modular_symbol_space(sign=1, base_ring=Rational Field, bound=None)

    Return the space of cuspidal modular symbols associated to this elliptic curve, with given sign and base ring.

    INPUT:

    - `sign` – 0, -1, or 1

    - `base_ring` – a ring

    EXAMPLES:

    Sage

        sage: f = EllipticCurve('37b')
        sage: f.modular_symbol_space()
        Modular Symbols subspace of dimension 1 of Modular Symbols space
         of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field
        sage: f.modular_symbol_space(-1)
        Modular Symbols subspace of dimension 1 of Modular Symbols space
         of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field
        sage: f.modular_symbol_space(0, bound=3)
        Modular Symbols subspace of dimension 2 of Modular Symbols space
         of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field

    Python

        >>> from sage.all import *
        >>> f = EllipticCurve('37b')
        >>> f.modular_symbol_space()
        Modular Symbols subspace of dimension 1 of Modular Symbols space
         of dimension 3 for Gamma_0(37) of weight 2 with sign 1 over Rational Field
        >>> f.modular_symbol_space(-Integer(1))
        Modular Symbols subspace of dimension 1 of Modular Symbols space
         of dimension 2 for Gamma_0(37) of weight 2 with sign -1 over Rational Field
        >>> f.modular_symbol_space(Integer(0), bound=Integer(3))
        Modular Symbols subspace of dimension 2 of Modular Symbols space
         of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field

    Note

    If you just want the \(q\)-expansion, use `q_expansion()`.

  mwrank(options='')

    Run Cremona’s mwrank program on this elliptic curve and return the result as a string.

    INPUT:

    - `options` – string; run-time options passed when starting mwrank. The format is as follows (see below for examples of usage):

      - `-v n` (verbosity level) sets verbosity to n (default=1)

      - `-o` (PARI/GP style output flag) turns ON extra PARI/GP short output (default is OFF)

      - `-p n` (precision) sets precision to \(n\) decimals (default=15)

      - `-b n` (quartic bound) bound on quartic point search (default=10)

      - `-x n` (n_aux) number of aux primes used for sieving (default=6)

      - `-l` (generator list flag) turns ON listing of points (default ON unless v=0)

      - `-s` (selmer_only flag) if set, computes Selmer rank only (default: not set)

      - `-d` (skip_2nd_descent flag) if set, skips the second descent for curves with 2-torsion (default: not set)

      - `-S n` (sat_bd) upper bound on saturation primes (default=100, -1 for automatic)

    OUTPUT: string; output of mwrank on this curve

    Note

    The output is a raw string and completely illegible using automatic display, so it is recommended to use print for legible output.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.mwrank() # random
        ...
        sage: print(E.mwrank())
        Curve [0,0,1,-1,0] :        Basic pair: I=48, J=-432
        disc=255744
        ...
        Generator 1 is [0:-1:1]; height 0.05111...

        Regulator = 0.05111...

        The rank and full Mordell-Weil basis have been determined unconditionally.
        ...

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.mwrank() # random
        ...
        >>> print(E.mwrank())
        Curve [0,0,1,-1,0] :        Basic pair: I=48, J=-432
        disc=255744
        ...
        Generator 1 is [0:-1:1]; height 0.05111...

        Regulator = 0.05111...

        The rank and full Mordell-Weil basis have been determined unconditionally.
        ...

    Options to mwrank can be passed:

    Sage

        sage: E = EllipticCurve([0,0,0,877,0])

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(877),Integer(0)])

    Run mwrank with `'verbose'` flag set to 0 but list generators if found:

    Sage

        sage: print(E.mwrank('-v0 -l'))
        Curve [0,0,0,877,0] :   0 <= rank <= 1
        Regulator = 1

    Python

        >>> from sage.all import *
        >>> print(E.mwrank('-v0 -l'))
        Curve [0,0,0,877,0] :   0 <= rank <= 1
        Regulator = 1

    Run mwrank again, this time with a higher bound for point searching on homogeneous spaces:

    Sage

        sage: print(E.mwrank('-v0 -l -b11'))
        Curve [0,0,0,877,0] :   Rank = 1
        Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.98037...
        Regulator = 95.98037...

    [Python]

        >>> from sage.all import *
        >>> print(E.mwrank('-v0 -l -b11'))
        Curve [0,0,0,877,0] :   Rank = 1
        Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.98037...
        Regulator = 95.98037...

  mwrank_curve(verbose=False)

    Construct an mwrank_EllipticCurve from this elliptic curve.

    The resulting mwrank_EllipticCurve has available methods from John Cremona’s eclib library.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a1')
        sage: EE = E.mwrank_curve()
        sage: EE
        y^2 + y = x^3 - x^2 - 10 x - 20
        sage: type(EE)
        <class 'sage.libs.eclib.interface.mwrank_EllipticCurve'>
        sage: EE.isogeny_class()
        ([[0, -1, 1, -10, -20], [0, -1, 1, -7820, -263580], [0, -1, 1, 0, 0]],
         [[0, 5, 5], [5, 0, 0], [5, 0, 0]])

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a1')
        >>> EE = E.mwrank_curve()
        >>> EE
        y^2 + y = x^3 - x^2 - 10 x - 20
        >>> type(EE)
        <class 'sage.libs.eclib.interface.mwrank_EllipticCurve'>
        >>> EE.isogeny_class()
        ([[0, -1, 1, -10, -20], [0, -1, 1, -7820, -263580], [0, -1, 1, 0, 0]],
         [[0, 5, 5], [5, 0, 0], [5, 0, 0]])

  newform()

    Same as `self.modular_form()`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.newform()
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
        sage: E.newform() == E.modular_form()
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.newform()
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
        >>> E.newform() == E.modular_form()
        True

  ngens(proof=None)

    Return the number of generators of this elliptic curve.

    Note

    See `gens()` for further documentation. The function `ngens()` calls `gens()` if not already done, but only with default parameters. Better results may be obtained by calling `mwrank()` with carefully chosen parameters.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.ngens()
        1

        sage: E = EllipticCurve([0,0,0,877,0])
        sage: E.ngens()
        1

        sage: print(E.mwrank('-v0 -b12 -l'))
        Curve [0,0,0,877,0] :   Rank = 1
        Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.98037...
        Regulator = 95.980...

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.ngens()
        1

        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(877),Integer(0)])
        >>> E.ngens()
        1

        >>> print(E.mwrank('-v0 -b12 -l'))
        Curve [0,0,0,877,0] :   Rank = 1
        Generator 1 is [29604565304828237474403861024284371796799791624792913256602210:-256256267988926809388776834045513089648669153204356603464786949:490078023219787588959802933995928925096061616470779979261000]; height 95.98037...
        Regulator = 95.980...

  optimal_curve()

    Given an elliptic curve that is in the installed Cremona database, return the optimal curve isogenous to it.

    EXAMPLES:

    The following curve is not optimal:

    Sage

        sage: E = EllipticCurve('11a2'); E
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field
        sage: E.optimal_curve()
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        sage: E.optimal_curve().cremona_label()
        '11a1'

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a2'); E
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 7820*x - 263580 over Rational Field
        >>> E.optimal_curve()
        Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
        >>> E.optimal_curve().cremona_label()
        '11a1'

    Note that 990h is the special case where the optimal curve isn’t the first in the Cremona labeling:

    Sage

        sage: E = EllipticCurve('990h4'); E
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 6112*x - 41533 over Rational Field
        sage: F = E.optimal_curve(); F
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1568*x - 4669 over Rational Field
        sage: F.cremona_label()
        '990h3'
        sage: EllipticCurve('990a1').optimal_curve().cremona_label()   # a isn't h.
        '990a1'

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('990h4'); E
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 6112*x - 41533 over Rational Field
        >>> F = E.optimal_curve(); F
        Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 1568*x - 4669 over Rational Field
        >>> F.cremona_label()
        '990h3'
        >>> EllipticCurve('990a1').optimal_curve().cremona_label()   # a isn't h.
        '990a1'

    If the input curve is optimal, this function returns that curve (not just a copy of it or a curve isomorphic to it!):

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.optimal_curve() is E
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.optimal_curve() is E
        True

    Also, if this curve is optimal but not given by a minimal model, this curve will still be returned, so this function need not return a minimal model in general.

    Sage

        sage: F = E.short_weierstrass_model(); F
        Elliptic Curve defined by y^2  = x^3 - 16*x + 16 over Rational Field
        sage: F.optimal_curve()
        Elliptic Curve defined by y^2  = x^3 - 16*x + 16 over Rational Field

    [Python]

        >>> from sage.all import *
        >>> F = E.short_weierstrass_model(); F
        Elliptic Curve defined by y^2  = x^3 - 16*x + 16 over Rational Field
        >>> F.optimal_curve()
        Elliptic Curve defined by y^2  = x^3 - 16*x + 16 over Rational Field

  ordinary_primes(B)

    Return a list of all ordinary primes for this elliptic curve up to and possibly including B.

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('11a')
        sage: e.aplist(20)
        [-2, -1, 1, -2, 1, 4, -2, 0]
        sage: e.ordinary_primes(97)
        [3, 5, 7, 11, 13, 17, 23, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
        sage: e = EllipticCurve('49a')
        sage: e.aplist(20)
        [1, 0, 0, 0, 4, 0, 0, 0]
        sage: e.supersingular_primes(97)
        [3, 5, 13, 17, 19, 31, 41, 47, 59, 61, 73, 83, 89, 97]
        sage: e.ordinary_primes(97)
        [2, 11, 23, 29, 37, 43, 53, 67, 71, 79]
        sage: e.ordinary_primes(3)
        [2]
        sage: e.ordinary_primes(2)
        [2]
        sage: e.ordinary_primes(1)
        []

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> e.aplist(Integer(20))
        [-2, -1, 1, -2, 1, 4, -2, 0]
        >>> e.ordinary_primes(Integer(97))
        [3, 5, 7, 11, 13, 17, 23, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
        >>> e = EllipticCurve('49a')
        >>> e.aplist(Integer(20))
        [1, 0, 0, 0, 4, 0, 0, 0]
        >>> e.supersingular_primes(Integer(97))
        [3, 5, 13, 17, 19, 31, 41, 47, 59, 61, 73, 83, 89, 97]
        >>> e.ordinary_primes(Integer(97))
        [2, 11, 23, 29, 37, 43, 53, 67, 71, 79]
        >>> e.ordinary_primes(Integer(3))
        [2]
        >>> e.ordinary_primes(Integer(2))
        [2]
        >>> e.ordinary_primes(Integer(1))
        []

  padic_E2(p, prec=20, check=False, check_hypotheses=True, algorithm='auto')

    Return the value of the \(p\)-adic modular form \(E2\) for \((E, \omega)\) where \(\omega\) is the usual invariant differential \(dx/(2y + a_1 x + a_3)\).

    INPUT:

    - `p` – prime (= 5) for which \(E\) is good and ordinary

    - `prec` – (relative) \(p\)-adic precision (= 1) for result

    - `check` – boolean; whether to perform a consistency check. This will slow down the computation by a constant factor 2. (The consistency check is to compute the whole matrix of frobenius on Monsky-Washnitzer cohomology, and verify that its trace is correct to the specified precision. Otherwise, the trace is used to compute one column from the other one (possibly after a change of basis).)

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic sigma function makes sense

    - `algorithm` – one of `'standard'`, `'sqrtp'`, or `'auto'`. This selects which version of Kedlaya’s algorithm is used. The `'standard'` one is the one described in Kedlaya’s paper. The `'sqrtp'` one has better performance for large \(p\), but only works when \(p > 6N\) (\(N=\) `prec`). The `'auto'` option selects `'sqrtp'` whenever possible.

      Note that if the `'sqrtp'` algorithm is used, a consistency check will automatically be applied, regardless of the setting of the `check` flag.

    OUTPUT: \(p\)-adic number to precision `prec`

    Note

    If the discriminant of the curve has nonzero valuation at p, then the result will not be returned mod \(p^\text{prec}\), but it still will have `prec` digits of precision.

    Todo

    Once we have a better implementation of the “standard” algorithm, the algorithm selection strategy for “auto” needs to be revisited.

    AUTHORS:

    - David Harvey (2006-09-01): partly based on code written by Robert Bradshaw at the MSRI 2006 modular forms workshop

    ACKNOWLEDGMENT: - discussion with Eyal Goren that led to the trace trick.

    EXAMPLES: Here is the example discussed in the paper “Computation of p-adic Heights and Log Convergence” (Mazur, Stein, Tate) [MST2006]:

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_E2(5)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + O(5^20)

    Python

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5))
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + O(5^20)

    Let’s try to higher precision (this is the same answer the MAGMA implementation gives):

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 100)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + 2*5^30 + 5^31 + 4*5^33 + 3*5^34 + 4*5^35 + 5^36 + 4*5^37 + 4*5^38 + 3*5^39 + 4*5^41 + 2*5^42 + 3*5^43 + 2*5^44 + 2*5^48 + 3*5^49 + 4*5^50 + 2*5^51 + 5^52 + 4*5^53 + 4*5^54 + 3*5^55 + 2*5^56 + 3*5^57 + 4*5^58 + 4*5^59 + 5^60 + 3*5^61 + 5^62 + 4*5^63 + 5^65 + 3*5^66 + 2*5^67 + 5^69 + 2*5^70 + 3*5^71 + 3*5^72 + 5^74 + 5^75 + 5^76 + 3*5^77 + 4*5^78 + 4*5^79 + 2*5^80 + 3*5^81 + 5^82 + 5^83 + 4*5^84 + 3*5^85 + 2*5^86 + 3*5^87 + 5^88 + 2*5^89 + 4*5^90 + 4*5^92 + 3*5^93 + 4*5^94 + 3*5^95 + 2*5^96 + 4*5^97 + 4*5^98 + 2*5^99 + O(5^100)

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(100))
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + 2*5^30 + 5^31 + 4*5^33 + 3*5^34 + 4*5^35 + 5^36 + 4*5^37 + 4*5^38 + 3*5^39 + 4*5^41 + 2*5^42 + 3*5^43 + 2*5^44 + 2*5^48 + 3*5^49 + 4*5^50 + 2*5^51 + 5^52 + 4*5^53 + 4*5^54 + 3*5^55 + 2*5^56 + 3*5^57 + 4*5^58 + 4*5^59 + 5^60 + 3*5^61 + 5^62 + 4*5^63 + 5^65 + 3*5^66 + 2*5^67 + 5^69 + 2*5^70 + 3*5^71 + 3*5^72 + 5^74 + 5^75 + 5^76 + 3*5^77 + 4*5^78 + 4*5^79 + 2*5^80 + 3*5^81 + 5^82 + 5^83 + 4*5^84 + 3*5^85 + 2*5^86 + 3*5^87 + 5^88 + 2*5^89 + 4*5^90 + 4*5^92 + 3*5^93 + 4*5^94 + 3*5^95 + 2*5^96 + 4*5^97 + 4*5^98 + 2*5^99 + O(5^100)

    Check it works at low precision too:

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1)
        2 + O(5)
        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 2)
        2 + 4*5 + O(5^2)
        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 3)
        2 + 4*5 + O(5^3)

    Python

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(1))
        2 + O(5)
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(2))
        2 + 4*5 + O(5^2)
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(3))
        2 + 4*5 + O(5^3)

    TODO: With the old(-er), i.e., = sage-2.4 \(p\)-adics we got \(5 + O(5^2)\) as output, i.e., relative precision 1, but with the newer \(p\)-adics we get relative precision 0 and absolute precision 1.

    Sage

        sage: EllipticCurve([1, 1, 1, 1, 1]).padic_E2(5, 1)
        O(5)

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).padic_E2(Integer(5), Integer(1))
        O(5)

    Check it works for different models of the same curve (37a), even when the discriminant changes by a power of p (note that E2 depends on the differential too, which is why it gets scaled in some of the examples below):

    Sage

        sage: X1 = EllipticCurve([-1, 1/4])
        sage: X1.j_invariant(), X1.discriminant()
         (110592/37, 37)
        sage: X1.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> X1 = EllipticCurve([-Integer(1), Integer(1)/Integer(4)])
        >>> X1.j_invariant(), X1.discriminant()
         (110592/37, 37)
        >>> X1.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Sage

        sage: X2 = EllipticCurve([0, 0, 1, -1, 0])
        sage: X2.j_invariant(), X2.discriminant()
         (110592/37, 37)
        sage: X2.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    [Python]

        >>> from sage.all import *
        >>> X2 = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)])
        >>> X2.j_invariant(), X2.discriminant()
         (110592/37, 37)
        >>> X2.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Sage

        sage: X3 = EllipticCurve([-1*(2**4), 1/4*(2**6)])
        sage: X3.j_invariant(), X3.discriminant() / 2**12
         (110592/37, 37)
        sage: 2**(-2) * X3.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> X3 = EllipticCurve([-Integer(1)*(Integer(2)**Integer(4)), Integer(1)/Integer(4)*(Integer(2)**Integer(6))])
        >>> X3.j_invariant(), X3.discriminant() / Integer(2)**Integer(12)
         (110592/37, 37)
        >>> Integer(2)**(-Integer(2)) * X3.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Sage

        sage: X4 = EllipticCurve([-1*(7**4), 1/4*(7**6)])
        sage: X4.j_invariant(), X4.discriminant() / 7**12
         (110592/37, 37)
        sage: 7**(-2) * X4.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    [Python]

        >>> from sage.all import *
        >>> X4 = EllipticCurve([-Integer(1)*(Integer(7)**Integer(4)), Integer(1)/Integer(4)*(Integer(7)**Integer(6))])
        >>> X4.j_invariant(), X4.discriminant() / Integer(7)**Integer(12)
         (110592/37, 37)
        >>> Integer(7)**(-Integer(2)) * X4.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Sage

        sage: X5 = EllipticCurve([-1*(5**4), 1/4*(5**6)])
        sage: X5.j_invariant(), X5.discriminant() / 5**12
         (110592/37, 37)
        sage: 5**(-2) * X5.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> X5 = EllipticCurve([-Integer(1)*(Integer(5)**Integer(4)), Integer(1)/Integer(4)*(Integer(5)**Integer(6))])
        >>> X5.j_invariant(), X5.discriminant() / Integer(5)**Integer(12)
         (110592/37, 37)
        >>> Integer(5)**(-Integer(2)) * X5.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Sage

        sage: X6 = EllipticCurve([-1/(5**4), 1/4/(5**6)])
        sage: X6.j_invariant(), X6.discriminant() * 5**12
         (110592/37, 37)
        sage: 5**2 * X6.padic_E2(5, 10)
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    [Python]

        >>> from sage.all import *
        >>> X6 = EllipticCurve([-Integer(1)/(Integer(5)**Integer(4)), Integer(1)/Integer(4)/(Integer(5)**Integer(6))])
        >>> X6.j_invariant(), X6.discriminant() * Integer(5)**Integer(12)
         (110592/37, 37)
        >>> Integer(5)**Integer(2) * X6.padic_E2(Integer(5), Integer(10))
         2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + O(5^10)

    Test check=True vs check=False:

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1, check=False)
        2 + O(5)
        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 1, check=True)
        2 + O(5)
        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 30, check=False)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)
        sage: EllipticCurve([-1, 1/4]).padic_E2(5, 30, check=True)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)

    Python

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(1), check=False)
        2 + O(5)
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(1), check=True)
        2 + O(5)
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(30), check=False)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(5), Integer(30), check=True)
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + 4*5^20 + 5^21 + 4*5^22 + 2*5^23 + 3*5^24 + 3*5^26 + 2*5^27 + 3*5^28 + O(5^30)

    Here’s one using the \(p^{1/2}\) algorithm:

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_E2(3001, 3, algorithm='sqrtp')
        1907 + 2819*3001 + 1124*3001^2 + O(3001^3)

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_E2(Integer(3001), Integer(3), algorithm='sqrtp')
        1907 + 2819*3001 + 1124*3001^2 + O(3001^3)

  padic_height(p, prec=20, sigma=None, check_hypotheses=True)

    Compute the cyclotomic \(p\)-adic height.

    The equation of the curve must be integral and minimal at \(p\).

    INPUT:

    - `p` – prime >= 5 for which the curve has semi-stable reduction

    - `prec` – integer >= 1 (default: 20); desired precision of result

    - `sigma` – precomputed value of sigma; if not supplied, this function will call `padic_sigma` to compute it

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic height makes sense

    OUTPUT:

    A function that accepts two parameters:

    - a \(\QQ\)-rational point on the curve whose height should be computed

    - optional boolean flag ‘check’: if `False`, it skips some input checking, and returns the \(p\)-adic height of that point to the desired precision.

    - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way as to make the \(p\)-adic Birch Swinnerton-Dyer conjecture hold as stated in [MTT1986].

    AUTHORS:

    - Jennifer Balakrishnan: original code developed at the 2006 MSRI graduate workshop on modular forms

    - David Harvey (2006-09-13): integrated into Sage, optimised to speed up repeated evaluations of the returned height function, addressed some thorny precision questions

    - David Harvey (2006-09-30): rewrote to use division polynomials for computing denominator of \(nP\).

    - David Harvey (2007-02): cleaned up according to algorithms in “Efficient Computation of p-adic Heights”

    - Chris Wuthrich (2007-05): added supersingular and multiplicative heights

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("37a")
        sage: P = E.gens()[0]
        sage: h = E.padic_height(5, 10)
        sage: h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("37a")
        >>> P = E.gens()[Integer(0)]
        >>> h = E.padic_height(Integer(5), Integer(10))
        >>> h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    An anomalous case:

    Sage

        sage: h = E.padic_height(53, 10)
        sage: h(P)
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)

    [Python]

        >>> from sage.all import *
        >>> h = E.padic_height(Integer(53), Integer(10))
        >>> h(P)
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)

    Boundary case:

    Sage

        sage: E.padic_height(5, 3)(P)
        5 + 5^2 + O(5^3)

    Python

        >>> from sage.all import *
        >>> E.padic_height(Integer(5), Integer(3))(P)
        5 + 5^2 + O(5^3)

    A case that works the division polynomial code a little harder:

    Sage

        sage: E.padic_height(5, 10)(5*P)
        5^3 + 5^4 + 5^5 + 3*5^8 + 4*5^9 + O(5^10)

    [Python]

        >>> from sage.all import *
        >>> E.padic_height(Integer(5), Integer(10))(Integer(5)*P)
        5^3 + 5^4 + 5^5 + 3*5^8 + 4*5^9 + O(5^10)

    Check that answers agree over a range of precisions:

    Sage

        sage: max_prec = 30    # make sure we get past p^2    # long time
        sage: full = E.padic_height(5, max_prec)(P)           # long time
        sage: for prec in range(1, max_prec):                 # long time
        ....:     assert E.padic_height(5, prec)(P) == full

    Python

        >>> from sage.all import *
        >>> max_prec = Integer(30)    # make sure we get past p^2    # long time
        >>> full = E.padic_height(Integer(5), max_prec)(P)           # long time
        >>> for prec in range(Integer(1), max_prec):                 # long time
        ...     assert E.padic_height(Integer(5), prec)(P) == full

    A supersingular prime for a curve:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.is_supersingular(3)
        True
        sage: h = E.padic_height(3, 5)
        sage: h(E.gens()[0])
        (3 + 3^3 + O(3^6), 2*3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + O(3^7))
        sage: E.padic_regulator(5)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)
        sage: E.padic_regulator(3, 5)
        (3 + 2*3^2 + 3^3 + O(3^4), 3^2 + 2*3^3 + 3^4 + O(3^5))

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.is_supersingular(Integer(3))
        True
        >>> h = E.padic_height(Integer(3), Integer(5))
        >>> h(E.gens()[Integer(0)])
        (3 + 3^3 + O(3^6), 2*3^2 + 3^3 + 3^4 + 3^5 + 2*3^6 + O(3^7))
        >>> E.padic_regulator(Integer(5))
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)
        >>> E.padic_regulator(Integer(3), Integer(5))
        (3 + 2*3^2 + 3^3 + O(3^4), 3^2 + 2*3^3 + 3^4 + O(3^5))

    A torsion point in both the good and supersingular cases:

    Sage

        sage: E = EllipticCurve('11a')
        sage: P = E.torsion_subgroup().gen(0).element(); P
        (5 : 5 : 1)
        sage: h = E.padic_height(19, 5)
        sage: h(P)
        0
        sage: h = E.padic_height(5, 5)
        sage: h(P)
        0

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> P = E.torsion_subgroup().gen(Integer(0)).element(); P
        (5 : 5 : 1)
        >>> h = E.padic_height(Integer(19), Integer(5))
        >>> h(P)
        0
        >>> h = E.padic_height(Integer(5), Integer(5))
        >>> h(P)
        0

    The result is not dependent on the model for the curve:

    Sage

        sage: E = EllipticCurve([0,0,0,0,2^12*17])
        sage: Em = E.minimal_model()
        sage: P = E.gens()[0]
        sage: Pm = Em.gens()[0]
        sage: h = E.padic_height(7)
        sage: hm = Em.padic_height(7)
        sage: h(P) == hm(Pm)
        True

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(2)**Integer(12)*Integer(17)])
        >>> Em = E.minimal_model()
        >>> P = E.gens()[Integer(0)]
        >>> Pm = Em.gens()[Integer(0)]
        >>> h = E.padic_height(Integer(7))
        >>> hm = Em.padic_height(Integer(7))
        >>> h(P) == hm(Pm)
        True

  padic_height_pairing_matrix(p, prec=20, height=None, check_hypotheses=True)

    Compute the cyclotomic \(p\)-adic height pairing matrix of this curve with respect to the basis `self.gens()` for the Mordell-Weil group for a given odd prime \(p\) of good ordinary reduction. The model needs to be integral and minimal at \(p\).

    INPUT:

    - `p` – prime >= 5

    - `prec` – answer will be returned modulo \(p^{\mathrm{prec}}\)

    - `height` – precomputed height function; if not supplied, this function will call `padic_height` to compute it

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic height makes sense

    OUTPUT: the \(p\)-adic cyclotomic height pairing matrix of this curve to the given precision

    AUTHORS:

    - David Harvey, Liang Xiao, Robert Bradshaw, Jennifer Balakrishnan: original implementation at the 2006 MSRI graduate workshop on modular forms

    - David Harvey (2006-09-13): cleaned up and integrated into Sage, removed some redundant height computations

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("37a")
        sage: E.padic_height_pairing_matrix(5, 10)
        [5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("37a")
        >>> E.padic_height_pairing_matrix(Integer(5), Integer(10))
        [5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)]

    A rank two example:

    Sage

        sage: e =EllipticCurve('389a')
        sage: e._set_gens([e(-1, 1), e(1,0)])  # avoid platform dependent gens
        sage: e.padic_height_pairing_matrix(5,10)
        [                      3*5 + 2*5^2 + 5^4 + 5^5 + 5^7 + 4*5^9 + O(5^10) 5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10)]
        [5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10)                         4*5 + 2*5^4 + 3*5^6 + 4*5^7 + 4*5^8 + O(5^10)]

    [Python]

        >>> from sage.all import *
        >>> e =EllipticCurve('389a')
        >>> e._set_gens([e(-Integer(1), Integer(1)), e(Integer(1),Integer(0))])  # avoid platform dependent gens
        >>> e.padic_height_pairing_matrix(Integer(5),Integer(10))
        [                      3*5 + 2*5^2 + 5^4 + 5^5 + 5^7 + 4*5^9 + O(5^10) 5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10)]
        [5 + 4*5^2 + 5^3 + 2*5^4 + 3*5^5 + 4*5^6 + 5^7 + 5^8 + 2*5^9 + O(5^10)                         4*5 + 2*5^4 + 3*5^6 + 4*5^7 + 4*5^8 + O(5^10)]

    An anomalous rank 3 example:

    Sage

        sage: e = EllipticCurve("5077a")
        sage: e._set_gens([e(-1,3), e(2,0), e(4,6)])
        sage: e.padic_height_pairing_matrix(5,4)
        [4 + 3*5 + 4*5^2 + 4*5^3 + O(5^4)       4 + 4*5^2 + 2*5^3 + O(5^4)       3*5 + 4*5^2 + 5^3 + O(5^4)]
        [      4 + 4*5^2 + 2*5^3 + O(5^4)   3 + 4*5 + 3*5^2 + 5^3 + O(5^4)                 2 + 4*5 + O(5^4)]
        [      3*5 + 4*5^2 + 5^3 + O(5^4)                 2 + 4*5 + O(5^4)     1 + 3*5 + 5^2 + 5^3 + O(5^4)]

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve("5077a")
        >>> e._set_gens([e(-Integer(1),Integer(3)), e(Integer(2),Integer(0)), e(Integer(4),Integer(6))])
        >>> e.padic_height_pairing_matrix(Integer(5),Integer(4))
        [4 + 3*5 + 4*5^2 + 4*5^3 + O(5^4)       4 + 4*5^2 + 2*5^3 + O(5^4)       3*5 + 4*5^2 + 5^3 + O(5^4)]
        [      4 + 4*5^2 + 2*5^3 + O(5^4)   3 + 4*5 + 3*5^2 + 5^3 + O(5^4)                 2 + 4*5 + O(5^4)]
        [      3*5 + 4*5^2 + 5^3 + O(5^4)                 2 + 4*5 + O(5^4)     1 + 3*5 + 5^2 + 5^3 + O(5^4)]

  padic_height_via_multiply(p, prec=20, E2=None, check_hypotheses=True)

    Compute the cyclotomic \(p\)-adic height.

    The equation of the curve must be minimal at \(p\).

    INPUT:

    - `p` – prime >= 5 for which the curve has good ordinary reduction

    - `prec` – integer >= 2 (default: 20); desired precision of result

    - `E2` – precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod \(p^{prec-2}\) (or slightly higher in the anomalous case; see the code for details).

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic height makes sense

    OUTPUT:

    A function that accepts two parameters:

    - a \(\QQ\)-rational point on the curve whose height should be computed

    - optional boolean flag ‘check’: if `False`, it skips some input checking, and returns the \(p\)-adic height of that point to the desired precision.

    - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way as to make the \(p\)-adic Birch Swinnerton-Dyer conjecture hold as stated in [MTT1986].

    AUTHORS:

    - David Harvey (2008-01): based on the padic_height() function, using the algorithm of [Har2009].

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("37a")
        sage: P = E.gens()[0]
        sage: h = E.padic_height_via_multiply(5, 10)
        sage: h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("37a")
        >>> P = E.gens()[Integer(0)]
        >>> h = E.padic_height_via_multiply(Integer(5), Integer(10))
        >>> h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    An anomalous case:

    Sage

        sage: h = E.padic_height_via_multiply(53, 10)
        sage: h(P)
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)

    [Python]

        >>> from sage.all import *
        >>> h = E.padic_height_via_multiply(Integer(53), Integer(10))
        >>> h(P)
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + 17*53^9 + O(53^10)

    Supply the value of E2 manually:

    Sage

        sage: E2 = E.padic_E2(5, 8)
        sage: E2
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + O(5^8)
        sage: h = E.padic_height_via_multiply(5, 10, E2=E2)
        sage: h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E2 = E.padic_E2(Integer(5), Integer(8))
        >>> E2
        2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + O(5^8)
        >>> h = E.padic_height_via_multiply(Integer(5), Integer(10), E2=E2)
        >>> h(P)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    Boundary case:

    Sage

        sage: E.padic_height_via_multiply(5, 3)(P)
        5 + 5^2 + O(5^3)

    [Python]

        >>> from sage.all import *
        >>> E.padic_height_via_multiply(Integer(5), Integer(3))(P)
        5 + 5^2 + O(5^3)

    Check that answers agree over a range of precisions:

    Sage

        sage: max_prec = 30    # make sure we get past p^2    # long time
        sage: full = E.padic_height(5, max_prec)(P)           # long time
        sage: for prec in range(2, max_prec):                 # long time
        ....:     assert E.padic_height_via_multiply(5, prec)(P) == full

    Python

        >>> from sage.all import *
        >>> max_prec = Integer(30)    # make sure we get past p^2    # long time
        >>> full = E.padic_height(Integer(5), max_prec)(P)           # long time
        >>> for prec in range(Integer(2), max_prec):                 # long time
        ...     assert E.padic_height_via_multiply(Integer(5), prec)(P) == full

  padic_lseries(p, normalize=None, implementation='eclib', precision=None)

    Return the \(p\)-adic \(L\)-series of `self` at \(p\), which is an object whose approx method computes approximation to the true \(p\)-adic \(L\)-series to any desired precision.

    INPUT:

    - `p` – prime

    - `normalize` – ‘L_ratio’ (default), ‘period’ or ‘none’; this is describes the way the modular symbols are normalized. See modular_symbol for more details.

    - `implementation` – ‘eclib’ (default), ‘sage’, ‘num’ or ‘pollackstevens’; Whether to use John Cremona’s eclib, the Sage implementation, numerical modular symbols or Pollack-Stevens’ implementation of overconvergent modular symbols.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: L = E.padic_lseries(5); L
        5-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
        sage: type(L)
        <class 'sage.schemes.elliptic_curves.padic_lseries.pAdicLseriesOrdinary'>

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> L = E.padic_lseries(Integer(5)); L
        5-adic L-series of Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
        >>> type(L)
        <class 'sage.schemes.elliptic_curves.padic_lseries.pAdicLseriesOrdinary'>

    We compute the \(3\)-adic \(L\)-series of two curves of rank \(0\) and in each case verify the interpolation property for their leading coefficient (i.e., value at 0):

    Sage

        sage: e = EllipticCurve('11a')
        sage: ms = e.modular_symbol()
        sage: [ms(1/11), ms(1/3), ms(0), ms(oo)]
        [0, -3/10, 1/5, 0]
        sage: ms(0)
        1/5
        sage: L = e.padic_lseries(3)
        sage: P = L.series(5)
        sage: P(0)
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
        sage: alpha = L.alpha(9); alpha
        2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + O(3^9)
        sage: R.<x> = QQ[]
        sage: f = x^2 - e.ap(3)*x + 3
        sage: f(alpha)
        O(3^9)
        sage: r = e.lseries().L_ratio(); r
        1/5
        sage: (1 - alpha^(-1))^2 * r
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + O(3^9)
        sage: P(0)
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> ms = e.modular_symbol()
        >>> [ms(Integer(1)/Integer(11)), ms(Integer(1)/Integer(3)), ms(Integer(0)), ms(oo)]
        [0, -3/10, 1/5, 0]
        >>> ms(Integer(0))
        1/5
        >>> L = e.padic_lseries(Integer(3))
        >>> P = L.series(Integer(5))
        >>> P(Integer(0))
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)
        >>> alpha = L.alpha(Integer(9)); alpha
        2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + O(3^9)
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> f = x**Integer(2) - e.ap(Integer(3))*x + Integer(3)
        >>> f(alpha)
        O(3^9)
        >>> r = e.lseries().L_ratio(); r
        1/5
        >>> (Integer(1) - alpha**(-Integer(1)))**Integer(2) * r
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + 3^7 + O(3^9)
        >>> P(Integer(0))
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7)

    Next consider the curve 37b:

    Sage

        sage: e = EllipticCurve('37b')
        sage: L = e.padic_lseries(3)
        sage: P = L.series(5)
        sage: alpha = L.alpha(9); alpha
        1 + 2*3 + 3^2 + 2*3^5 + 2*3^7 + 3^8 + O(3^9)
        sage: r = e.lseries().L_ratio(); r
        1/3
        sage: (1 - alpha^(-1))^2 * r
        3 + 3^2 + 2*3^4 + 2*3^5 + 2*3^6 + 3^7 + O(3^9)
        sage: P(0)
        3 + 3^2 + 2*3^4 + 2*3^5 + O(3^6)

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('37b')
        >>> L = e.padic_lseries(Integer(3))
        >>> P = L.series(Integer(5))
        >>> alpha = L.alpha(Integer(9)); alpha
        1 + 2*3 + 3^2 + 2*3^5 + 2*3^7 + 3^8 + O(3^9)
        >>> r = e.lseries().L_ratio(); r
        1/3
        >>> (Integer(1) - alpha**(-Integer(1)))**Integer(2) * r
        3 + 3^2 + 2*3^4 + 2*3^5 + 2*3^6 + 3^7 + O(3^9)
        >>> P(Integer(0))
        3 + 3^2 + 2*3^4 + 2*3^5 + O(3^6)

    We can use Sage modular symbols instead to compute the \(L\)-series:

    Sage

        sage: e = EllipticCurve('11a')
        sage: L = e.padic_lseries(3, implementation = 'sage')
        sage: L.series(5,prec=10)
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T + (1 + 2*3 + O(3^4))*T^2 + (3 + 2*3^2 + O(3^3))*T^3 + (2*3 + 3^2 + O(3^3))*T^4 + (2 + 2*3 + 2*3^2 + O(3^3))*T^5 + (1 + 3^2 + O(3^3))*T^6 + (2 + 3^2 + O(3^3))*T^7 + (2 + 2*3 + 2*3^2 + O(3^3))*T^8 + (2 + O(3^2))*T^9 + O(T^10)

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> L = e.padic_lseries(Integer(3), implementation = 'sage')
        >>> L.series(Integer(5),prec=Integer(10))
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + 3^6 + O(3^7) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T + (1 + 2*3 + O(3^4))*T^2 + (3 + 2*3^2 + O(3^3))*T^3 + (2*3 + 3^2 + O(3^3))*T^4 + (2 + 2*3 + 2*3^2 + O(3^3))*T^5 + (1 + 3^2 + O(3^3))*T^6 + (2 + 3^2 + O(3^3))*T^7 + (2 + 2*3 + 2*3^2 + O(3^3))*T^8 + (2 + O(3^2))*T^9 + O(T^10)

    Also the numerical modular symbols can be used. This may allow for much larger conductor in some instances:

    Sage

        sage: E = EllipticCurve([101,103])
        sage: L = E.padic_lseries(5, implementation='num')
        sage: L.series(2)
        O(5^4) + (3 + O(5))*T + (1 + O(5))*T^2 + (3 + O(5))*T^3 + O(5)*T^4 + O(T^5)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(101),Integer(103)])
        >>> L = E.padic_lseries(Integer(5), implementation='num')
        >>> L.series(Integer(2))
        O(5^4) + (3 + O(5))*T + (1 + O(5))*T^2 + (3 + O(5))*T^3 + O(5)*T^4 + O(T^5)

    Finally, we can use the overconvergent method of Pollack-Stevens.:

    Sage

        sage: e = EllipticCurve('11a')
        sage: L = e.padic_lseries(3, implementation = 'pollackstevens', precision = 6)
        sage: L.series(5)
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + O(3^6) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T + (1 + 2*3 + O(3^2))*T^2 + (3 + O(3^2))*T^3 + O(3^0)*T^4 + O(T^5)
        sage: L[3]
        3 + O(3^2)

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> L = e.padic_lseries(Integer(3), implementation = 'pollackstevens', precision = Integer(6))
        >>> L.series(Integer(5))
        2 + 3 + 3^2 + 2*3^3 + 2*3^5 + O(3^6) + (1 + 3 + 2*3^2 + 3^3 + O(3^4))*T + (1 + 2*3 + O(3^2))*T^2 + (3 + O(3^2))*T^3 + O(3^0)*T^4 + O(T^5)
        >>> L[Integer(3)]
        3 + O(3^2)

    Another example with a semistable prime.:

    Sage

        sage: E = EllipticCurve("11a1")
        sage: L = E.padic_lseries(11, implementation = 'pollackstevens', precision=3)
        sage: L[1]
        10 + 3*11 + O(11^2)
        sage: L[3]
        O(11^0)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("11a1")
        >>> L = E.padic_lseries(Integer(11), implementation = 'pollackstevens', precision=Integer(3))
        >>> L[Integer(1)]
        10 + 3*11 + O(11^2)
        >>> L[Integer(3)]
        O(11^0)

  padic_regulator(p, prec=20, height=None, check_hypotheses=True)

    Compute the cyclotomic \(p\)-adic regulator of this curve. The model of the curve needs to be integral and minimal at \(p\). Moreover the reduction at \(p\) should not be additive.

    INPUT:

    - `p` – prime >= 5

    - `prec` – answer will be returned modulo \(p^{\mathrm{prec}}\)

    - `height` – precomputed height function; if not supplied, this function will call `padic_height` to compute it

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic height makes sense

    OUTPUT: the \(p\)-adic cyclotomic regulator of this curve, to the requested precision

    If the rank is 0, we output 1.

    AUTHORS:

    - Liang Xiao: original implementation at the 2006 MSRI graduate workshop on modular forms

    - David Harvey (2006-09-13): cleaned up and integrated into Sage, removed some redundant height computations

    - Chris Wuthrich (2007-05-22): added multiplicative and supersingular cases

    - David Harvey (2007-09-20): fixed some precision loss that was occurring

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("37a")
        sage: E.padic_regulator(5, 10)
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("37a")
        >>> E.padic_regulator(Integer(5), Integer(10))
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + O(5^10)

    An anomalous case:

    Sage

        sage: E.padic_regulator(53, 10)
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + O(53^9)

    [Python]

        >>> from sage.all import *
        >>> E.padic_regulator(Integer(53), Integer(10))
        26*53^-1 + 30 + 20*53 + 47*53^2 + 10*53^3 + 32*53^4 + 9*53^5 + 22*53^6 + 35*53^7 + 30*53^8 + O(53^9)

    An anomalous case where the precision drops some:

    Sage

        sage: E = EllipticCurve("5077a")
        sage: E.padic_regulator(5, 10)
        5 + 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 4*5^7 + 2*5^8 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("5077a")
        >>> E.padic_regulator(Integer(5), Integer(10))
        5 + 5^2 + 4*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + 4*5^7 + 2*5^8 + 5^9 + O(5^10)

    Check that answers agree over a range of precisions:

    Sage

        sage: max_prec = 30    # make sure we get past p^2    # long time
        sage: full = E.padic_regulator(5, max_prec)           # long time
        sage: for prec in range(1, max_prec):                 # long time
        ....:     assert E.padic_regulator(5, prec) == full

    [Python]

        >>> from sage.all import *
        >>> max_prec = Integer(30)    # make sure we get past p^2    # long time
        >>> full = E.padic_regulator(Integer(5), max_prec)           # long time
        >>> for prec in range(Integer(1), max_prec):                 # long time
        ...     assert E.padic_regulator(Integer(5), prec) == full

    A case where the generator belongs to the formal group already (Issue #3632):

    Sage

        sage: E = EllipticCurve([37,0])
        sage: E.padic_regulator(5,10)
        2*5^2 + 2*5^3 + 5^4 + 5^5 + 4*5^6 + 3*5^8 + 4*5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(37),Integer(0)])
        >>> E.padic_regulator(Integer(5),Integer(10))
        2*5^2 + 2*5^3 + 5^4 + 5^5 + 4*5^6 + 3*5^8 + 4*5^9 + O(5^10)

    The result is not dependent on the model for the curve:

    Sage

        sage: E = EllipticCurve([0,0,0,0,2^12*17])
        sage: Em = E.minimal_model()
        sage: E.padic_regulator(7) == Em.padic_regulator(7)
        True

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(2)**Integer(12)*Integer(17)])
        >>> Em = E.minimal_model()
        >>> E.padic_regulator(Integer(7)) == Em.padic_regulator(Integer(7))
        True

    Allow a python int as input:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.padic_regulator(int(5))
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.padic_regulator(int(Integer(5)))
        5 + 5^2 + 5^3 + 3*5^6 + 4*5^7 + 5^9 + 5^10 + 3*5^11 + 3*5^12 + 5^13 + 4*5^14 + 5^15 + 2*5^16 + 5^17 + 2*5^18 + 4*5^19 + O(5^20)

  padic_sigma(p, N=20, E2=None, check=False, check_hypotheses=True)

    Compute the \(p\)-adic sigma function with respect to the standard invariant differential \(dx/(2y + a_1 x + a_3)\), as defined by Mazur and Tate in [MT1991], as a power series in the usual uniformiser \(t\) at the origin.

    The equation of the curve must be minimal at \(p\).

    INPUT:

    - `p` – prime >= 5 for which the curve has good ordinary reduction

    - `N` – integer >= 1 (default: 20); precision of result, see OUTPUT section for description

    - `E2` – precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod \(p^{N-2}\).

    - `check` – boolean; whether to perform a consistency check (i.e. verify that the computed sigma satisfies the defining

    - `differential equation` – note that this does NOT guarantee correctness of all the returned digits, but it comes pretty close

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic sigma function makes sense

    OUTPUT: a power series \(t + \cdots\) with coefficients in \(\ZZ_p\)

    The output series will be truncated at \(O(t^{N+1})\), and the coefficient of \(t^n\) for \(n \geq 1\) will be correct to precision \(O(p^{N-n+1})\).

    In practice this means the following. If \(t_0 = p^k u\), where \(u\) is a \(p\)-adic unit with at least \(N\) digits of precision, and \(k \geq 1\), then the returned series may be used to compute \(\sigma(t_0)\) correctly modulo \(p^{N+k}\) (i.e. with \(N\) correct \(p\)-adic digits).

    ALGORITHM: Described in “Efficient Computation of p-adic Heights” (David Harvey) [Har2009] which is basically an optimised version of the algorithm from “p-adic Heights and Log Convergence” (Mazur, Stein, Tate) [MST2006].

    Running time is soft-\(O(N^2 \log p)\), plus whatever time is necessary to compute \(E_2\).

    AUTHORS:

    - David Harvey (2006-09-12)

    - David Harvey (2007-02): rewrote

    EXAMPLES:

    Sage

        sage: EllipticCurve([-1, 1/4]).padic_sigma(5, 10)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)

    Python

        >>> from sage.all import *
        >>> EllipticCurve([-Integer(1), Integer(1)/Integer(4)]).padic_sigma(Integer(5), Integer(10))
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)

    Run it with a consistency check:

    Sage

        sage: EllipticCurve("37a").padic_sigma(5, 10, check=True)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve("37a").padic_sigma(Integer(5), Integer(10), check=True)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)

    Boundary cases:

    Sage

        sage: EllipticCurve([1, 1, 1, 1, 1]).padic_sigma(5, 1)
         (1 + O(5))*t + O(t^2)
        sage: EllipticCurve([1, 1, 1, 1, 1]).padic_sigma(5, 2)
         (1 + O(5^2))*t + (3 + O(5))*t^2 + O(t^3)

    Python

        >>> from sage.all import *
        >>> EllipticCurve([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).padic_sigma(Integer(5), Integer(1))
         (1 + O(5))*t + O(t^2)
        >>> EllipticCurve([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)]).padic_sigma(Integer(5), Integer(2))
         (1 + O(5^2))*t + (3 + O(5))*t^2 + O(t^3)

    Supply your very own value of E2:

    Sage

        sage: X = EllipticCurve("37a")
        sage: my_E2 = X.padic_E2(5, 8)
        sage: my_E2 = my_E2 + 5**5    # oops!!!
        sage: X.padic_sigma(5, 10, E2=my_E2)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 4*5^5 + 2*5^6 + 3*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 3*5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)

    [Python]

        >>> from sage.all import *
        >>> X = EllipticCurve("37a")
        >>> my_E2 = X.padic_E2(Integer(5), Integer(8))
        >>> my_E2 = my_E2 + Integer(5)**Integer(5)    # oops!!!
        >>> X.padic_sigma(Integer(5), Integer(10), E2=my_E2)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 4*5^5 + 2*5^6 + 3*5^7 + O(5^8))*t^3 + (3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + 2*5^6 + O(5^7))*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 3*5^5 + O(5^6))*t^5 + (2 + 3*5 + 5^4 + O(5^5))*t^6 + (4 + 3*5 + 2*5^2 + O(5^4))*t^7 + (2 + 3*5 + 2*5^2 + O(5^3))*t^8 + (4*5 + O(5^2))*t^9 + (1 + O(5))*t^10 + O(t^11)

    Check that sigma is “weight 1”.

    Sage

        sage: f = EllipticCurve([-1, 3]).padic_sigma(5, 10)
        sage: g = EllipticCurve([-1*(2**4), 3*(2**6)]).padic_sigma(5, 10)
        sage: t = f.parent().gen()
        sage: f(2*t)/2
        (1 + O(5^10))*t + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
        sage: g
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
        sage: f(2*t)/2 -g
        O(t^11)

    Python

        >>> from sage.all import *
        >>> f = EllipticCurve([-Integer(1), Integer(3)]).padic_sigma(Integer(5), Integer(10))
        >>> g = EllipticCurve([-Integer(1)*(Integer(2)**Integer(4)), Integer(3)*(Integer(2)**Integer(6))]).padic_sigma(Integer(5), Integer(10))
        >>> t = f.parent().gen()
        >>> f(Integer(2)*t)/Integer(2)
        (1 + O(5^10))*t + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
        >>> g
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (4 + 3*5 + 3*5^2 + 3*5^3 + 4*5^4 + 4*5^5 + 3*5^6 + 5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (3 + 3*5^2 + 5^4 + 2*5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (4 + 5 + 3*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (4 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)
        >>> f(Integer(2)*t)/Integer(2) -g
        O(t^11)

    Test that it returns consistent results over a range of precision:

    Sage

        sage: # long time
        sage: max_N = 30   # get up to at least p^2
        sage: E = EllipticCurve([1, 1, 1, 1, 1])
        sage: p = 5
        sage: E2 = E.padic_E2(5, max_N)
        sage: max_sigma = E.padic_sigma(p, max_N, E2=E2)
        sage: for N in range(3, max_N):
        ....:    sigma = E.padic_sigma(p, N, E2=E2)
        ....:    assert sigma == max_sigma

    [Python]

        >>> from sage.all import *
        >>> # long time
        >>> max_N = Integer(30)   # get up to at least p^2
        >>> E = EllipticCurve([Integer(1), Integer(1), Integer(1), Integer(1), Integer(1)])
        >>> p = Integer(5)
        >>> E2 = E.padic_E2(Integer(5), max_N)
        >>> max_sigma = E.padic_sigma(p, max_N, E2=E2)
        >>> for N in range(Integer(3), max_N):
        ...    sigma = E.padic_sigma(p, N, E2=E2)
        ...    assert sigma == max_sigma

  padic_sigma_truncated(p, N=20, lamb=0, E2=None, check_hypotheses=True)

    Compute the \(p\)-adic sigma function with respect to the standard invariant differential \(dx/(2y + a_1 x + a_3)\), as defined by Mazur and Tate in [MT1991], as a power series in the usual uniformiser \(t\) at the origin.

    The equation of the curve must be minimal at \(p\).

    This function differs from `padic_sigma()` in the precision profile of the returned power series; see OUTPUT below.

    INPUT:

    - `p` – prime >= 5 for which the curve has good ordinary reduction

    - `N` – integer >= 2 (default: 20); precision of result, see OUTPUT section for description

    - `lamb` – integer >= 0; see OUTPUT section for description

    - `E2` – precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied must be correct mod \(p^{N-2}\).

    - `check_hypotheses` – boolean; whether to check that this is a curve for which the \(p\)-adic sigma function makes sense

    OUTPUT: a power series \(t + \cdots\) with coefficients in \(\ZZ_p\)

    The coefficient of \(t^j\) for \(j \geq 1\) will be correct to precision \(O(p^{N - 2 + (3 - j)(lamb + 1)})\).

    ALGORITHM: Described in “Efficient Computation of p-adic Heights” [Har2009], which is basically an optimised version of the algorithm from “p-adic Heights and Log Convergence” (Mazur, Stein, Tate) [MST2006].

    Running time is soft-\(O(N^2 \lambda^{-1} \log p)\), plus whatever time is necessary to compute \(E_2\).

    AUTHORS:

    - David Harvey (2008-01): wrote based on previous `padic_sigma()` function

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([-1, 1/4])
        sage: E.padic_sigma_truncated(5, 10)
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(1), Integer(1)/Integer(4)])
        >>> E.padic_sigma_truncated(Integer(5), Integer(10))
        O(5^11) + (1 + O(5^10))*t + O(5^9)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^7)*t^4 + (2 + 4*5^2 + 4*5^3 + 5^4 + 5^5 + O(5^6))*t^5 + O(5^5)*t^6 + (2 + 2*5 + 5^2 + 4*5^3 + O(5^4))*t^7 + O(5^3)*t^8 + (1 + 2*5 + O(5^2))*t^9 + O(5)*t^10 + O(t^11)

    Note the precision of the \(t^3\) coefficient depends only on \(N\), not on lamb:

    Sage

        sage: E.padic_sigma_truncated(5, 10, lamb=2)
        O(5^17) + (1 + O(5^14))*t + O(5^11)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^5)*t^4 + (2 + O(5^2))*t^5 + O(t^6)

    [Python]

        >>> from sage.all import *
        >>> E.padic_sigma_truncated(Integer(5), Integer(10), lamb=Integer(2))
        O(5^17) + (1 + O(5^14))*t + O(5^11)*t^2 + (3 + 2*5^2 + 3*5^3 + 3*5^6 + 4*5^7 + O(5^8))*t^3 + O(5^5)*t^4 + (2 + O(5^2))*t^5 + O(t^6)

    Compare against plain padic_sigma() function over a dense range of N and lamb

    Sage

        sage: E = EllipticCurve([1, 2, 3, 4, 7])                            # long time
        sage: E2 = E.padic_E2(5, 50)                                        # long time
        sage: for N in range(2, 10):                                        # long time
        ....:    for lamb in range(10):
        ....:       correct = E.padic_sigma(5, N + 3*lamb, E2=E2)
        ....:       compare = E.padic_sigma_truncated(5, N=N, lamb=lamb, E2=E2)
        ....:       assert compare == correct

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), Integer(2), Integer(3), Integer(4), Integer(7)])                            # long time
        >>> E2 = E.padic_E2(Integer(5), Integer(50))                                        # long time
        >>> for N in range(Integer(2), Integer(10)):                                        # long time
        ...    for lamb in range(Integer(10)):
        ...       correct = E.padic_sigma(Integer(5), N + Integer(3)*lamb, E2=E2)
        ...       compare = E.padic_sigma_truncated(Integer(5), N=N, lamb=lamb, E2=E2)
        ...       assert compare == correct

  pari_curve()

    Return the PARI curve corresponding to this elliptic curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, 0, 1, -1, 0])
        sage: e = E.pari_curve()
        sage: type(e)
        <... 'cypari2.gen.Gen'>
        sage: e.type()
        't_VEC'
        sage: e.ellan(10)
        [1, -2, -3, 2, -2, 6, -1, 0, 6, 4]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)])
        >>> e = E.pari_curve()
        >>> type(e)
        <... 'cypari2.gen.Gen'>
        >>> e.type()
        't_VEC'
        >>> e.ellan(Integer(10))
        [1, -2, -3, 2, -2, 6, -1, 0, 6, 4]

    Sage

        sage: E = EllipticCurve(RationalField(), ['1/3', '2/3'])
        sage: e = E.pari_curve()
        sage: e[:5]
        [0, 0, 0, 1/3, 2/3]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve(RationalField(), ['1/3', '2/3'])
        >>> e = E.pari_curve()
        >>> e[:Integer(5)]
        [0, 0, 0, 1/3, 2/3]

    When doing certain computations, PARI caches the results:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: _ = E.__dict__.pop('_pari_curve', None)  # clear cached data
        sage: Epari = E.pari_curve()
        sage: Epari
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]]
        sage: Epari.omega()
        [2.99345864623196, -2.45138938198679*I]
        sage: Epari
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, Vecsmall([1]), [Vecsmall([64, 1])], [[2.99345864623196, -2.45138938198679*I], 0, [0.837565435283323, 0.269594436405445, -1.10715987168877, 1.37675430809421, 1.94472530697209, 0.567970998877878]~, 0, 0, 0, 0, 0]]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> _ = E.__dict__.pop('_pari_curve', None)  # clear cached data
        >>> Epari = E.pari_curve()
        >>> Epari
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]]
        >>> Epari.omega()
        [2.99345864623196, -2.45138938198679*I]
        >>> Epari
        [0, 0, 1, -1, 0, 0, -2, 1, -1, 48, -216, 37, 110592/37, Vecsmall([1]), [Vecsmall([64, 1])], [[2.99345864623196, -2.45138938198679*I], 0, [0.837565435283323, 0.269594436405445, -1.10715987168877, 1.37675430809421, 1.94472530697209, 0.567970998877878]~, 0, 0, 0, 0, 0]]

    This shows that the bug uncovered by Issue #4715 is fixed:

    Sage

        sage: Ep = EllipticCurve('903b3').pari_curve()

    [Python]

        >>> from sage.all import *
        >>> Ep = EllipticCurve('903b3').pari_curve()

    This still works, even when the curve coefficients are large (see Issue #13163):

    Sage

        sage: E = EllipticCurve([4382696457564794691603442338788106497, 28, 3992, 16777216, 298])
        sage: E.pari_curve()
        [4382696457564794691603442338788106497, 28, 3992, 16777216, 298, ...]
        sage: E.minimal_model()
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 7686423934083797390675981169229171907674183588326184511391146727143672423167091484392497987721106542488224058921302964259990799229848935835464702*x + 8202280443553761483773108648734271851215988504820214784899752662100459663011709992446860978259617135893103951840830254045837355547141096270521198994389833928471736723050112419004202643591202131091441454709193394358885 over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(4382696457564794691603442338788106497), Integer(28), Integer(3992), Integer(16777216), Integer(298)])
        >>> E.pari_curve()
        [4382696457564794691603442338788106497, 28, 3992, 16777216, 298, ...]
        >>> E.minimal_model()
        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 7686423934083797390675981169229171907674183588326184511391146727143672423167091484392497987721106542488224058921302964259990799229848935835464702*x + 8202280443553761483773108648734271851215988504820214784899752662100459663011709992446860978259617135893103951840830254045837355547141096270521198994389833928471736723050112419004202643591202131091441454709193394358885 over Rational Field

  pari_mincurve()

    Return the PARI curve corresponding to a minimal model for this elliptic curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve(RationalField(), ['1/3', '2/3'])
        sage: e = E.pari_mincurve()
        sage: e[:5]
        [0, 0, 0, 27, 486]
        sage: E.conductor()
        47232
        sage: e.ellglobalred()
        [47232, [1, 0, 0, 0], 2, [2, 7; 3, 2; 41, 1], [[7, 2, 0, 1], [2, -3, 0, 2], [1, 5, 0, 1]]]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve(RationalField(), ['1/3', '2/3'])
        >>> e = E.pari_mincurve()
        >>> e[:Integer(5)]
        [0, 0, 0, 27, 486]
        >>> E.conductor()
        47232
        >>> e.ellglobalred()
        [47232, [1, 0, 0, 0], 2, [2, 7; 3, 2; 41, 1], [[7, 2, 0, 1], [2, -3, 0, 2], [1, 5, 0, 1]]]

  period_lattice(embedding=None)

    Return the period lattice of the elliptic curve with respect to the differential \(dx/(2y + a_1x + a_3)\).

    INPUT:

    - `embedding` – ignored (for compatibility with the period_lattice function for elliptic_curve_number_field)

    OUTPUT:

    (period lattice) The `PeriodLattice_ell` object associated to this elliptic curve (with respect to the natural embedding of \(\QQ\) into \(\RR\)).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.period_lattice()
        Period lattice associated to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.period_lattice()
        Period lattice associated to
         Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

  point_search(height_limit, verbose=False, rank_bound=None)

    Search for points on a curve up to an input bound on the naive logarithmic height.

    INPUT:

    - `height_limit` – float; bound on naive height

    - `verbose` – boolean (default: `False`); if `True`, report on the saturation process otherwise just return the result

    - `rank_bound` – boolean (optional); if provided, stop saturating once we find this many independent nontorsion points

    OUTPUT: points (list) - list of independent points which generate the subgroup of the Mordell-Weil group generated by the points found and then saturated.

    Warning

    height_limit is logarithmic, so increasing by 1 will cause the running time to increase by a factor of approximately 4.5 (=exp(1.5)).

    IMPLEMENTATION: Uses Michael Stoll’s ratpoints module in PARI/GP.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: E.point_search(1, verbose=False)
        [(-1 : 1 : 1), (0 : 0 : 1)]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> E.point_search(Integer(1), verbose=False)
        [(-1 : 1 : 1), (0 : 0 : 1)]

    Increasing the height_limit takes longer, but finds no more points:

    Sage

        sage: E.point_search(10, verbose=False)  # long time
        [(-1 : 1 : 1), (0 : 0 : 1)]

    [Python]

        >>> from sage.all import *
        >>> E.point_search(Integer(10), verbose=False)  # long time
        [(-1 : 1 : 1), (0 : 0 : 1)]

    In fact this curve has rank 2 so no more than 2 points will ever be output, but we are not using this fact.

    Sage

        sage: E.saturation(_)
        ([(-1 : 1 : 1), (0 : 0 : 1)], 1, 0.152460177943144)

    Python

        >>> from sage.all import *
        >>> E.saturation(_)
        ([(-1 : 1 : 1), (0 : 0 : 1)], 1, 0.152460177943144)

    What this shows is that if the rank is 2 then the points listed do generate the Mordell-Weil group (mod torsion). Finally,

    Sage

        sage: E.rank()
        2

    [Python]

        >>> from sage.all import *
        >>> E.rank()
        2

    If we only need one independent generator:

    Sage

        sage: E.point_search(5, verbose=False, rank_bound=1)
        [(-2 : 0 : 1)]

    Python

        >>> from sage.all import *
        >>> E.point_search(Integer(5), verbose=False, rank_bound=Integer(1))
        [(-2 : 0 : 1)]

  pollack_stevens_modular_symbol(sign=0, implementation='eclib')

    Create the modular symbol attached to the elliptic curve, suitable for overconvergent calculations.

    INPUT:

    - `sign` – +1 or -1 or 0 (default), in which case this it is the sum of the two

    - `implementation` – either ‘eclib’ (default) or ‘sage’. This determines classical modular symbols which implementation of the underlying classical modular symbols is used

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('113a1')
        sage: symb = E.pollack_stevens_modular_symbol()
        sage: symb
        Modular symbol of level 113 with values in Sym^0 Q^2
        sage: symb.values()
        [-1/2, 1, -1, 0, 0, 1, 1, -1, 0, -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0]

        sage: E = EllipticCurve([0,1])
        sage: symb = E.pollack_stevens_modular_symbol(+1)
        sage: symb.values()
        [-1/6, 1/12, 0, 1/6, 1/12, 1/3, -1/12, 0, -1/6, -1/12, -1/4, -1/6, 1/12]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('113a1')
        >>> symb = E.pollack_stevens_modular_symbol()
        >>> symb
        Modular symbol of level 113 with values in Sym^0 Q^2
        >>> symb.values()
        [-1/2, 1, -1, 0, 0, 1, 1, -1, 0, -1, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, 0]

        >>> E = EllipticCurve([Integer(0),Integer(1)])
        >>> symb = E.pollack_stevens_modular_symbol(+Integer(1))
        >>> symb.values()
        [-1/6, 1/12, 0, 1/6, 1/12, 1/3, -1/12, 0, -1/6, -1/12, -1/4, -1/6, 1/12]

  prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, return_BSD=False)

    Attempt to prove the Birch and Swinnerton-Dyer conjectural formula for \(E\), returning a list of primes \(p\) for which this function fails to prove BSD(E,p).

    Here, BSD(E,p) is the statement: “the Birch and Swinnerton-Dyer formula holds up to a rational number coprime to \(p\).”

    INPUT:

    - `E` – an elliptic curve

    - `verbosity` – integer; how much information about the proof to print

      - 0: print nothing

      - 1: print sketch of proof

      - 2: print information about remaining primes

    - `two_desc` – string (default: `'mwrank'`); what to use for the two-descent. Options are `'mwrank', 'pari', 'sage'`.

    - `proof` – boolean or `None` (default: None, see proof.elliptic_curve or sage.structure.proof). If `False`, this function just immediately returns the empty list.

    - `secs_hi` – maximum number of seconds to try to compute the Heegner index before switching over to trying to compute the Heegner index bound. (Rank 0 only!)

    - `return_BSD` – boolean (default: `False`); whether to return an object which contains information to reconstruct a proof

    Note

    When printing verbose output, phrases such as “by Mazur” are referring to the following list of papers:

    REFERENCES:

    - [Cha2005]

    - [Jet2008]

    - [Kat2004]

    - [Kol1991]

    - [LW2015]

    - [LS]

    - [Maz1978]

    - [Rub1991]

    - [SW2013]

    - [GJPST2009]

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a').prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 5} by Kolyvagin.
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 5 by Kolyvagin bound
        []

        sage: EllipticCurve('14a').prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        []

        sage: E = EllipticCurve("20a1")
        sage: E.prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kato further implies that #Sha[3] is trivial.
        []

        sage: E = EllipticCurve("50b1")
        sage: E.prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 3, 5} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        True for p = 5 by Kolyvagin bound
        []
        sage: E.prove_BSD(two_desc='pari')
        []

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a').prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 5} by Kolyvagin.
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 5 by Kolyvagin bound
        []

        >>> EllipticCurve('14a').prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        []

        >>> E = EllipticCurve("20a1")
        >>> E.prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kato further implies that #Sha[3] is trivial.
        []

        >>> E = EllipticCurve("50b1")
        >>> E.prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 3, 5} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        True for p = 5 by Kolyvagin bound
        []
        >>> E.prove_BSD(two_desc='pari')
        []

    A rank two curve:

    Sage

        sage: E = EllipticCurve('389a')

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('389a')

    We know nothing with proof=True:

    Sage

        sage: E.prove_BSD()
        Set of all prime numbers: 2, 3, 5, 7, ...

    Python

        >>> from sage.all import *
        >>> E.prove_BSD()
        Set of all prime numbers: 2, 3, 5, 7, ...

    We (think we) know everything with proof=False:

    Sage

        sage: E.prove_BSD(proof=False)
        []

    [Python]

        >>> from sage.all import *
        >>> E.prove_BSD(proof=False)
        []

    A curve of rank 0 and prime conductor:

    Sage

        sage: E = EllipticCurve('19a')
        sage: E.prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        []

        sage: E = EllipticCurve('37a')
        sage: E.rank()
        1
        sage: E._EllipticCurve_rational_field__rank
        (1, True)
        sage: E.analytic_rank = lambda : 0
        sage: E.prove_BSD()
        Traceback (most recent call last):
        ...
        RuntimeError: It seems that the rank conjecture does not hold for this curve
        (Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)!
        This may be a counterexample to BSD, but is more likely a bug.

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('19a')
        >>> E.prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        Kolyvagin's bound for p = 3 applies by Lawson-Wuthrich
        True for p = 3 by Kolyvagin bound
        []

        >>> E = EllipticCurve('37a')
        >>> E.rank()
        1
        >>> E._EllipticCurve_rational_field__rank
        (1, True)
        >>> E.analytic_rank = lambda : Integer(0)
        >>> E.prove_BSD()
        Traceback (most recent call last):
        ...
        RuntimeError: It seems that the rank conjecture does not hold for this curve
        (Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field)!
        This may be a counterexample to BSD, but is more likely a bug.

    We test the consistency check for the 2-part of Sha:

    Sage

        sage: E = EllipticCurve('37a')
        sage: S = E.sha(); S
        Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x
         over Rational Field
        sage: def foo(use_database):
        ....:  return 4
        sage: S.an = foo
        sage: E.prove_BSD()
        Traceback (most recent call last):
        ...
        RuntimeError: Apparent contradiction: 0 <= rank(sha[2]) <= 0, but ord_2(sha_an) = 2

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> S = E.sha(); S
        Tate-Shafarevich group for the Elliptic Curve defined by y^2 + y = x^3 - x
         over Rational Field
        >>> def foo(use_database):
        ...  return Integer(4)
        >>> S.an = foo
        >>> E.prove_BSD()
        Traceback (most recent call last):
        ...
        RuntimeError: Apparent contradiction: 0 <= rank(sha[2]) <= 0, but ord_2(sha_an) = 2

    An example with a Tamagawa number at 5:

    Sage

        sage: E = EllipticCurve('123a1')
        sage: E.prove_BSD(verbosity=2)
        p = 2: True by 2-descent
        True for p not in {2, 5} by Kolyvagin.
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 5 by Kolyvagin bound
        []

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('123a1')
        >>> E.prove_BSD(verbosity=Integer(2))
        p = 2: True by 2-descent
        True for p not in {2, 5} by Kolyvagin.
        Kolyvagin's bound for p = 5 applies by Lawson-Wuthrich
        True for p = 5 by Kolyvagin bound
        []

    A curve for which 3 divides the order of the Tate-Shafarevich group:

    Sage

        sage: E = EllipticCurve('681b')
        sage: E.prove_BSD(verbosity=2)               # long time
        p = 2: True by 2-descent...
        True for p not in {2, 3} by Kolyvagin....
        Remaining primes:
        p = 3: irreducible, surjective, non-split multiplicative
            (0 <= ord_p <= 2)
            ord_p(#Sha_an) = 2
        [3]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('681b')
        >>> E.prove_BSD(verbosity=Integer(2))               # long time
        p = 2: True by 2-descent...
        True for p not in {2, 3} by Kolyvagin....
        Remaining primes:
        p = 3: irreducible, surjective, non-split multiplicative
            (0 <= ord_p <= 2)
            ord_p(#Sha_an) = 2
        [3]

    A curve for which we need to use `heegner_index_bound`:

    Sage

        sage: E = EllipticCurve('198b')
        sage: E.prove_BSD(verbosity=1, secs_hi=1)
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        [3]

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('198b')
        >>> E.prove_BSD(verbosity=Integer(1), secs_hi=Integer(1))
        p = 2: True by 2-descent
        True for p not in {2, 3} by Kolyvagin.
        [3]

    The `return_BSD` option gives an object with detailed information about the proof:

    Sage

        sage: E = EllipticCurve('26b')
        sage: B = E.prove_BSD(return_BSD=True)
        sage: B.two_tor_rk
        0
        sage: B.N
        26
        sage: B.gens
        []
        sage: B.primes
        []
        sage: B.heegner_indexes
        {-23: 2}

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('26b')
        >>> B = E.prove_BSD(return_BSD=True)
        >>> B.two_tor_rk
        0
        >>> B.N
        26
        >>> B.gens
        []
        >>> B.primes
        []
        >>> B.heegner_indexes
        {-23: 2}

  q_eigenform(prec)

    Synonym for `self.q_expansion(prec)`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.q_eigenform(10)
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + O(q^10)
        sage: E.q_eigenform(10) == E.q_expansion(10)
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.q_eigenform(Integer(10))
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + O(q^10)
        >>> E.q_eigenform(Integer(10)) == E.q_expansion(Integer(10))
        True

  q_expansion(prec)

    Return the \(q\)-expansion to precision `prec` of the newform attached to this elliptic curve.

    INPUT:

    - `prec` – integer

    OUTPUT: a power series (in the variable ‘q’)

    Note

    If you want the output to be a modular form and not just a \(q\)-expansion, use `modular_form()`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.q_expansion(20)
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10
         - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.q_expansion(Integer(20))
        q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + 4*q^10
         - 5*q^11 - 6*q^12 - 2*q^13 + 2*q^14 + 6*q^15 - 4*q^16 - 12*q^18 + O(q^20)

  quadratic_twist(D)

    Return the global minimal model of the quadratic twist of this curve by `D`.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E7 = E.quadratic_twist(7); E7
        Elliptic Curve defined by y^2 = x^3 - 784*x + 5488 over Rational Field
        sage: E7.conductor()
        29008
        sage: E7.quadratic_twist(7) == E
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E7 = E.quadratic_twist(Integer(7)); E7
        Elliptic Curve defined by y^2 = x^3 - 784*x + 5488 over Rational Field
        >>> E7.conductor()
        29008
        >>> E7.quadratic_twist(Integer(7)) == E
        True

  rank(use_database=True, verbose=False, only_use_mwrank=True, algorithm='mwrank_lib', proof=None, pari_effort=0)

    Return the rank of this elliptic curve, assuming no conjectures.

    If we fail to provably compute the rank, raises a RuntimeError exception.

    INPUT:

    - `use_database` – boolean (default: `True`); if `True`, try to look up the rank in the Cremona database

    - `verbose` – boolean (default: `False`); if specified changes the verbosity of mwrank computations

    - `algorithm` – (default: `'mwrank_lib'`) one of:

      - `'mwrank_shell'` – call mwrank shell command

      - `'mwrank_lib'` – call mwrank c library

      - `'pari'` – call ellrank in pari

    - `only_use_mwrank` – boolean (default: `True`); if `False` try using analytic rank methods first

    - `proof` – boolean (default: `None`, see `proof.elliptic_curve` or `sage.structure.proof`); note that results obtained from databases are considered `proof=True`

    - `pari_effort` – (default: 0) parameter used in when the algorithm `pari` is chosen. It measure of the effort done to find rational points. Values up to 10 can be chosen; the running times increase roughly like the cube of the effort value.

    OUTPUT: the rank of the elliptic curve as `Integer`

    IMPLEMENTATION: uses \(L\)-functions, mwrank, pari, and databases

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a').rank()
        0
        sage: EllipticCurve('37a').rank()
        1
        sage: EllipticCurve('389a').rank()
        2
        sage: EllipticCurve('5077a').rank()
        3
        sage: EllipticCurve([1, -1, 0, -79, 289]).rank()   # This will use the default proof behavior of True
        4
        sage: EllipticCurve([0, 0, 1, -79, 342]).rank(proof=False)
        5
        sage: EllipticCurve([0, 0, 1, -79, 342]).rank(algorithm='pari')
        5

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a').rank()
        0
        >>> EllipticCurve('37a').rank()
        1
        >>> EllipticCurve('389a').rank()
        2
        >>> EllipticCurve('5077a').rank()
        3
        >>> EllipticCurve([Integer(1), -Integer(1), Integer(0), -Integer(79), Integer(289)]).rank()   # This will use the default proof behavior of True
        4
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(79), Integer(342)]).rank(proof=False)
        5
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(79), Integer(342)]).rank(algorithm='pari')
        5

    Examples with denominators in defining equations:

    Sage

        sage: E = EllipticCurve([0, 0, 0, 0, -675/4])
        sage: E.rank()
        0
        sage: E = EllipticCurve([0, 0, 1/2, 0, -1/5])
        sage: E.rank()
        1
        sage: E.minimal_model().rank()
        1

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(0), Integer(0), -Integer(675)/Integer(4)])
        >>> E.rank()
        0
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1)/Integer(2), Integer(0), -Integer(1)/Integer(5)])
        >>> E.rank()
        1
        >>> E.minimal_model().rank()
        1

    A large example where mwrank doesn’t determine the result with certainty, but pari does:

    Sage

        sage: EllipticCurve([1,0,0,0,37455]).rank(proof=False)
        0
        sage: EllipticCurve([1,0,0,0,37455]).rank(proof=True)
        Traceback (most recent call last):
        ...
        RuntimeError: rank not provably correct (lower bound: 0)
        sage: EllipticCurve([1,0,0,0,37455]).rank(algorithm='pari')
        0

    Python

        >>> from sage.all import *
        >>> EllipticCurve([Integer(1),Integer(0),Integer(0),Integer(0),Integer(37455)]).rank(proof=False)
        0
        >>> EllipticCurve([Integer(1),Integer(0),Integer(0),Integer(0),Integer(37455)]).rank(proof=True)
        Traceback (most recent call last):
        ...
        RuntimeError: rank not provably correct (lower bound: 0)
        >>> EllipticCurve([Integer(1),Integer(0),Integer(0),Integer(0),Integer(37455)]).rank(algorithm='pari')
        0

  rank_bound(algorithm='pari')

    Return the upper bound on the rank of the curve, computed using a 2-descent.

    INPUT:

    - `algorithm` – either `'pari'` (default) or `'mwrank'`

    In many cases, this is the actual rank of the curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve("389a1")
        sage: E.rank_bound()
        2

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve("389a1")
        >>> E.rank_bound()
        2

    The following is the curve 571a1, which has rank 0, but Sha of order 4, yet pari, using the Cassels pairing is able to show that the rank is 0. The 2-descent in mwrank only determines a weaker upper bound:

    Sage

        sage: E = EllipticCurve([0, -1, 1, -929, -10595])
        sage: E.rank_bound()
        0
        sage: E.rank_bound(algorithm='mwrank')
        2

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(1), -Integer(929), -Integer(10595)])
        >>> E.rank_bound()
        0
        >>> E.rank_bound(algorithm='mwrank')
        2

    In the following last example, both algorithm only determine a rank bound larger than the actual rank:

    Sage

        sage: E = EllipticCurve([1, 1, 1, -896670, -327184905])
        sage: E.rank_bound()
        2
        sage: E.rank_bound(algorithm='mwrank')
        2
        sage: E.rank(only_use_mwrank=False) # uses L-function
        0

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), Integer(1), Integer(1), -Integer(896670), -Integer(327184905)])
        >>> E.rank_bound()
        2
        >>> E.rank_bound(algorithm='mwrank')
        2
        >>> E.rank(only_use_mwrank=False) # uses L-function
        0

  real_components()

    Return the number of real components.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a')
        sage: E.real_components ()
        2
        sage: E = EllipticCurve('37b')
        sage: E.real_components ()
        2
        sage: E = EllipticCurve('11a')
        sage: E.real_components ()
        1

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a')
        >>> E.real_components ()
        2
        >>> E = EllipticCurve('37b')
        >>> E.real_components ()
        2
        >>> E = EllipticCurve('11a')
        >>> E.real_components ()
        1

  reduction(p)

    Return the reduction of the elliptic curve at a prime of good reduction.

    Note

    The actual reduction is done in `self.change_ring(GF(p))`; the reduction is performed after changing to a model which is minimal at p.

    INPUT:

    - `p` – a (positive) prime number

    OUTPUT: an elliptic curve over the finite field \(\GF{p}\)

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('389a1')
        sage: E.reduction(2)
        Elliptic Curve defined by y^2 + y = x^3 + x^2 over Finite Field of size 2
        sage: E.reduction(3)
        Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3
        sage: E.reduction(5)
        Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x over Finite Field of size 5
        sage: E.reduction(38)
        Traceback (most recent call last):
        ...
        AttributeError: p must be prime.
        sage: E.reduction(389)
        Traceback (most recent call last):
        ...
        AttributeError: The curve must have good reduction at p.
        sage: E = EllipticCurve([5^4, 5^6])
        sage: E.reduction(5)
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('389a1')
        >>> E.reduction(Integer(2))
        Elliptic Curve defined by y^2 + y = x^3 + x^2 over Finite Field of size 2
        >>> E.reduction(Integer(3))
        Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3
        >>> E.reduction(Integer(5))
        Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x over Finite Field of size 5
        >>> E.reduction(Integer(38))
        Traceback (most recent call last):
        ...
        AttributeError: p must be prime.
        >>> E.reduction(Integer(389))
        Traceback (most recent call last):
        ...
        AttributeError: The curve must have good reduction at p.
        >>> E = EllipticCurve([Integer(5)**Integer(4), Integer(5)**Integer(6)])
        >>> E.reduction(Integer(5))
        Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 5

  regulator(proof=None, precision=53, **kwds)

    Return the regulator of this curve, which must be defined over \(\QQ\).

    INPUT:

    - `proof` – boolean or `None` (default: `None`, see proof.[tab] or sage.structure.proof). Note that results from databases are considered `proof = True`.

    - `precision` – integer (default: 53); the precision in bits of the result

    - `**kwds` – passed to `gens()` method

    EXAMPLES:

    Sage

        sage: E = EllipticCurve([0, 0, 1, -1, 0])
        sage: E.regulator()
        0.0511114082399688
        sage: EllipticCurve('11a').regulator()
        1.00000000000000
        sage: EllipticCurve('37a').regulator()
        0.0511114082399688
        sage: EllipticCurve('389a').regulator()
        0.152460177943144
        sage: EllipticCurve('5077a').regulator()
        0.41714355875838...
        sage: EllipticCurve([1, -1, 0, -79, 289]).regulator()
        1.50434488827528
        sage: EllipticCurve([0, 0, 1, -79, 342]).regulator(proof=False)  # long time (6s on sage.math, 2011)
        14.790527570131...

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(1), Integer(0)])
        >>> E.regulator()
        0.0511114082399688
        >>> EllipticCurve('11a').regulator()
        1.00000000000000
        >>> EllipticCurve('37a').regulator()
        0.0511114082399688
        >>> EllipticCurve('389a').regulator()
        0.152460177943144
        >>> EllipticCurve('5077a').regulator()
        0.41714355875838...
        >>> EllipticCurve([Integer(1), -Integer(1), Integer(0), -Integer(79), Integer(289)]).regulator()
        1.50434488827528
        >>> EllipticCurve([Integer(0), Integer(0), Integer(1), -Integer(79), Integer(342)]).regulator(proof=False)  # long time (6s on sage.math, 2011)
        14.790527570131...

  root_number(p=None)

    Return the root number of this elliptic curve.

    This is 1 if the order of vanishing of the \(L\)-function \(L(E,s)\) at 1 is even, and -1 if it is odd.

    INPUT:

    - `p` – (optional) if given, return the local root number at `p`

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a1').root_number()
        1
        sage: EllipticCurve('37a1').root_number()
        -1
        sage: EllipticCurve('389a1').root_number()
        1
        sage: type(EllipticCurve('389a1').root_number())
        <... 'sage.rings.integer.Integer'>

        sage: E = EllipticCurve('100a1')
        sage: E.root_number(2)
        -1
        sage: E.root_number(5)
        1
        sage: E.root_number(7)
        1

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a1').root_number()
        1
        >>> EllipticCurve('37a1').root_number()
        -1
        >>> EllipticCurve('389a1').root_number()
        1
        >>> type(EllipticCurve('389a1').root_number())
        <... 'sage.rings.integer.Integer'>

        >>> E = EllipticCurve('100a1')
        >>> E.root_number(Integer(2))
        -1
        >>> E.root_number(Integer(5))
        1
        >>> E.root_number(Integer(7))
        1

    The root number is cached:

    Sage

        sage: E.root_number(2) is E.root_number(2)
        True
        sage: E.root_number()
        1

    [Python]

        >>> from sage.all import *
        >>> E.root_number(Integer(2)) is E.root_number(Integer(2))
        True
        >>> E.root_number()
        1

  satisfies_heegner_hypothesis(D)

    Return `True` precisely when \(D\) is a fundamental discriminant that satisfies the Heegner hypothesis for this elliptic curve.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a1')
        sage: E.satisfies_heegner_hypothesis(-7)
        True
        sage: E.satisfies_heegner_hypothesis(-11)
        False

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a1')
        >>> E.satisfies_heegner_hypothesis(-Integer(7))
        True
        >>> E.satisfies_heegner_hypothesis(-Integer(11))
        False

  saturation(points, verbose=False, max_prime=-1, min_prime=2)

    Given a list of rational points on \(E\), compute the saturation in \(E(Q)\) of the subgroup they generate.

    INPUT:

    - `points` – list of points on \(E\)

    - `verbose` – boolean (default: `False`); if `True`, give verbose output

    - `max_prime` – integer (default: \(-1\)); if \(-1\), an upper bound is computed for the primes at which the subgroup may not be saturated, and saturation is performed for all primes up to this bound; otherwise, the bound used is the minimum of `max_prime` and the computed bound

    - `min_prime` – integer (default: \(2\)); only do \(p\)-saturation at primes \(p\) greater than or equal to this

    Note

    To saturate at a single prime \(p\), set `max_prime` and `min_prime` both to \(p\). One situation where this is useful is after mapping saturated points from another elliptic curve by a \(p\)-isogeny, since the images may not be \(p\)-saturated but will be saturated at all other primes.

    OUTPUT:

    - `saturation` – list; points that form a basis for the saturation

    - `index` – integer; the index of the group generated by points in their saturation

    - `regulator` – real with default precision; regulator of saturated points

    ALGORITHM:

    Uses Cremona’s `eclib` package, which computes a bound on the saturation index. To \(p\)-saturate, or prove \(p\)-saturation, we consider the reductions of the points modulo primes \(q\) of good reduction such that \(E(\GF{q})\) has order divisible by \(p\).

    Note

    In versions of `eclib` up to `v20190909`, division of points in `eclib` was done using floating point methods, without automatic handling of precision, so that \(p\)-saturation sometimes failed unless `mwrank_set_precision()` was called in advance with a suitably high bit precision. Since version `v20210310` of `eclib`, division is done using exact methods based on division polynomials, and \(p\)-saturation cannot fail in this way.

    Note

    The computed index of saturation may be large, in which case saturation may take a long time. For example, the rank 4 curve `EllipticCurve([0,1,1,-9872,374262])` has a saturation index bound of 11816 and takes around 40 seconds to prove saturation.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: P=E(0,0)
        sage: Q=5*P; Q
        (1/4 : -5/8 : 1)
        sage: E.saturation([Q])
        ([(0 : 0 : 1)], 5, 0.0511114082399688)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> P=E(Integer(0),Integer(0))
        >>> Q=Integer(5)*P; Q
        (1/4 : -5/8 : 1)
        >>> E.saturation([Q])
        ([(0 : 0 : 1)], 5, 0.0511114082399688)

  selmer_rank(algorithm='pari')

    Return the rank of the 2-Selmer group of the curve.

    INPUT:

    - `algorithm` – either `'pari'` (default) or `'mwrank'`

    EXAMPLES: This example has rank 1, Sha[2] of order 4 and a single rational 2-torsion point:

    Sage

        sage: E = EllipticCurve([1, 1, 1, 508, -2551])
        sage: E.selmer_rank()
        4
        sage: E.selmer_rank(algorithm='mwrank')
        4

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), Integer(1), Integer(1), Integer(508), -Integer(2551)])
        >>> E.selmer_rank()
        4
        >>> E.selmer_rank(algorithm='mwrank')
        4

    The following is the curve 960d1, which has rank 0, but Sha of order 4:

    Sage

        sage: E = EllipticCurve([0, -1, 0, -900, -10098])
        sage: E.selmer_rank()
        3
        sage: E.selmer_rank(algorithm='mwrank')
        3

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(0), -Integer(1), Integer(0), -Integer(900), -Integer(10098)])
        >>> E.selmer_rank()
        3
        >>> E.selmer_rank(algorithm='mwrank')
        3

    This curve has rank 1, and 4 elements in Sha[2]. Yet the order of Sha is 16, so that group is the product of two cyclic groups of order 4:

    Sage

        sage: E = EllipticCurve([1, 0, 0, -150752, -22541610])
        sage: E.selmer_rank()
        4

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), Integer(0), Integer(0), -Integer(150752), -Integer(22541610)])
        >>> E.selmer_rank()
        4

    Instead in this last example of rank 0, Sha is a product of four cyclic groups of order 2:

    Sage

        sage: E = EllipticCurve([1, 0, 0, -49280, -4214808])
        sage: E.selmer_rank()
        5
        sage: E.rank()
        0

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([Integer(1), Integer(0), Integer(0), -Integer(49280), -Integer(4214808)])
        >>> E.selmer_rank()
        5
        >>> E.rank()
        0

  sha()

    Return an object of class ‘sage.schemes.elliptic_curves.sha_tate.Sha’ attached to this elliptic curve.

    This can be used in functions related to bounding the order of Sha (The Tate-Shafarevich group of the curve).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: S = E.sha()
        sage: S
        Tate-Shafarevich group for the Elliptic Curve
         defined by y^2 + y = x^3 - x over Rational Field
        sage: S.bound_kolyvagin()
        ([2], 1)

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> S = E.sha()
        >>> S
        Tate-Shafarevich group for the Elliptic Curve
         defined by y^2 + y = x^3 - x over Rational Field
        >>> S.bound_kolyvagin()
        ([2], 1)

  silverman_height_bound(algorithm='default')

    Return the Silverman height bound.

    This is a positive real (floating point) number B such that for all points \(P\) on the curve over any number field, \(|h(P) - \hat{h}(P)| \leq B\), where \(h(P)\) is the naive logarithmic height of \(P\) and \(\hat{h}(P)\) is the canonical height.

    INPUT:

    - `algorithm` – one of the following:

      - `'default'` (default) - compute using a Python implementation in Sage

      - `'mwrank'` – use a C++ implementation in the mwrank library

    Note

    - The CPS_height_bound is often better (i.e. smaller) than the Silverman bound, but it only applies for points over the base field, whereas the Silverman bound works over all number fields.

    - The Silverman bound is also fairly straightforward to compute over number fields, but isn’t implemented here.

    - Silverman’s paper is ‘The Difference Between the Weil Height and the Canonical Height on Elliptic Curves’, Math. Comp., Volume 55, Number 192, pages 723-743. We use a correction by Bremner with 0.973 replaced by 0.961, as explained in the source code to mwrank (htconst.cc).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.silverman_height_bound()
        4.825400758180918
        sage: E.silverman_height_bound(algorithm='mwrank')
        4.825400758180918
        sage: E.CPS_height_bound()
        0.16397076103046915

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.silverman_height_bound()
        4.825400758180918
        >>> E.silverman_height_bound(algorithm='mwrank')
        4.825400758180918
        >>> E.CPS_height_bound()
        0.16397076103046915

  supersingular_primes(B)

    Return a list of all supersingular primes for this elliptic curve up to and possibly including B.

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('11a')
        sage: e.aplist(20)
        [-2, -1, 1, -2, 1, 4, -2, 0]
        sage: e.supersingular_primes(1000)
        [2, 19, 29, 199, 569, 809]

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> e.aplist(Integer(20))
        [-2, -1, 1, -2, 1, 4, -2, 0]
        >>> e.supersingular_primes(Integer(1000))
        [2, 19, 29, 199, 569, 809]

    Sage

        sage: e = EllipticCurve('27a')
        sage: e.aplist(20)
        [0, 0, 0, -1, 0, 5, 0, -7]
        sage: e.supersingular_primes(97)
        [2, 5, 11, 17, 23, 29, 41, 47, 53, 59, 71, 83, 89]
        sage: e.ordinary_primes(97)
        [7, 13, 19, 31, 37, 43, 61, 67, 73, 79, 97]
        sage: e.supersingular_primes(3)
        [2]
        sage: e.supersingular_primes(2)
        [2]
        sage: e.supersingular_primes(1)
        []

    [Python]

        >>> from sage.all import *
        >>> e = EllipticCurve('27a')
        >>> e.aplist(Integer(20))
        [0, 0, 0, -1, 0, 5, 0, -7]
        >>> e.supersingular_primes(Integer(97))
        [2, 5, 11, 17, 23, 29, 41, 47, 53, 59, 71, 83, 89]
        >>> e.ordinary_primes(Integer(97))
        [7, 13, 19, 31, 37, 43, 61, 67, 73, 79, 97]
        >>> e.supersingular_primes(Integer(3))
        [2]
        >>> e.supersingular_primes(Integer(2))
        [2]
        >>> e.supersingular_primes(Integer(1))
        []

  tamagawa_exponent(p)

    The Tamagawa index of the elliptic curve at `p`.

    This is the index of the component group \(E(\QQ_p)/E^0(\QQ_p)\). It equals the Tamagawa number (as the component group is cyclic) except for types \(I_m^*\) (\(m\) even) when the group can be \(C_2 \times C_2\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('816a1')
        sage: E.tamagawa_number(2)
        4
        sage: E.tamagawa_exponent(2)
        2
        sage: E.kodaira_symbol(2)
        I2*

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('816a1')
        >>> E.tamagawa_number(Integer(2))
        4
        >>> E.tamagawa_exponent(Integer(2))
        2
        >>> E.kodaira_symbol(Integer(2))
        I2*

    Sage

        sage: E = EllipticCurve('200c4')
        sage: E.kodaira_symbol(5)
        I4*
        sage: E.tamagawa_number(5)
        4
        sage: E.tamagawa_exponent(5)
        2

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve('200c4')
        >>> E.kodaira_symbol(Integer(5))
        I4*
        >>> E.tamagawa_number(Integer(5))
        4
        >>> E.tamagawa_exponent(Integer(5))
        2

    See Issue #4715:

    Sage

        sage: E = EllipticCurve('117a3')
        sage: E.tamagawa_exponent(13)
        4

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('117a3')
        >>> E.tamagawa_exponent(Integer(13))
        4

  tamagawa_number(p)

    The Tamagawa number of the elliptic curve at `p`.

    This is the order of the component group \(E(\QQ_p)/E^0(\QQ_p)\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.tamagawa_number(11)
        5
        sage: E = EllipticCurve('37b')
        sage: E.tamagawa_number(37)
        3

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.tamagawa_number(Integer(11))
        5
        >>> E = EllipticCurve('37b')
        >>> E.tamagawa_number(Integer(37))
        3

  tamagawa_number_old(p)

    The Tamagawa number of the elliptic curve at `p`.

    This is the order of the component group \(E(\QQ_p)/E^0(\QQ_p)\).

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('11a')
        sage: E.tamagawa_number_old(11)
        5
        sage: E = EllipticCurve('37b')
        sage: E.tamagawa_number_old(37)
        3

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('11a')
        >>> E.tamagawa_number_old(Integer(11))
        5
        >>> E = EllipticCurve('37b')
        >>> E.tamagawa_number_old(Integer(37))
        3

  tamagawa_product()

    Return the product of the Tamagawa numbers.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('54a')
        sage: E.tamagawa_product ()
        3

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('54a')
        >>> E.tamagawa_product ()
        3

  tate_curve(p)

    Create the Tate curve over the \(p\)-adics associated to this elliptic curve.

    This Tate curve is a \(p\)-adic curve with split multiplicative reduction of the form \(y^2+xy=x^3+s_4 x+s_6\) which is isomorphic to the given curve over the algebraic closure of \(\QQ_p\). Its points over \(\QQ_p\) are isomorphic to \(\QQ_p^{\times}/q^{\ZZ}\) for a certain parameter \(q \in \ZZ_p\).

    INPUT:

    - `p` – a prime where the curve has split multiplicative reduction

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('130a1')
        sage: e.tate_curve(2)
        2-adic Tate curve associated to the Elliptic Curve
         defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('130a1')
        >>> e.tate_curve(Integer(2))
        2-adic Tate curve associated to the Elliptic Curve
         defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field

    The input curve must have multiplicative reduction at the prime.

    Sage

        sage: e.tate_curve(3)
        Traceback (most recent call last):
        ...
        ValueError: the elliptic curve must have multiplicative reduction at 3

    [Python]

        >>> from sage.all import *
        >>> e.tate_curve(Integer(3))
        Traceback (most recent call last):
        ...
        ValueError: the elliptic curve must have multiplicative reduction at 3

    We compute with \(p=5\):

    Sage

        sage: T = e.tate_curve(5); T
        5-adic Tate curve associated to the Elliptic Curve
         defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field

    Python

        >>> from sage.all import *
        >>> T = e.tate_curve(Integer(5)); T
        5-adic Tate curve associated to the Elliptic Curve
         defined by y^2 + x*y + y = x^3 - 33*x + 68 over Rational Field

    We find the Tate parameter \(q\):

    Sage

        sage: T.parameter(prec=5)
        3*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)

    [Python]

        >>> from sage.all import *
        >>> T.parameter(prec=Integer(5))
        3*5^3 + 3*5^4 + 2*5^5 + 2*5^6 + 3*5^7 + O(5^8)

    We compute the \(\mathcal{L}\)-invariant of the curve:

    Sage

        sage: T.L_invariant(prec=10)
        5^3 + 4*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 3*5^8 + 5^9 + O(5^10)

    Python

        >>> from sage.all import *
        >>> T.L_invariant(prec=Integer(10))
        5^3 + 4*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 3*5^8 + 5^9 + O(5^10)

  three_selmer_rank(algorithm='UseSUnits')

    Return the 3-selmer rank of this elliptic curve, computed using Magma.

    INPUT:

    - `algorithm` – ‘Heuristic’ (which is usually much faster in large examples), ‘FindCubeRoots’, or ‘UseSUnits’ (default)

    OUTPUT: nonnegative integer

    EXAMPLES: A rank 0 curve:

    Sage

        sage: EllipticCurve('11a').three_selmer_rank()       # optional - magma
        0

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a').three_selmer_rank()       # optional - magma
        0

    A rank 0 curve with rational 3-isogeny but no 3-torsion

    Sage

        sage: EllipticCurve('14a3').three_selmer_rank()      # optional - magma
        0

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve('14a3').three_selmer_rank()      # optional - magma
        0

    A rank 0 curve with rational 3-torsion:

    Sage

        sage: EllipticCurve('14a1').three_selmer_rank()      # optional - magma
        1

    Python

        >>> from sage.all import *
        >>> EllipticCurve('14a1').three_selmer_rank()      # optional - magma
        1

    A rank 1 curve with rational 3-isogeny:

    Sage

        sage: EllipticCurve('91b').three_selmer_rank()       # optional - magma
        2

    [Python]

        >>> from sage.all import *
        >>> EllipticCurve('91b').three_selmer_rank()       # optional - magma
        2

    A rank 0 curve with nontrivial 3-Sha. The Heuristic option makes this about twice as fast as without it.

    Sage

        sage: EllipticCurve('681b').three_selmer_rank(algorithm='Heuristic')   # long time (10 seconds); optional - magma
        2

    Python

        >>> from sage.all import *
        >>> EllipticCurve('681b').three_selmer_rank(algorithm='Heuristic')   # long time (10 seconds); optional - magma
        2

  torsion_order()

    Return the order of the torsion subgroup.

    EXAMPLES:

    Sage

        sage: e = EllipticCurve('11a')
        sage: e.torsion_order()
        5
        sage: type(e.torsion_order())
        <... 'sage.rings.integer.Integer'>
        sage: e = EllipticCurve([1,2,3,4,5])
        sage: e.torsion_order()
        1
        sage: type(e.torsion_order())
        <... 'sage.rings.integer.Integer'>

    Python

        >>> from sage.all import *
        >>> e = EllipticCurve('11a')
        >>> e.torsion_order()
        5
        >>> type(e.torsion_order())
        <... 'sage.rings.integer.Integer'>
        >>> e = EllipticCurve([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)])
        >>> e.torsion_order()
        1
        >>> type(e.torsion_order())
        <... 'sage.rings.integer.Integer'>

  torsion_points()

    Return the torsion points of this elliptic curve as a sorted list.

    OUTPUT: list of all the torsion points on this elliptic curve

    EXAMPLES:

    Sage

        sage: EllipticCurve('11a').torsion_points()
        [(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)]
        sage: EllipticCurve('37b').torsion_points()
        [(0 : 1 : 0), (8 : -19 : 1), (8 : 18 : 1)]

    Python

        >>> from sage.all import *
        >>> EllipticCurve('11a').torsion_points()
        [(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)]
        >>> EllipticCurve('37b').torsion_points()
        [(0 : 1 : 0), (8 : -19 : 1), (8 : 18 : 1)]

    Some curves with large torsion groups:

    Sage

        sage: E = EllipticCurve([-1386747, 368636886])
        sage: T = E.torsion_subgroup(); T
        Torsion Subgroup isomorphic to Z/8 + Z/2 associated to the
         Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over
         Rational Field
        sage: E.torsion_points()
        [(0 : 1 : 0),
         (-1293 : 0 : 1),
         (-933 : -29160 : 1),
         (-933 : 29160 : 1),
         (-285 : -27216 : 1),
         (-285 : 27216 : 1),
         (147 : -12960 : 1),
         (147 : 12960 : 1),
         (282 : 0 : 1),
         (1011 : 0 : 1),
         (1227 : -22680 : 1),
         (1227 : 22680 : 1),
         (2307 : -97200 : 1),
         (2307 : 97200 : 1),
         (8787 : -816480 : 1),
         (8787 : 816480 : 1)]
        sage: EllipticCurve('210b5').torsion_points()
        [(0 : 1 : 0),
         (-41/4 : 37/8 : 1),
         (-5 : -103 : 1),
         (-5 : 107 : 1),
         (10 : -208 : 1),
         (10 : 197 : 1),
         (37 : -397 : 1),
         (37 : 359 : 1),
         (100 : -1153 : 1),
         (100 : 1052 : 1),
         (415 : -8713 : 1),
         (415 : 8297 : 1)]
        sage: EllipticCurve('210e2').torsion_points()
        [(0 : 1 : 0),
         (-36 : 18 : 1),
         (-26 : -122 : 1),
         (-26 : 148 : 1),
         (-8 : -122 : 1),
         (-8 : 130 : 1),
         (4 : -62 : 1),
         (4 : 58 : 1),
         (31/4 : -31/8 : 1),
         (28 : -14 : 1),
         (34 : -122 : 1),
         (34 : 88 : 1),
         (64 : -482 : 1),
         (64 : 418 : 1),
         (244 : -3902 : 1),
         (244 : 3658 : 1)]

    [Python]

        >>> from sage.all import *
        >>> E = EllipticCurve([-Integer(1386747), Integer(368636886)])
        >>> T = E.torsion_subgroup(); T
        Torsion Subgroup isomorphic to Z/8 + Z/2 associated to the
         Elliptic Curve defined by y^2 = x^3 - 1386747*x + 368636886 over
         Rational Field
        >>> E.torsion_points()
        [(0 : 1 : 0),
         (-1293 : 0 : 1),
         (-933 : -29160 : 1),
         (-933 : 29160 : 1),
         (-285 : -27216 : 1),
         (-285 : 27216 : 1),
         (147 : -12960 : 1),
         (147 : 12960 : 1),
         (282 : 0 : 1),
         (1011 : 0 : 1),
         (1227 : -22680 : 1),
         (1227 : 22680 : 1),
         (2307 : -97200 : 1),
         (2307 : 97200 : 1),
         (8787 : -816480 : 1),
         (8787 : 816480 : 1)]
        >>> EllipticCurve('210b5').torsion_points()
        [(0 : 1 : 0),
         (-41/4 : 37/8 : 1),
         (-5 : -103 : 1),
         (-5 : 107 : 1),
         (10 : -208 : 1),
         (10 : 197 : 1),
         (37 : -397 : 1),
         (37 : 359 : 1),
         (100 : -1153 : 1),
         (100 : 1052 : 1),
         (415 : -8713 : 1),
         (415 : 8297 : 1)]
        >>> EllipticCurve('210e2').torsion_points()
        [(0 : 1 : 0),
         (-36 : 18 : 1),
         (-26 : -122 : 1),
         (-26 : 148 : 1),
         (-8 : -122 : 1),
         (-8 : 130 : 1),
         (4 : -62 : 1),
         (4 : 58 : 1),
         (31/4 : -31/8 : 1),
         (28 : -14 : 1),
         (34 : -122 : 1),
         (34 : 88 : 1),
         (64 : -482 : 1),
         (64 : 418 : 1),
         (244 : -3902 : 1),
         (244 : 3658 : 1)]

  two_descent(verbose=True, selmer_only=False, first_limit=20, second_limit=8, n_aux=-1, second_descent=1)

    Compute 2-descent data for this curve.

    INPUT:

    - `verbose` – boolean (default: `True`); print what mwrank is doing. If `False`, no output is printed.

    - `selmer_only` – boolean (default: `False`); selmer_only switch

    - `first_limit` – integer (default: 20); naive height bound on first point search on quartic homogeneous spaces (before testing local solubility; very simple search with no overheads).

    - `second_limit` – integer (default: 8); logarithmic height bound on second point search on quartic homogeneous spaces (after testing local solubility; sieve-assisted search)

    - `n_aux` – integer (default: -1); if positive, the number of auxiliary primes used in sieve-assisted search for quartics. If -1 (the default) use a default value (set in the eclib code in `src/qrank/mrank1.cc` in DEFAULT_NAUX: currently 8). Only relevant for curves with no 2-torsion, where full 2-descent is carried out. Worth increasing for curves expected to be of rank > 6 to one or two more than the expected rank.

    - `second_descent` – boolean (default: `True`); flag specifying whether or not a second descent will be carried out. Only relevant for curves with 2-torsion. Recommended left as the default except for experts interested in details of Selmer groups.

    OUTPUT:

    Return `True` if the descent succeeded, i.e. if the lower bound and the upper bound for the rank are the same. In this case, generators and the rank are cached. A return value of `False` indicates that either rational points were not found, or that Sha[2] is nontrivial and mwrank was unable to determine this for sure.

    EXAMPLES:

    Sage

        sage: E = EllipticCurve('37a1')
        sage: E.two_descent(verbose=False)
        True

    Python

        >>> from sage.all import *
        >>> E = EllipticCurve('37a1')
        >>> E.two_descent(verbose=False)
        True

sage.schemes.elliptic_curves.ell_rational_field.cremona_curves(conductors)

  Return iterator over all known curves (in database) with conductor in the list of conductors.

  EXAMPLES:

  Sage

      sage: [(E.label(), E.rank()) for E in cremona_curves(srange(35,40))]
      [('35a1', 0),
       ('35a2', 0),
       ('35a3', 0),
       ('36a1', 0),
       ('36a2', 0),
       ('36a3', 0),
       ('36a4', 0),
       ('37a1', 1),
       ('37b1', 0),
       ('37b2', 0),
       ('37b3', 0),
       ('38a1', 0),
       ('38a2', 0),
       ('38a3', 0),
       ('38b1', 0),
       ('38b2', 0),
       ('39a1', 0),
       ('39a2', 0),
       ('39a3', 0),
       ('39a4', 0)]

  Python

      >>> from sage.all import *
      >>> [(E.label(), E.rank()) for E in cremona_curves(srange(Integer(35),Integer(40)))]
      [('35a1', 0),
       ('35a2', 0),
       ('35a3', 0),
       ('36a1', 0),
       ('36a2', 0),
       ('36a3', 0),
       ('36a4', 0),
       ('37a1', 1),
       ('37b1', 0),
       ('37b2', 0),
       ('37b3', 0),
       ('38a1', 0),
       ('38a2', 0),
       ('38a3', 0),
       ('38b1', 0),
       ('38b2', 0),
       ('39a1', 0),
       ('39a2', 0),
       ('39a3', 0),
       ('39a4', 0)]

sage.schemes.elliptic_curves.ell_rational_field.cremona_optimal_curves(conductors)

  Return iterator over all known optimal curves (in database) with conductor in the list of conductors.

  EXAMPLES:

  Sage

      sage: [(E.label(), E.rank()) for E in cremona_optimal_curves(srange(35,40))]
      [('35a1', 0),
       ('36a1', 0),
       ('37a1', 1),
       ('37b1', 0),
       ('38a1', 0),
       ('38b1', 0),
       ('39a1', 0)]

  Python

      >>> from sage.all import *
      >>> [(E.label(), E.rank()) for E in cremona_optimal_curves(srange(Integer(35),Integer(40)))]
      [('35a1', 0),
       ('36a1', 0),
       ('37a1', 1),
       ('37b1', 0),
       ('38a1', 0),
       ('38b1', 0),
       ('39a1', 0)]

  There is one case – 990h3 – when the optimal curve isn’t labeled with a 1:

  Sage

      sage: [e.cremona_label() for e in cremona_optimal_curves([990])]
      ['990a1', '990b1', '990c1', '990d1', '990e1', '990f1', '990g1',
       '990h3', '990i1', '990j1', '990k1', '990l1']

  [Python]

      >>> from sage.all import *
      >>> [e.cremona_label() for e in cremona_optimal_curves([Integer(990)])]
      ['990a1', '990b1', '990c1', '990d1', '990e1', '990f1', '990g1',
       '990h3', '990i1', '990j1', '990k1', '990l1']

sage.schemes.elliptic_curves.ell_rational_field.elliptic_curve_congruence_graph(curves)

  Return the congruence graph for this set of elliptic curves.

  INPUT:

  - `curves` – list of elliptic curves

  OUTPUT:

  The graph with each curve as a vertex (labelled by its Cremona label) and an edge from \(E\) to \(F\) labelled \(p\) if and only if \(E\) is congruent to \(F\) mod \(p\).

  EXAMPLES:

  Sage

      sage: from sage.schemes.elliptic_curves.ell_rational_field import elliptic_curve_congruence_graph
      sage: curves = list(cremona_optimal_curves([11..30]))
      sage: G = elliptic_curve_congruence_graph(curves)
      sage: G
      Graph on 12 vertices

  Python

      >>> from sage.all import *
      >>> from sage.schemes.elliptic_curves.ell_rational_field import elliptic_curve_congruence_graph
      >>> curves = list(cremona_optimal_curves((ellipsis_range(Integer(11),Ellipsis,Integer(30)))))
      >>> G = elliptic_curve_congruence_graph(curves)
      >>> G
      Graph on 12 vertices

sage.schemes.elliptic_curves.ell_rational_field.integral_points_with_bounded_mw_coeffs(E, mw_base, N, x_bound)

  Return the set of integers \(x\) which are \(x\)-coordinates of points on the curve \(E\) which are linear combinations of the generators (basis and torsion points) with coefficients bounded by \(N\).

  INPUT:

  - `E` – an elliptic curve

  - `mw_base` – list of points on \(E\) (generators)

  - `N` – positive integer (bound on coefficients)

  - `x_bound` – a positive real number (upper bound on size of x-coordinates)

  OUTPUT:

  list of integral points on \(E\) which are linear combinations of the given points with coefficients bounded by \(N\) in absolute value.