mordell_weil_saturation_attempt

323 days ago by arabindr

K.<a> = NumberField(x^2 - x - 1) import psage.ellcurve.lseries.sqrt5 as sqrt5w 
       
class ReductionMap: """ INPUT: - E -- Elliptic curve over K=Q(sqrt(5)) - P -- a prime in Q that splits in K - ell -- a prime that exactly divides the cardinality of E mod P. OUTPUT: - a callable map from E(K) to GF(ell) """ def __init__(self, E, P, ell): self.E = E self.P = P self.ell = ell self.v = K.factor(self.P) Emod0 = E.change_ring(self.v[0][0].residue_field()) Emod1 = E.change_ring(self.v[1][0].residue_field()) self.Emod0 = Emod0 self.Emod1 = Emod1 self.GFell = GF(ell) # compute the ell-torsion subgroup T0 = Emod0(0).division_points(ell) T1 = Emod1(0).division_points(ell) if len(T0) == ell: self.T = T0 self.Emod = Emod0 elif len(T1) == ell: self.T = T1 self.Emod = Emod1 else: raise ValueError, "must have Emod[ell] of order ell" # compute multiplier self.card = self.Emod.cardinality() self.multiplier = ZZ(self.card / ell) # make discrete log table # 1. find first nonzero element g in T i = 0 g = self.T[i] while g == 0: i += 1 g = self.T[i] dlog = {g:1} # 2. set h to 2*g, 3*g, .., recording the multiple h = g + g for n in range(2,ell+1): dlog[h] = n h += g self.dlog = dlog def __call__(self, Q): # Reduce Q to the curve over the finite field. # Then multiple the result by #Emod/ell. # Finally write in terms of generator using dlog table. Qbar = self.Emod(Q) n = self.dlog[self.multiplier * Qbar] return self.GFell(n) 
       
def nice_prime_finder(E, norm_lower, norm_bound, ell): prime_set = prime_range(norm_lower, norm_bound) v=[] t = 0 for l in prime_set: if l!=5 and len(K.factor(l))==2: if E.has_good_reduction(K.factor(l)[0][0]) and E.has_good_reduction(K.factor(l)[1][0]): for P in K.primes_above(l): n = E.change_ring(P.residue_field()).cardinality() if n%ell ==0 and (n/ell)%ell != 0: v.append(l) return v 
       
def saturate_naive(E, Q, ell): cond = True while cond: cond = False for b in [0,1]: v = (E(Q[0] + b*Q[1])).division_points(ell) if len(v) > 0: Q[0] = v[0] cond = True cond = True while cond: cond = False v = (E(Q[1])).division_points(ell) if len(v) > 0: Q[1] = v[0] cond = True return Q 
       
def saturate_prime_old(E, Q, ell): norm_bound = 100 w=[] while len(w) < 5: w+=nice_prime_finder(E, norm_bound - 100, norm_bound, ell) norm_bound += 100 psi0 = ReductionMap(E, w[0], ell) psi1 = ReductionMap(E, w[1], ell) i = 2 M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psi1(Q[0]),psi1(Q[1])]]) while M[0] == M[1]: psii = ReductionMap(E, w[i], ell) M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psii(Q[0]),psii(Q[1])]]) i+=1 while det(M) == 0: a1 = ZZ(M[0][0]) a2 = ZZ(M[0][1]) if a1 == a2 == 0: a1 = ZZ(M[1][0]) a2 = ZZ(M[1][1]) g = gcd(a1,a2) a1/=g a2/=g try: Q2 = (ZZ(a2)*E(Q[0]) - ZZ(a1)*E(Q[1])).division_points(ell)[0] except IndexError: break if a1: Q[0] = Q2 else: Q[1] = Q2 i = 2 M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psi1(Q[0]),psi1(Q[1])]]) while M[0] == M[1]: psii = ReductionMap(E, w[i], ell) M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psii(Q[0]),psii(Q[1])]]) i+=1 return Q 
       
def saturate_prime(E, Q, ell): print ell w=[] ind = False norm_bound = 100 while len(w) < 20: w+=nice_prime_finder(E, norm_bound - 99, norm_bound, ell) norm_bound += 100 w = set(w) w = list(w) w.sort() j = 0 while j < 20 and ind == False: psi0 = ReductionMap(E, w[j], ell) psi1 = ReductionMap(E, w[j+1], ell) try: M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psi1(Q[0]),psi1(Q[1])]]) except ZeroDivisionError: j+=1 continue if M[0] == M[1]: j+=1 continue print ell print M a1 = M[0][0] a2 = M[0][1] if a1 == a2 == 0: a1 = M[1][0] a2 = M[1][1] if a2: a1 = ZZ(a1/a2) a2 = 1 else: a1 = 1 a2 = 0 try: Q2 = (ZZ(a2)*E(Q[0]) - ZZ(a1)*E(Q[1])).division_points(ell)[0] except IndexError: break if a1 == 0: Q[0] = Q2 else: Q[1] = Q2 try: M = matrix(GF(ell), [[psi0(Q[0]), psi0(Q[1])], [psi1(Q[0]),psi1(Q[1])]]) except ZeroDivisionError: j+=1 continue print M j+=1 if det(M): ind = True return Q 
       
