Skip to content

Commit

Permalink
gh-35626: Update the rank function of elliptic curves to use ellrank …
Browse files Browse the repository at this point in the history
…in pari

    
### 📚 Description

Fixes #35621

Pari has now a very good in-built algorithm to determine the rank and a
set of generators of the Mordell-Weil group of elliptic curves over the
rational. It is, as far as I understand, a port of Denis Simon's script
ellQ.gp. It performs a 2-descent and uses the Cassels Tate pairing to
conclude the rank in many cases - when Sha has no 4-torsion elements.
The functionality to search rational points is also very quick.



### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- `[x]` The title is concise, informative, and self-explanatory.
- `[x]` The description explains in detail what this PR is about.
- `[x]` I have linked a relevant issue or discussion.
- `[x]` I have created tests covering the changes.
- `[x]` I have updated the documentation accordingly.


### ⌛ Dependencies

- #35614 a pull request that fixes, among other things,  the
documentation in the files changed here.
  To avoid problems, I based it on that PR.

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: #35626
Reported by: Chris Wuthrich
Reviewer(s): Chris Wuthrich, John Cremona, Lorenz Panny
  • Loading branch information
Release Manager committed Jun 7, 2023
2 parents fe931a7 + 0f8b28a commit 86d2be0
Show file tree
Hide file tree
Showing 2 changed files with 274 additions and 56 deletions.
73 changes: 69 additions & 4 deletions src/sage/schemes/elliptic_curves/BSD.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from sage.arith.misc import prime_divisors
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.infinity import Infinity
from sage.rings.number_field.number_field import QuadraticField
from sage.functions.other import ceil
Expand Down Expand Up @@ -89,11 +90,17 @@ def simon_two_descent_work(E, two_tor_rk):
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.misc.superseded import deprecation
deprecation(35621, 'Use the two-descent in pari instead, as this script has been ported over to pari.')
rank_lower_bd, two_sel_rk, gens = E.simon_two_descent()
rank_upper_bd = two_sel_rk - two_tor_rk
gens = [P for P in gens if P.additive_order() == Infinity]
Expand Down Expand Up @@ -140,6 +147,55 @@ def mwrank_two_descent_work(E, two_tor_rk):
sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd
return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens

def pari_two_descent_work(E):
r"""
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, [])
"""
ep = E.pari_curve()
lower, rank_upper_bd, s, pts = ep.ellrank()
gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts])
gens = E.saturation(gens)[0]
# this is explained in the pari-gp documentation:
# s is the dimension of Sha[2]/2Sha[4],
# which is a lower bound for dim Sha[2]
# dim Sha[2] = dim Sel2 - rank E(Q) - dim tors
# rank_upper_bd = dim Sel_2 - dim tors - s
sha_upper_bd = rank_upper_bd - len(gens) + s
return len(gens), rank_upper_bd, s, sha_upper_bd, gens


def native_two_isogeny_descent_work(E, two_tor_rk):
"""
Expand Down Expand Up @@ -254,7 +310,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
- 2: print information about remaining primes
- ``two_desc`` -- string (default ``'mwrank'``), what to use for the
two-descent. Options are ``'mwrank', 'simon', 'sage'``
two-descent. Options are ``'mwrank', 'pari', 'sage'``
- ``proof`` -- bool or None (default: None, see
proof.elliptic_curve or sage.structure.proof). If False, this
Expand Down Expand Up @@ -317,7 +373,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
True for p = 3 by Kolyvagin bound
True for p = 5 by Kolyvagin bound
[]
sage: E.prove_BSD(two_desc='simon')
sage: E.prove_BSD(two_desc='pari')
[]
A rank two curve::
Expand Down Expand Up @@ -433,6 +489,15 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
p = 2: True by 2-descent
True for p not in {2} by Kolyvagin.
[]
::
sage: E = EllipticCurve('66b3')
sage: E.prove_BSD(two_desc="pari",verbosity=1)
p = 2: True by 2-descent
True for p not in {2} by Kolyvagin.
[]
"""
if proof is None:
from sage.structure.proof.proof import get_flag
Expand Down Expand Up @@ -461,8 +526,8 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,

if two_desc == 'mwrank':
M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk)
elif two_desc == 'simon':
M = simon_two_descent_work(BSD.curve, BSD.two_tor_rk)
elif two_desc == 'pari':
M = pari_two_descent_work(BSD.curve)
elif two_desc == 'sage':
M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk)
else:
Expand Down
Loading

0 comments on commit 86d2be0

Please sign in to comment.