Descent on elliptic curves over \(\QQ\) with a 2-isogeny

sage.schemes.elliptic_curves.descent_two_isogeny.test_els(a, b, c, d, e)[source]

Doctest function for cdef int everywhere_locally_soluble(mpz_t, mpz_t, mpz_t, mpz_t, mpz_t).

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import test_els
sage: for _ in range(1000):
....:     a,b,c,d,e = randint(1,1000), randint(1,1000), randint(1,1000), randint(1,1000), randint(1,1000)
....:     if pari.Pol([a,b,c,d,e]).hyperellratpoints(1000, 1):
....:         try:
....:             if not test_els(a,b,c,d,e):
....:                 print("This never happened", a, b, c, d, e)
....:         except ValueError:
....:             continue
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import test_els
>>> for _ in range(Integer(1000)):
...     a,b,c,d,e = randint(Integer(1),Integer(1000)), randint(Integer(1),Integer(1000)), randint(Integer(1),Integer(1000)), randint(Integer(1),Integer(1000)), randint(Integer(1),Integer(1000))
...     if pari.Pol([a,b,c,d,e]).hyperellratpoints(Integer(1000), Integer(1)):
...         try:
...             if not test_els(a,b,c,d,e):
...                 print("This never happened", a, b, c, d, e)
...         except ValueError:
...             continue
from sage.schemes.elliptic_curves.descent_two_isogeny import test_els
for _ in range(1000):
    a,b,c,d,e = randint(1,1000), randint(1,1000), randint(1,1000), randint(1,1000), randint(1,1000)
    if pari.Pol([a,b,c,d,e]).hyperellratpoints(1000, 1):
        try:
            if not test_els(a,b,c,d,e):
                print("This never happened", a, b, c, d, e)
        except ValueError:
            continue
sage.schemes.elliptic_curves.descent_two_isogeny.test_padic_square(a, p)[source]

Doctest function for cdef int padic_square(mpz_t, unsigned long).

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import test_padic_square as ps
sage: for i in [1..300]:
....:     for p in prime_range(100):
....:          if Qp(p)(i).is_square() != bool(ps(i,p)):
....:              print(i, p)
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import test_padic_square as ps
>>> for i in (ellipsis_range(Integer(1),Ellipsis,Integer(300))):
...     for p in prime_range(Integer(100)):
...          if Qp(p)(i).is_square() != bool(ps(i,p)):
...              print(i, p)
from sage.schemes.elliptic_curves.descent_two_isogeny import test_padic_square as ps
for i in [1..300]:
    for p in prime_range(100):
         if Qp(p)(i).is_square() != bool(ps(i,p)):
             print(i, p)
sage.schemes.elliptic_curves.descent_two_isogeny.test_qpls(a, b, c, d, e, p)[source]

Testing function for Qp_soluble.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import test_qpls as tq
sage: tq(1,2,3,4,5,7)
1
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import test_qpls as tq
>>> tq(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(7))
1
from sage.schemes.elliptic_curves.descent_two_isogeny import test_qpls as tq
tq(1,2,3,4,5,7)
sage.schemes.elliptic_curves.descent_two_isogeny.test_valuation(a, p)[source]

Doctest function for cdef long valuation(mpz_t, mpz_t).

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import test_valuation as tv
sage: for i in [1..20]:
....:     print('{:>10} {} {} {}'.format(str(factor(i)), tv(i,2), tv(i,3), tv(i,5)))
         1 0 0 0
         2 1 0 0
         3 0 1 0
       2^2 2 0 0
         5 0 0 1
     2 * 3 1 1 0
         7 0 0 0
       2^3 3 0 0
       3^2 0 2 0
     2 * 5 1 0 1
        11 0 0 0
   2^2 * 3 2 1 0
        13 0 0 0
     2 * 7 1 0 0
     3 * 5 0 1 1
       2^4 4 0 0
        17 0 0 0
   2 * 3^2 1 2 0
        19 0 0 0
   2^2 * 5 2 0 1
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import test_valuation as tv
>>> for i in (ellipsis_range(Integer(1),Ellipsis,Integer(20))):
...     print('{:>10} {} {} {}'.format(str(factor(i)), tv(i,Integer(2)), tv(i,Integer(3)), tv(i,Integer(5))))
         1 0 0 0
         2 1 0 0
         3 0 1 0
       2^2 2 0 0
         5 0 0 1
     2 * 3 1 1 0
         7 0 0 0
       2^3 3 0 0
       3^2 0 2 0
     2 * 5 1 0 1
        11 0 0 0
   2^2 * 3 2 1 0
        13 0 0 0
     2 * 7 1 0 0
     3 * 5 0 1 1
       2^4 4 0 0
        17 0 0 0
   2 * 3^2 1 2 0
        19 0 0 0
   2^2 * 5 2 0 1
from sage.schemes.elliptic_curves.descent_two_isogeny import test_valuation as tv
for i in [1..20]:
    print('{:>10} {} {} {}'.format(str(factor(i)), tv(i,2), tv(i,3), tv(i,5)))
sage.schemes.elliptic_curves.descent_two_isogeny.two_descent_by_two_isogeny(E, global_limit_small=10, global_limit_large=10000, verbosity=0, selmer_only=0, proof=1)[source]

Given an elliptic curve E with a two-isogeny phi : E –> E’ and dual isogeny phi’, runs a two-isogeny descent on E, returning n1, n2, n1’ and n2’. Here n1 is the number of quartic covers found with a rational point, and n2 is the number which are ELS.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny
sage: E = EllipticCurve('14a')
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
0
sage: E = EllipticCurve('65a')
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
1