E = EllipticCurve([0,-a,1,-a-1,2*a+1] ) Q = E.gens(); print Q print Q[0].height(), Q[1].height() 
       
[(0 : -a - 1 : 1), (-3/4*a + 1/4 : -5/4*a - 5/8 : 1)]
0.166157999281333 1.94042291278625
[(0 : -a - 1 : 1), (-3/4*a + 1/4 : -5/4*a - 5/8 : 1)]
0.166157999281333 1.94042291278625
def real_periods(E): embs = K.embeddings(RR) v=[1,1] i = 0 while i < 2: t = E.period_lattice(embs[i]).basis() if real(t[1])==0: v[i] = 2*t[0] else: v[i] = t[0] i+=1 return v[0]*v[1] 
       
def conjectural_sha(E, Lstar, bd = 35): def hp(X, Y): return (X+Y).height() - X.height() - Y.height() Q = E.gens() for ell in prime_range(2, 15): Q = saturate_naive(E, Q, ell) for ell in prime_range(15, bd): Q = saturate_prime(E, Q, ell) reg = hp(Q[0], Q[0])*hp(Q[1],Q[1]) - hp(Q[1],Q[0])^2 M = E.tamagawa_product_bsd() sha = RR(sqrt(5))*Lstar*(E.torsion_order())^2/((real_periods(E))*reg*M) return sha, reg, Q 
       
time conjectural_sha(E, 1.44) 
       
17
17
[16 11]
[13  9]
19
19
[ 4  8]
[11  2]
23
23
[ 8  6]
[11 18]
29
29
[ 2 21]
[ 1  2]
31
31
[30 27]
[ 3 10]
(0.999000229181568, 0.0853096123084645, [(0 : -a - 1 : 1), (a + 1 : a :
1)])
Time: CPU 100.61 s, Wall: 100.61 s
17
17
[16 11]
[13  9]
19
19
[ 4  8]
[11  2]
23
23
[ 8  6]
[11 18]
29
29
[ 2 21]
[ 1  2]
31
31
[30 27]
[ 3 10]
(0.999000229181568, 0.0853096123084645, [(0 : -a - 1 : 1), (a + 1 : a : 1)])
Time: CPU 100.61 s, Wall: 100.61 s
time conjectural_sha(EllipticCurve(K,[a, 0, 0, a - 3, -a + 2]), 1.65830254174) 
       
17
17
[7 8]
[9 5]
19
19
[10 18]
[ 1  4]
23
23
[ 9  1]
[20  6]
29
29
[ 7  6]
[23  4]
31
31
[24  0]
[20 25]
(1.00000000000118, 0.0929982882741012, [(1 : -a : 1), (0 : -a + 1 : 1)])
Time: CPU 181.10 s, Wall: 181.36 s
17
17
[7 8]
[9 5]
19
19
[10 18]
[ 1  4]
23
23
[ 9  1]
[20  6]
29
29
[ 7  6]
[23  4]
31
31
[24  0]
[20 25]
(1.00000000000118, 0.0929982882741012, [(1 : -a : 1), (0 : -a + 1 : 1)])
Time: CPU 181.10 s, Wall: 181.36 s
time conjectural_sha(EllipticCurve(K,[a, -a - 1, 0, -1, a + 1]), 1.83792258404) 
       
17
17
[16  7]
[ 1 12]
19
19
[18  6]
[16 16]
23
23
[20 14]
[ 9 16]
29
29
[26 14]
[15 17]
31
31
[ 3 15]
[23 28]
(1.00000000000005, 0.113330086069452, [(0 : -a : 1), (1 : -a : 1)])
Time: CPU 157.61 s, Wall: 157.84 s
17
17
[16  7]
[ 1 12]
19
19
[18  6]
[16 16]
23
23
[20 14]
[ 9 16]
29
29
[26 14]
[15 17]
31
31
[ 3 15]
[23 28]
(1.00000000000005, 0.113330086069452, [(0 : -a : 1), (1 : -a : 1)])
Time: CPU 157.61 s, Wall: 157.84 s
conjectural_sha(EllipticCurve(K,[0, -a - 1, a, a, 0]), 2.16472915773) 
       
3
3
[0 2]
[1 0]
5
5
[0 4]
[0 2]
7
7
[3 5]
[4 6]
11
11
[9 5]
[9 8]
13
13
[ 3  9]
[12  5]
(1.00000000000043, 0.171182414222050, [(0 : -a : 1), (1 : -a : 1)])
3
3
[0 2]
[1 0]
5
5
[0 4]
[0 2]
7
7
[3 5]
[4 6]
11
11
[9 5]
[9 8]
13
13
[ 3  9]
[12  5]
(1.00000000000043, 0.171182414222050, [(0 : -a : 1), (1 : -a : 1)])
conjectural_sha(EllipticCurve(K,[1, -a, a + 1, -3*a - 2, 3*a + 2]), 2.25901353313) 
       
