Skip to content

Commit 86d2be0

Browse files
author
Release Manager
committed
gh-35626: Update the rank function of elliptic curves to use ellrank 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
2 parents fe931a7 + 0f8b28a commit 86d2be0

File tree

2 files changed

+274
-56
lines changed

2 files changed

+274
-56
lines changed

src/sage/schemes/elliptic_curves/BSD.py

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from sage.arith.misc import prime_divisors
55
from sage.rings.integer_ring import ZZ
6+
from sage.rings.rational_field import QQ
67
from sage.rings.infinity import Infinity
78
from sage.rings.number_field.number_field import QuadraticField
89
from sage.functions.other import ceil
@@ -89,11 +90,17 @@ def simon_two_descent_work(E, two_tor_rk):
8990
sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work
9091
sage: E = EllipticCurve('14a')
9192
sage: simon_two_descent_work(E, E.two_torsion_rank())
93+
doctest:warning
94+
...
95+
DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.
96+
See https://github.com/sagemath/sage/issues/35621 for details.
9297
(0, 0, 0, 0, [])
9398
sage: E = EllipticCurve('37a')
9499
sage: simon_two_descent_work(E, E.two_torsion_rank())
95100
(1, 1, 0, 0, [(0 : 0 : 1)])
96101
"""
102+
from sage.misc.superseded import deprecation
103+
deprecation(35621, 'Use the two-descent in pari instead, as this script has been ported over to pari.')
97104
rank_lower_bd, two_sel_rk, gens = E.simon_two_descent()
98105
rank_upper_bd = two_sel_rk - two_tor_rk
99106
gens = [P for P in gens if P.additive_order() == Infinity]
@@ -140,6 +147,55 @@ def mwrank_two_descent_work(E, two_tor_rk):
140147
sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd
141148
return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens
142149

150+
def pari_two_descent_work(E):
151+
r"""
152+
Prepare the output from pari by two-isogeny.
153+
154+
INPUT:
155+
156+
- ``E`` -- an elliptic curve
157+
158+
OUTPUT: A tuple of 5 elements with the first 4 being integers.
159+
160+
- a lower bound on the rank
161+
162+
- an upper bound on the rank
163+
164+
- a lower bound on the rank of Sha[2]
165+
166+
- an upper bound on the rank of Sha[2]
167+
168+
- a list of the generators found
169+
170+
EXAMPLES::
171+
172+
sage: from sage.schemes.elliptic_curves.BSD import pari_two_descent_work
173+
sage: E = EllipticCurve('14a')
174+
sage: pari_two_descent_work(E)
175+
(0, 0, 0, 0, [])
176+
sage: E = EllipticCurve('37a')
177+
sage: pari_two_descent_work(E) # random, up to sign
178+
(1, 1, 0, 0, [(0 : -1 : 1)])
179+
sage: E = EllipticCurve('210e7')
180+
sage: pari_two_descent_work(E)
181+
(0, 2, 0, 2, [])
182+
sage: E = EllipticCurve('66b3')
183+
sage: pari_two_descent_work(E)
184+
(0, 0, 2, 2, [])
185+
186+
"""
187+
ep = E.pari_curve()
188+
lower, rank_upper_bd, s, pts = ep.ellrank()
189+
gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts])
190+
gens = E.saturation(gens)[0]
191+
# this is explained in the pari-gp documentation:
192+
# s is the dimension of Sha[2]/2Sha[4],
193+
# which is a lower bound for dim Sha[2]
194+
# dim Sha[2] = dim Sel2 - rank E(Q) - dim tors
195+
# rank_upper_bd = dim Sel_2 - dim tors - s
196+
sha_upper_bd = rank_upper_bd - len(gens) + s
197+
return len(gens), rank_upper_bd, s, sha_upper_bd, gens
198+
143199

144200
def native_two_isogeny_descent_work(E, two_tor_rk):
145201
"""
@@ -254,7 +310,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
254310
- 2: print information about remaining primes
255311
256312
- ``two_desc`` -- string (default ``'mwrank'``), what to use for the
257-
two-descent. Options are ``'mwrank', 'simon', 'sage'``
313+
two-descent. Options are ``'mwrank', 'pari', 'sage'``
258314
259315
- ``proof`` -- bool or None (default: None, see
260316
proof.elliptic_curve or sage.structure.proof). If False, this
@@ -317,7 +373,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
317373
True for p = 3 by Kolyvagin bound
318374
True for p = 5 by Kolyvagin bound
319375
[]
320-
sage: E.prove_BSD(two_desc='simon')
376+
sage: E.prove_BSD(two_desc='pari')
321377
[]
322378
323379
A rank two curve::
@@ -433,6 +489,15 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
433489
p = 2: True by 2-descent
434490
True for p not in {2} by Kolyvagin.
435491
[]
492+
493+
::
494+
495+
sage: E = EllipticCurve('66b3')
496+
sage: E.prove_BSD(two_desc="pari",verbosity=1)
497+
p = 2: True by 2-descent
498+
True for p not in {2} by Kolyvagin.
499+
[]
500+
436501
"""
437502
if proof is None:
438503
from sage.structure.proof.proof import get_flag
@@ -461,8 +526,8 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5,
461526

462527
if two_desc == 'mwrank':
463528
M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk)
464-
elif two_desc == 'simon':
465-
M = simon_two_descent_work(BSD.curve, BSD.two_tor_rk)
529+
elif two_desc == 'pari':
530+
M = pari_two_descent_work(BSD.curve)
466531
elif two_desc == 'sage':
467532
M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk)
468533
else:

0 commit comments

Comments
 (0)