Birch and Swinnerton-Dyer formulas

class sage.schemes.elliptic_curves.BSD.BSD_data[source]

Bases: object

Helper class used to keep track of information in proving BSD.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import BSD_data
sage: D = BSD_data()
sage: D.Sha is None
True
sage: D.curve=EllipticCurve('11a')
sage: D.update()
sage: D.Sha
Tate-Shafarevich group for the Elliptic Curve
 defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import BSD_data
>>> D = BSD_data()
>>> D.Sha is None
True
>>> D.curve=EllipticCurve('11a')
>>> D.update()
>>> D.Sha
Tate-Shafarevich group for the Elliptic Curve
 defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
from sage.schemes.elliptic_curves.BSD import BSD_data
D = BSD_data()
D.Sha is None
D.curve=EllipticCurve('11a')
D.update()
D.Sha
update()[source]

Update some properties from curve.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import BSD_data
sage: D = BSD_data()
sage: D.Sha is None
True
sage: D.curve = EllipticCurve('11a')
sage: D.update()
sage: D.Sha
Tate-Shafarevich group for the Elliptic Curve
 defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import BSD_data
>>> D = BSD_data()
>>> D.Sha is None
True
>>> D.curve = EllipticCurve('11a')
>>> D.update()
>>> D.Sha
Tate-Shafarevich group for the Elliptic Curve
 defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
from sage.schemes.elliptic_curves.BSD import BSD_data
D = BSD_data()
D.Sha is None
D.curve = EllipticCurve('11a')
D.update()
D.Sha
sage.schemes.elliptic_curves.BSD.heegner_index_work(E)[source]

Prepare the input and output for computing the heegner index.

INPUT:

  • E – an elliptic curve

OUTPUT:

  • a Heegner index

  • the discriminant used

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import heegner_index_work
sage: heegner_index_work(EllipticCurve('14a'))
(1, -31)
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import heegner_index_work
>>> heegner_index_work(EllipticCurve('14a'))
(1, -31)
from sage.schemes.elliptic_curves.BSD import heegner_index_work
heegner_index_work(EllipticCurve('14a'))
sage.schemes.elliptic_curves.BSD.mwrank_two_descent_work(E, two_tor_rk)[source]

Prepare the output from mwrank two-descent.

INPUT:

  • E – an elliptic curve

  • two_tor_rk – its two-torsion rank

OUTPUT:

  • a lower bound on the rank

  • an upper bound on the rank

  • a lower bound on the rank of Sha[2]

  • an upper bound on the rank of Sha[2]

  • a list of the generators found

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import mwrank_two_descent_work
sage: E = EllipticCurve('14a')
sage: mwrank_two_descent_work(E, E.two_torsion_rank())
(0, 0, 0, 0, [])
sage: E = EllipticCurve('37a')
sage: mwrank_two_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, [(0 : -1 : 1)])
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import mwrank_two_descent_work
>>> E = EllipticCurve('14a')
>>> mwrank_two_descent_work(E, E.two_torsion_rank())
(0, 0, 0, 0, [])
>>> E = EllipticCurve('37a')
>>> mwrank_two_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, [(0 : -1 : 1)])
from sage.schemes.elliptic_curves.BSD import mwrank_two_descent_work
E = EllipticCurve('14a')
mwrank_two_descent_work(E, E.two_torsion_rank())
E = EllipticCurve('37a')
mwrank_two_descent_work(E, E.two_torsion_rank())
sage.schemes.elliptic_curves.BSD.native_two_isogeny_descent_work(E, two_tor_rk)[source]

Prepare the output from two-descent by two-isogeny.

INPUT:

  • E – an elliptic curve

  • two_tor_rk – its two-torsion rank

OUTPUT:

  • a lower bound on the rank

  • an upper bound on the rank

  • a lower bound on the rank of Sha[2]

  • an upper bound on the rank of Sha[2]

  • a list of the generators found (currently None, since we don’t store them)

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import native_two_isogeny_descent_work
sage: E = EllipticCurve('14a')
sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())
(0, 0, 0, 0, None)
sage: E = EllipticCurve('65a')
sage: native_two_isogeny_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, None)
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import native_two_isogeny_descent_work
>>> E = EllipticCurve('14a')
>>> native_two_isogeny_descent_work(E, E.two_torsion_rank())
(0, 0, 0, 0, None)
>>> E = EllipticCurve('65a')
>>> native_two_isogeny_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, None)
from sage.schemes.elliptic_curves.BSD import native_two_isogeny_descent_work
E = EllipticCurve('14a')
native_two_isogeny_descent_work(E, E.two_torsion_rank())
E = EllipticCurve('65a')
native_two_isogeny_descent_work(E, E.two_torsion_rank())
sage.schemes.elliptic_curves.BSD.pari_two_descent_work(E)[source]

Prepare the output from pari by two-isogeny.

INPUT:

  • E – an elliptic curve

