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 curvetwo_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 curvetwo_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
, returning a list of primes 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
.”INPUT:
E
– an elliptic curveverbosity
– integer; how much information about the proof to print0: 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 orNone
(default: None, see proof.elliptic_curve or sage.structure.proof). IfFalse
, 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 curvetwo_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())