Calculating the rank of an elliptic curve

Solution 1:

The following code initializes the curve,

a1 = 0
a2 = 1385517326399
a3 = 0
a4 = 122858128750077837043200
a6 = 2723553057107893845651798389990400

E = EllipticCurve([a1, a2, a3, a4, a6])

print(E)

and the print confirms that we have what we want in our hands:

y^2 = x^3 + 1385517326399*x^2 
          + 122858128750077837043200*x
          + 2723553057107893845651798389990400

(Result was manually rearranged.)

Then the call E.rank() was also running into an error on my older machine, the last traceback lines being:

     43 
     44 cdef void NTL_error_callback(const char* s) except *:
---> 45     raise NTLError(char_to_str(s))
     46 
     47 

NTLError: RR: division by zero

However note that the error comes from running the do_descent method, in my case:

/usr/lib/python3.9/site-packages/sage/libs/eclib/interface.py in two_descent(self, verbose, selmer_only, first_limit, second_limit, n_aux, second_descent)
    378         #   (since otherwise mwrank just sets limit tiny)
    379         self.__descent = _two_descent()
--> 380         self.__descent.do_descent(self.__curve,
    381                                       verbose,
    382                                       selmer_only,

and inside it the error happens in a cimport piece of code in sig_on(). So we outside python and cannot traceback it any longer.


Also, trying for instance a related method:

E.two_descent(second_limit=11)

we get verbose information on what is going on, and also this call runs into an error, but we know somehow closer where it happens:

-------------------------------------------------------
2. E'(Q)/phi'(E(Q))
-------------------------------------------------------
First stage (no second descent yet)...
(887753905,0,-2542826149054,0,1722641177203345):  no rational point found (hlim=8)
After first global descent, this component of the rank
    has lower bound 0
    and upper bound 1
    (difference =   1)
Second descent will attempt to reduce this
Second stage (using second descent)...
d1=887753905: ---------------------------------------------------------------------------
NTLError                                  Traceback (most recent call last)
<ipython-input-10-99fadbf96833> in <module>
----> 1 E.two_descent(second_limit=Integer(11))


But well, note that we always we have at least:

sage: E.simon_two_descent()
(2, 8, [(-91824010798 : 48478807884801502 : 1)])
sage: E.rank_bounds()
(2, 6)

These are some rough bounds for the rank. And there is also a rational point found on the curve:

sage: P = E.point([-91824010798, 48478807884801502])
sage: P.order()
+Infinity
sage: P.height()
6.53112831073560*

A final remark. We have an elliptic curve constructed by a receipt - as described in the comments, involving big coefficients

sage: factor(x^3 + 1385517326399*x^2 + 122858128750077837043200*x + 2723553057107893845651798389990400)
(x + 1292061882720)*(x + 55420693055)*(x + 38034750624)

and with prescribed torsion points as above. We may still be lucky with one rational point of infinite order. But given the size of the coefficients, the effort to get the rank (and the generators, and all descent data) is in some disproportion to profit we get when we know the answer. What can we do with this virtual answer?

For the "smaller" curves covered by the same receipt we have ranks $1,2,3$. And which is for instance the profit when knowing the rank of the curve which is previous in the list...?

sage: E5 = EllipticCurve([0, 35343024, 0, 79944226084800, 45207500520241382400])
sage: E5.rank()
2
sage: E5.gens()
[(-903538152/49 : -22540454171136/343 : 1),
 (-6408468920/961 : -835866977892800/29791 : 1)]

Solution 2:

I have managed to resolve the rank of this particular elliptic curve. For those who are interested here is a proof that the rank of $E/\mathbb{Q}$ is $2$. The process is complicated both by the fact that $2$-torsion in the Shafarevich-Tate group of $E$ is nontrivial and that the generators for $E$ have rather heinous height.

I have to apologise to the OP - I couldn't prove this in Sage, since rather a lot of the required tools are only available in Magma. So for a proof, here we go:

Recall the standard descent exact sequence $$ 0 \to E(\mathbb{Q})/2E(\mathbb{Q}) \to Sel^2(E/\mathbb{Q}) \to TS(E/\mathbb{Q})[2] \to 0$$

Here $TS(E/\mathbb{Q})$ is denoting the Shafarevich-Tate group of $E/\mathbb{Q}$.

As remarked by dan_fulea in his answer, we can perform a $2$-descent on $E$ (this is actually not so hard since $E$ has full $2$-torsion we don't have to do any computations in extensions). This is implemented in Magma as TwoDescent(E).

We see that the $2$-rank of $Sel^2(E/\mathbb{Q})$ is $6$, but some of that is coming from the $2$-torsion in $E$. Indeed the quotient of $Sel^2(E/\mathbb{Q})$ by $E(\mathbb{Q})[2]$ has $2$-rank $4$. So at least we have an easy upper bound on the rank of $4$.

I now claim that $TS(E/\mathbb{Q})[2]$ has $2$-rank $2$.

We now turn to the fact that by doing a $2$-descent we ended up with $16$ two-coverings representing elements of $Sel^2(E/\mathbb{Q})$ modulo $E(\mathbb{Q})[2]$. We know that a pair of such $2$-coverings $C, D \in Sel^2(E/\mathbb{Q})$ pair to $1$ under the Cassels-Tate pairing $$Sel^2(E/\mathbb{Q}) \times Sel^2(E/\mathbb{Q}) \to \mathbb{Z}/2\mathbb{Z}$$ then both $C$ and $D$ represent nontrivial elements of $TS(E/\mathbb{Q})[2]$ (implicitly we are relying here on the conjectural finiteness of $TS(E/\mathbb{Q})$ - we'll remove this later)$.

By the Magma implementation CasselsTatePairing on $2$-coverings we find that all but four elements of $Sel^2(E/\mathbb{Q})$ map to nontrivial elements of $TS(E/\mathbb{Q})[2]$.

It therefore remains to find two linearly independent elements of the free part of $E(\mathbb{Q})$.

This is a little tricky. Of the three nontrivial $2$-coverings which we don't suspect represent nontrivial elements of $TS(E/\mathbb{Q})[2]$ one has an "obvious" (to a computer) point - mapping this back to $E$ gives the generator noted by dan_fulea, namely $$(-91824010798 : -48478807884801502 : 1)$$

I tried searching, but came up empty on the remaining $2$-coverings. The trick now is to try a $4$-descent and try to search for points on the four coverings. Hence for one of the remaining two $2$-coverings we perform a $4$-descent and find a bunch of quadric intersections on which we can search for points. By the most naive approach of "search to increasingly large height" we find the point $$\left( \frac{-404815020562025920469222824465732539146371105350282919301689649295373102255}{11168457996343790621407117988969509363127104837463541266529052816} : \frac{7745601033476969490079390610408893368338650005748425084236397941557595630641095312826717436633265016034026711375}{1180292976500173572748600997479332385461657284253729082801582412268783253837038991468707187676864} : 1 \right)$$ on $E$.

By construction these points map to different elements of $Sel^2(E/\mathbb{Q})$ so are independent.

Finally we note that it is possible to prove (unconditionally) that the size of $TS(E/\mathbb{Q})[2]$ is $4$ by performing a $4$-descent on the $2$-coverings which represent nontrivial elements.

We conclude the rank of $E(\mathbb{Q})$ is $2$.

Code to verify this is below:

a1 := 0;
a2 := 1385517326399;
a3 := 0;
a4 := 122858128750077837043200;
a6 := 2723553057107893845651798389990400;

E := EllipticCurve([a1, a2, a3, a4, a6]);

covers, maps := TwoDescent(E : RemoveTorsion:=true);
assert CasselsTatePairing(covers[1], covers[2]) eq 1;

sha := [covers[1]]; //can put this is by above assertion
for c in covers do
    r := CasselsTatePairing(covers[1], c);
    if r eq 1 then
        Append(~sha, c); //if it hits something nontrivial in sha we put it in here
    end if;
end for;

for c in [c : c in covers | not c in sha] do
    r := CasselsTatePairing(sha[2], c);
    if r eq 1 then
        Append(~sha, c);
    end if;
end for;

for c in [c : c in covers | not c in sha] do
    r := CasselsTatePairing(sha[3], c);
    if r eq 1 then
        Append(~sha, c);
    end if;
end for;

our_EQ := [c : c in covers | not c in sha] ;
assert #our_EQ eq 3; //these are our 3 nontrivial 2-coverings which we suspect have points

i1 := Index(covers, our_EQ[1]);

p := Points(our_EQ[1] : Bound:=10)[1];
p1 := maps[i1](p); p1; //first point

fourcovers := FourDescent(our_EQ[2]);
C := fourcovers[5]; //you may need to change this [5] the fourcovers aren't the same every time

p := PointsQI(C, 10^7)[1];
_,m := AssociatedEllipticCurve(C : E:=E );
p2 := m(p); p2; //second point

//finally we make this all unconditional
shacovers, _ := TwoDescent(E : RemoveTorsion:=true, RemoveGens:={p1,p2});

for c in shacovers do
    assert #FourDescent(c) eq 0; //represents a nontrivial element of sha
end for;