OUTPUT: a tuple of 5 elements with the first 4 being integers

  • a lower bound on the rank

  • an upper bound on the rank

  • a lower bound on the rank of Sha[2]

  • an upper bound on the rank of Sha[2]

  • a list of the generators found

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import pari_two_descent_work
sage: E = EllipticCurve('14a')
sage: pari_two_descent_work(E)
(0, 0, 0, 0, [])
sage: E = EllipticCurve('37a')
sage: pari_two_descent_work(E) # random, up to sign
(1, 1, 0, 0, [(0 : -1 : 1)])
sage: E = EllipticCurve('210e7')
sage: pari_two_descent_work(E)
(0, 2, 0, 2, [])
sage: E = EllipticCurve('66b3')
sage: pari_two_descent_work(E)
(0, 0, 2, 2, [])
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import pari_two_descent_work
>>> E = EllipticCurve('14a')
>>> pari_two_descent_work(E)
(0, 0, 0, 0, [])
>>> E = EllipticCurve('37a')
>>> pari_two_descent_work(E) # random, up to sign
(1, 1, 0, 0, [(0 : -1 : 1)])
>>> E = EllipticCurve('210e7')
>>> pari_two_descent_work(E)
(0, 2, 0, 2, [])
>>> E = EllipticCurve('66b3')
>>> pari_two_descent_work(E)
(0, 0, 2, 2, [])
from sage.schemes.elliptic_curves.BSD import pari_two_descent_work
E = EllipticCurve('14a')
pari_two_descent_work(E)
E = EllipticCurve('37a')
pari_two_descent_work(E) # random, up to sign
E = EllipticCurve('210e7')
pari_two_descent_work(E)
E = EllipticCurve('66b3')
pari_two_descent_work(E)
sage.schemes.elliptic_curves.BSD.prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, return_BSD=False)[source]

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:

EXAMPLES:

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')
[]
>>> 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')
[]
EllipticCurve('11a').prove_BSD(verbosity=2)
EllipticCurve('14a').prove_BSD(verbosity=2)
E = EllipticCurve("20a1")
E.prove_BSD(verbosity=2)
E = EllipticCurve("50b1")
E.prove_BSD(verbosity=2)
E.prove_BSD(two_desc='pari')

A rank two curve:

sage: E = EllipticCurve('389a')
>>> from sage.all import *
>>> E = EllipticCurve('389a')
E = EllipticCurve('389a')

We know nothing with proof=True:

sage: E.prove_BSD()
Set of all prime numbers: 2, 3, 5, 7, ...
>>> from sage.all import *
>>> E.prove_BSD()
Set of all prime numbers: 2, 3, 5, 7, ...
E.prove_BSD()

We (think we) know everything with proof=False:

sage: E.prove_BSD(proof=False)
[]
>>> from sage.all import *
>>> E.prove_BSD(proof=False)
[]
E.prove_BSD(proof=False)

A curve of rank 0 and prime conductor:

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.
>>> 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.
E = EllipticCurve('19a')
E.prove_BSD(verbosity=2)
E = EllipticCurve('37a')
E.rank()
E._EllipticCurve_rational_field__rank
E.analytic_rank = lambda : 0
E.prove_BSD()

We test the consistency check for the 2-part of Sha:

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
>>> 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
E = EllipticCurve('37a')
S = E.sha(); S
def foo(use_database):
 return 4
S.an = foo
E.prove_BSD()

An example with a Tamagawa number at 5:

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
[]
>>> 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
[]
E = EllipticCurve('123a1')
E.prove_BSD(verbosity=2)

A curve for which 3 divides the order of the Tate-Shafarevich group:

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]
>>> 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]
E = EllipticCurve('681b')
E.prove_BSD(verbosity=2)               # long time

A curve for which we need to use heegner_index_bound:

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]
>>> 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]
E = EllipticCurve('198b')
E.prove_BSD(verbosity=1, secs_hi=1)

The return_BSD option gives an object with detailed information about the proof:

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}
>>> 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}
E = EllipticCurve('26b')
B = E.prove_BSD(return_BSD=True)
B.two_tor_rk
B.N
B.gens
B.primes
B.heegner_indexes
sage.schemes.elliptic_curves.BSD.simon_two_descent_work(E, two_tor_rk)[source]

Prepare the output from Simon two-descent.

INPUT:

  • E – an elliptic curve

  • two_tor_rk – its two-torsion rank

OUTPUT:

  • a lower bound on the rank

  • an upper bound on the rank

  • a lower bound on the rank of Sha[2]

  • an upper bound on the rank of Sha[2]

  • a list of the generators found

EXAMPLES:

sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work
sage: E = EllipticCurve('14a')
sage: simon_two_descent_work(E, E.two_torsion_rank())
doctest:warning
...
DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.
See https://github.com/sagemath/sage/issues/35621 for details.
...
(0, 0, 0, 0, [])
sage: E = EllipticCurve('37a')
sage: simon_two_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, [(0 : 0 : 1)])
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.BSD import simon_two_descent_work
>>> E = EllipticCurve('14a')
>>> simon_two_descent_work(E, E.two_torsion_rank())
doctest:warning
...
DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.
See https://github.com/sagemath/sage/issues/35621 for details.
...
(0, 0, 0, 0, [])
>>> E = EllipticCurve('37a')
>>> simon_two_descent_work(E, E.two_torsion_rank())
(1, 1, 0, 0, [(0 : 0 : 1)])
from sage.schemes.elliptic_curves.BSD import simon_two_descent_work
E = EllipticCurve('14a')
simon_two_descent_work(E, E.two_torsion_rank())
E = EllipticCurve('37a')
simon_two_descent_work(E, E.two_torsion_rank())