aboutsummaryrefslogtreecommitdiff
path: root/divisibility_reductions/jumps.sage
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2026-06-14 09:58:21 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2026-06-14 09:58:21 +0200
commit5ea79c7ae0d44686f1df05c4a016652afbe58968 (patch)
tree05f6a052373f5fe0942777a48303b2f8b884cbe1 /divisibility_reductions/jumps.sage
downloadkummer-notes-code-5ea79c7ae0d44686f1df05c4a016652afbe58968.tar.gz
kummer-notes-code-5ea79c7ae0d44686f1df05c4a016652afbe58968.zip
Initial commit
Diffstat (limited to 'divisibility_reductions/jumps.sage')
-rwxr-xr-xdivisibility_reductions/jumps.sage145
1 files changed, 145 insertions, 0 deletions
diff --git a/divisibility_reductions/jumps.sage b/divisibility_reductions/jumps.sage
new file mode 100755
index 0000000..7517464
--- /dev/null
+++ b/divisibility_reductions/jumps.sage
@@ -0,0 +1,145 @@
1from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
2
3# Pre-tests on E and P
4def suitable( E, P, ell ):
5 if not is_EllipticCurve(E):
6 print "E is not an elliptic curve"
7 return False
8 if E.base_field() != QQ:
9 print "E is not defined over Q"
10 return False
11 if not P in E:
12 print "P is not in E"
13 return False
14 if P.has_finite_order():
15 print "P has finite order"
16 return False
17 if not is_prime(ell):
18 print "ell is not prime"
19 return False
20 return True
21
22
23# Stupid auxiliary function. Returns higest power of n dividing m.
24def val( n, m ):
25 ret = 0
26 while m % (n^(ret+1)) == 0:
27 ret += 1
28 return ret
29
30def test_jump_kl2_label( label, ell ):
31 E = EllipticCurve( label )
32 if E.rank() < 1:
33 print "E has rank 0"
34 return
35 P = E.gens()[0]
36 test_jump_kl2( E, P, ell )
37
38def test_jump_kl2( E, P, ell ):
39 if not suitable( E, P, ell ):
40 return
41
42 flag = True
43 for p in Primes():
44 if p > 10^3:
45 break
46 if p == ell:
47 # print "Skipping", p, "because = ell"
48 continue
49 if E.discriminant() % p == 0:
50 # print "Skipping", p, "because E has bad reduction"
51 continue
52 if P.reduction(p).order() % ell != 0:
53 # print "Skipping", p, "because red of P is infinitely ell-divisible"
54 continue
55
56 # print "Working with prime p =", p
57
58 F = FiniteField(p)
59
60 for i in range(3):
61 # print "Torsion level", i, "..."
62
63 # We can build the division fields for increasing powers of l
64 # incrementally. To get a division field, we first compute the
65 # splitting field of the division polynomial. We may be off by
66 # a degree 2 extension. If so, by finite field magic we know
67 # exactly which degree 2 extension we need: the unique one!
68 R.<x> = PolynomialRing(F)
69 F.<a> = E.reduction(p).division_polynomial(ell^i).splitting_field()
70 E_red = E.reduction(p).base_extend(F)
71 # extend if necessary
72 k = val(ell,E_red.gens()[0].order())
73 h = val(ell,E_red.order()) - k
74 if k < i or h < i:
75 F.<a> = F.extension(2)
76 E_red = E_red.base_extend(F)
77
78 P_red = E_red.point(P.reduction(p))
79
80 flag = False
81 if P_red.is_divisible_by(ell):
82 # print "P ell-divisible in this torsion level"
83 flag = True
84 break
85
86 if not flag:
87 print "Point not divisible mod", p
88 print "Stopping here"
89 break
90 if flag:
91 print "*********************************"
92 print "*** Candidate counterexample! ***"
93 print "*********************************"
94
95# Wrapper
96def test_jump_den_label( label, ell ):
97 E = EllipticCurve(label)
98 if E.rank() < 1:
99 print "E has rank 0"
100 return
101 P = E.gens()[0]
102 test_jump_den( E, P, ell )
103
104def test_jump_den( E, P, ell ):
105 if not suitable( E, P, ell ):
106 return
107
108 n_primes = 0
109 inf_divisible = 0
110 tot_l_part = 0
111 tot_non_l_part = 0
112
113 for p in Primes():
114 if p > 5*10^3:
115 break
116 if p == ell or E.discriminant() % p == 0:
117 continue
118
119 n_primes += 1
120
121 E_red = E.reduction(p)
122 N = E_red.order()
123 k = val(ell,E_red.gens()[0].order())
124 h = val(ell,N) - k
125 temp_non_l_part = (N / (ell^(h+k)))-1
126 tot_non_l_part += temp_non_l_part
127 temp_l_part = N - temp_non_l_part
128 tot_l_part += temp_l_part
129
130 if P.reduction(p).order() % ell != 0:
131 inf_divisible += 1
132
133 found = RDF( inf_divisible / n_primes )
134 expected = RDF( tot_non_l_part / (tot_l_part+tot_non_l_part) )
135 print "Found: %0.3f, expected: %0.3f"%(found, expected)
136 if abs(found-expected) > 0.05:
137 print "Unexpected density! Checking divisibility in reductions..."
138 test_jump_kl2( E, P, ell )
139
140def test_from_file( filename ):
141 attach(filename)
142 for coord in data:
143 label = EllipticCurve(coord).label()
144 print "Trying curve", label, "with ell =", 3
145 test_jump_den_label(label,3)

Generated with cgit - Back to sebastiano.tronto.net