sage: # needs sage.symbolic
sage: x,y = var('x,y')
sage: E = EllipticCurve(y^2 == x^3 + x^2 - 25*x + 39)
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
sage: log(n1,2) + log(n1_prime,2) - 2  # the rank
2
sage: E = EllipticCurve(y^2 + x*y + y == x^3 - 131*x + 558)
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
sage: log(n1,2) + log(n1_prime,2) - 2  # the rank
3
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny
>>> E = EllipticCurve('14a')
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
0
>>> E = EllipticCurve('65a')
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
1

>>> # needs sage.symbolic
>>> x,y = var('x,y')
>>> E = EllipticCurve(y**Integer(2) == x**Integer(3) + x**Integer(2) - Integer(25)*x + Integer(39))
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2)  # the rank
2
>>> E = EllipticCurve(y**Integer(2) + x*y + y == x**Integer(3) - Integer(131)*x + Integer(558))
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2)  # the rank
3
from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny
E = EllipticCurve('14a')
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
log(n1,2) + log(n1_prime,2) - 2 # the rank
E = EllipticCurve('65a')
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
log(n1,2) + log(n1_prime,2) - 2 # the rank
# needs sage.symbolic
x,y = var('x,y')
E = EllipticCurve(y^2 == x^3 + x^2 - 25*x + 39)
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
log(n1,2) + log(n1_prime,2) - 2  # the rank
E = EllipticCurve(y^2 + x*y + y == x^3 - 131*x + 558)
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
log(n1,2) + log(n1_prime,2) - 2  # the rank

Using the verbosity option:

sage: E = EllipticCurve('14a')
sage: two_descent_by_two_isogeny(E, verbosity=1)
2-isogeny
Results:
2 <= #E(Q)/phi'(E'(Q)) <= 2
2 <= #E'(Q)/phi(E(Q)) <= 2
#Sel^(phi')(E'/Q) = 2
#Sel^(phi)(E/Q) = 2
1 <= #Sha(E'/Q)[phi'] <= 1
1 <= #Sha(E/Q)[phi] <= 1
1 <= #Sha(E/Q)[2], #Sha(E'/Q)[2] <= 1
0 <= rank of E(Q) = rank of E'(Q) <= 0
(2, 2, 2, 2)
>>> from sage.all import *
>>> E = EllipticCurve('14a')
>>> two_descent_by_two_isogeny(E, verbosity=Integer(1))
2-isogeny
Results:
2 <= #E(Q)/phi'(E'(Q)) <= 2
2 <= #E'(Q)/phi(E(Q)) <= 2
#Sel^(phi')(E'/Q) = 2
#Sel^(phi)(E/Q) = 2
1 <= #Sha(E'/Q)[phi'] <= 1
1 <= #Sha(E/Q)[phi] <= 1
1 <= #Sha(E/Q)[2], #Sha(E'/Q)[2] <= 1
0 <= rank of E(Q) = rank of E'(Q) <= 0
(2, 2, 2, 2)
E = EllipticCurve('14a')
two_descent_by_two_isogeny(E, verbosity=1)

Handling curves whose discriminants involve larger than wordsize primes:

sage: E = EllipticCurve('14a')
sage: E = E.quadratic_twist(next_prime(10^20))
sage: E
Elliptic Curve defined by y^2 = x^3 + x^2 + 716666666666666667225666666666666666775672*x - 391925925925925926384240370370370370549019837037037037060249356 over Rational Field
sage: E.discriminant().factor()
-1 * 2^18 * 7^3 * 100000000000000000039^6
sage: log(100000000000000000039.0, 2.0)
66.438...
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
0
>>> from sage.all import *
>>> E = EllipticCurve('14a')
>>> E = E.quadratic_twist(next_prime(Integer(10)**Integer(20)))
>>> E
Elliptic Curve defined by y^2 = x^3 + x^2 + 716666666666666667225666666666666666775672*x - 391925925925925926384240370370370370549019837037037037060249356 over Rational Field
>>> E.discriminant().factor()
-1 * 2^18 * 7^3 * 100000000000000000039^6
>>> log(RealNumber('100000000000000000039.0'), RealNumber('2.0'))
66.438...
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
0
E = EllipticCurve('14a')
E = E.quadratic_twist(next_prime(10^20))
E
E.discriminant().factor()
log(100000000000000000039.0, 2.0)
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny(E)
log(n1,2) + log(n1_prime,2) - 2 # the rank
sage.schemes.elliptic_curves.descent_two_isogeny.two_descent_by_two_isogeny_work(c, d, global_limit_small=10, global_limit_large=10000, verbosity=0, selmer_only=0, proof=1)[source]

Do all the work in doing a two-isogeny descent.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny_work
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(13,128)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
0
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(1,-16)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
1
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(10,8)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
2
sage: n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(85,320)
sage: log(n1,2) + log(n1_prime,2) - 2 # the rank
3
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny_work
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(Integer(13),Integer(128))
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
0
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(Integer(1),-Integer(16))
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
1
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(Integer(10),Integer(8))
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
2
>>> n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(Integer(85),Integer(320))
>>> log(n1,Integer(2)) + log(n1_prime,Integer(2)) - Integer(2) # the rank
3
from sage.schemes.elliptic_curves.descent_two_isogeny import two_descent_by_two_isogeny_work
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(13,128)
log(n1,2) + log(n1_prime,2) - 2 # the rank
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(1,-16)
log(n1,2) + log(n1_prime,2) - 2 # the rank
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(10,8)
log(n1,2) + log(n1_prime,2) - 2 # the rank
n1, n2, n1_prime, n2_prime = two_descent_by_two_isogeny_work(85,320)
log(n1,2) + log(n1_prime,2) - 2 # the rank