3
3
[0 2]
[0 1]
[1 2]
[0 1]
5
5
[1 1]
[4 0]
7
7
[2 2]
[4 6]
11
11
[3 4]
[7 2]
13
13
[10  1]
[12  8]
(0.999999999999455, 0.157330535689450, [(a : -a - 1 : 1), (0 : -2*a - 1
: 1)])
3
3
[0 2]
[0 1]
[1 2]
[0 1]
5
5
[1 1]
[4 0]
7
7
[2 2]
[4 6]
11
11
[3 4]
[7 2]
13
13
[10  1]
[12  8]
(0.999999999999455, 0.157330535689450, [(a : -a - 1 : 1), (0 : -2*a - 1 : 1)])
conjectural_sha(EllipticCurve(K,[a + 1, a + 1, a + 1, a - 2, -2*a]), 2.28209252167) 
       
3
3
[1 1]
[1 0]
5
5
[3 2]
[0 1]
7
7
[1 6]
[6 1]
11
11
[10  6]
[ 5  9]
13
13
[5 4]
[5 0]
(0.999999999998572, 0.0951868564282234, [(-2 : 0 : 1), (-a + 2 : -2*a +
2 : 1)])
3
3
[1 1]
[1 0]
5
5
[3 2]
[0 1]
7
7
[1 6]
[6 1]
11
11
[10  6]
[ 5  9]
13
13
[5 4]
[5 0]
(0.999999999998572, 0.0951868564282234, [(-2 : 0 : 1), (-a + 2 : -2*a + 2 : 1)])
conjectural_sha(EllipticCurve(K,[1, -a, a + 1, -4, 2]), 2.28688622269) 
       
3
3
[2 0]
[0 0]
[2 2]
[0 2]
5
5
[2 4]
[1 3]
7
7
[4 5]
[0 5]
11
11
[9 5]
[0 6]
13
13
[ 9  6]
[ 0 12]
(1.00000000000006, 0.134964158934332, [(2*a - 1 : -3*a + 1 : 1), (1 : -a
- 1 : 1)])
3
3
[2 0]
[0 0]
[2 2]
[0 2]
5
5
[2 4]
[1 3]
7
7
[4 5]
[0 5]
11
11
[9 5]
[0 6]
13
13
[ 9  6]
[ 0 12]
(1.00000000000006, 0.134964158934332, [(2*a - 1 : -3*a + 1 : 1), (1 : -a - 1 : 1)])
conjectural_sha(EllipticCurve(K,[1, a + 1, 0, 3*a - 3, -a + 2]), 2.47197204952) 
       
3
3
[1 1]
[2 2]
5
5
[1 1]
[1 2]
7
7
[3 5]
[4 3]
11
11
[5 1]
[4 8]
13
13
[ 2  0]
[12  6]
(0.999999999999048, 0.0889402580362338, [(a - 2 : -a + 2 : 1), (-2*a + 2
: -a + 3 : 1)])
3
3
[1 1]
[2 2]
5
5
[1 1]
[1 2]
7
7
[3 5]
[4 3]
11
11
[5 1]
[4 8]
13
13
[ 2  0]
[12  6]
(0.999999999999048, 0.0889402580362338, [(a - 2 : -a + 2 : 1), (-2*a + 2 : -a + 3 : 1)])
conjectural_sha(EllipticCurve(K,[1, a + 1, a, 0, 0]), 2.32495199742) 
       
3
3
[2 1]
[1 2]
[2 1]
[1 1]
5
5
[4 0]
[2 1]
7
7
[1 0]
[2 2]
11
11
[8 6]
[4 0]
13
13
[9 2]
[4 5]
(0.999999999998045, 0.165554899660458, [(a + 1 : -4*a - 2 : 1), (2 : 3*a
- 2 : 1)])
3
3
[2 1]
[1 2]
[2 1]
[1 1]
5
5
[4 0]
[2 1]
7
7
[1 0]
[2 2]
11
11
[8 6]
[4 0]
13
13
[9 2]
[4 5]
(0.999999999998045, 0.165554899660458, [(a + 1 : -4*a - 2 : 1), (2 : 3*a - 2 : 1)])
conjectural_sha(EllipticCurve(K,[1, 0, 0, -2*a - 3, 2*a + 2]), 2.43326511373) 
       
3
3
[0 1]
[2 0]
5
5
[0 1]
[3 1]
7
7
[2 0]
[5 1]
11
11
[ 1  3]
[ 0 10]
13
13
[0 5]
[2 5]
(1.00000000000171, 0.146923967827133, [(-a - 1 : -1 : 1), (a : -a + 1 :
1)])
3
3
[0 1]
[2 0]
5
5
[0 1]
[3 1]
7
7
[2 0]
[5 1]
11
11
[ 1  3]
[ 0 10]
13
13
[0 5]
[2 5]
(1.00000000000171, 0.146923967827133, [(-a - 1 : -1 : 1), (a : -a + 1 : 1)])