## Attachment 'p-descent-experiments.txt'

```   1 """
2 Broumas (Compositio 107, 1997) gave an explicit formula for the
3 p-descent map.  I wanted to implement it in Sage to answer a question
4 described below.
5
6 Context:
7 K is a function field of characteristic p, E an elliptic curve over K.
8 Assume j(E) is not a pth-power in K.  (Equivalently, E does not have a
9 point of order p defined over a separable extension of K.)  General
10 theory gives an injective homomorphism
11
12 	E(K)/pE(K) -> K
13
14 (the target is the additive group of K).  It actually lands in a
15 certain subspace, but that will not be needed here.  Broumas gives
16 an explicit formula taking the (x,y)-coordinates of a point (on a
17 special model of E) to K.  It involves field operations and a
18 derivative operator.  When p>3, "a special model" just means the usual
19 Weierstrass form y^2=x^3+ax+b.
20
21 My problem:
22 p>2.  Consider y^2=x(x+1)(x+t) over Fp(t).
23 Fix f>0 and let q=p^f, d=q+1.
24 Let K=F_{q^2}(u) and make it an extension of Fp(t) by setting t=u^d.
25 I have a bunch of points on E(K):  Let P(u)=(u,u(u+1)^((q+1)/2)), let
26 zeta be a primitive d-th root of unity in K, and set
27
28      P_i=P(zeta^i u)  i=0,...,d-1
29
30 These points are almost independent (sum of P_i over even i is
31 torsion, simialrly for summing over odd i) and generate a subgroup of
32 E(K) of rank d-2=q-1.  There are also a few explicit torsion points
33 around, which we will ignore below because they are of order prime to
34 p.  Let V be the subgroup of E(K) generated by the P_i (and the
35 torsion points).  Then it turns out that the index [E(K):V] is finite
36 of p-power order.  My problem is to compute in specific cases whether
37 the index is 1 or not.  This amounts to computing the dimension as a
38 vector space over Fp of the image of V under the descent map:
39
40       V/pV -> E(K)/pE(K) -> K
41
42 If the image has dimension q-1 then the index is 1 and we have the
43 full Mordell-Weil group explicitly.  If it is less, we need to find
44 more points.
45
46 Based on data produced by Sage and other considerations, I guess that
47 the index is >1 exactly when f>2.
48
49 The code below is divided into two cases, p=3 and p>3.
50 """
51 #################################
52 ##p=3:
53 p=3; f=3; q=3^f
54 k=FiniteField(q^2,name='a')
55 zeta=k.multiplicative_generator()^(q-1)  # a primitive (q+1)st root of unity
56 R, u = PolynomialRing(k, 'u').objgen()
57 K=R.fraction_field()
58 t=u^(q+1)
59 EL=EllipticCurve(K,[0,t+1,0,t,0])
60 ##
61 ## special weierstrass form suitable for p=3 descent map
62 ## (a1=a3=a4=0)
63 E=EL.change_weierstrass_model([1/(t+1),t/(t+1),0,0])
64 ## so (x,y)=(x'/(t+1)^2+t/(t+1),y'/(t+1)^3)
65 ## and (x',y')=((t+1)^2*x-t*(t+1),(t+1)^3*y)
66 ##
67 a2=E.a2(); a6=E.a6(); A=a2 # Hasse invariant
68 def wp(z):
69     return z^p-A*z
70 ##
71 ## Broumas' derivative operator (script D in the paper):
72 def DD(z):
73     return (t+1)^2*(t-1)*u*derivative(z,u)
74 ## DD characterized by DD(a6)/a6==a2
75 ##
76 ## Broumas' descent map:
77 ## The formula corrects a typo in Broumas
78 ##   (missing x in last term of formula for mu)
79 def mu(P):
80     if 2*P==E(0):
81         return 0
82     else:
83         x=P[0]/P[2]; y=P[1]/P[2]
84         return wp(DD(x)/(2*y))+y+wp((x^2+(-DD(a2)/a2+DD(a6)/a6)*x)/(2*y))
85 ##
86 #### Torsion points
87 P0=E([-t*(t+1),0]); P1=E([t^2-1,0]); Pt=E([-t^3+t,0])
88 Q4=E([u^((q+1)/2)*(t+1)^2-t^2-t,(t+1)^3*u^((q+1)/2)*(u^((q+1)/2)+1)]) # 2*Q4==P0
89 ##
90 ## Generators
91 def point(i):
92     return E([(t+1)^2*zeta^i*u-t*(t+1),(t+1)^3*zeta^i*u*(zeta^i*u+1)^((q+1)/2)])
93 P=[]
94 for i in range(q+1):
95     P.append(point(i))
96 print 'points created'
97 ## checks when q=3:
98 ## P[0]+P[2]==Q4-P1
99 ## P[1]+P[3]==Q4
100 ##
101 ## Descents:
102 L=[]
103 for i in range(q+1):
104     L.append(mu(P[i]))
105 print 'descents done'
106 ##
107 ## the L[i] (miraculously) turn out to be polynomials
108 ## strip out the coefficients and turn them into vectors with Fp entries:
109 N=L[0].numerator().degree()+1
110 m=matrix(GF(p),q+1,2*f*N)
111 for pt in range(q+1):
112     x=L[pt]; print 'row', pt, 'created'
113     y=x.numerator().coeffs()
114     for i in range(N):
115         z=y[i]._vector_()
116         for j in range(2*f):
117             m[pt,2*f*i+j]=z[j]
118 ##
119 ## rank of m is the dimension of the image of the points under the descent map
120 (q-1)-rank(m)
121
122
123 #################################################
124 ##p>3:
125 p=5; f=3; q=p^f
126 k=FiniteField(q^2,name='a')
127 zeta=k.multiplicative_generator()^(q-1)  # a primitive (q+1)st root of unity
128 R, u = PolynomialRing(k, 'u').objgen()
129 K=R.fraction_field()
130 t=u^(q+1)
131 EL=EllipticCurve(K,[0,t+1,0,t,0])
132 E=EL.change_weierstrass_model([1,-(t+1)/3,0,0])
133 ##
134 ## Basic invariants of E:
135 a4=E.a4(); a6=E.a6(); delta=E.discriminant(); j=E.j_invariant(); j_prime=derivative(j,u)
136 ##
137 ## Hasse invariant, Weierstrass P, and M function:
138 S, zz = PolynomialRing(K, 'zz').objgen()
139 g=(zz^3+E.a4()*zz+E.a6())^((p-1)/2)
140 A=g.coeffs()[p-1]
141 M=g.quo_rem(zz^p)[0]
142 def wp(z):
143     return z^p-A*z
144 ##
145 ## Broumas' derivative operator (script D in the paper):
146 def DD(z):
147     return 18*(a6/a4)*(j/j_prime)*derivative(z,u)
148 ##
149 ## Broumas' descent map
150 def mu(P):
151     if 2*P==E(0):
152         return 0
153     else:
154         x=P[0]/P[2]; y=P[1]/P[2]
155         return wp(DD(x)/(2*y))+y*M(x)+wp((-2*x^2-(1/6)*(DD(delta)/delta)*x-(4/3)*a4)/(2*y))
156 ##
157 ## Torsion points:
158 P0=E([(t+1)/3,0]); P1=E([-1+(t+1)/3,0]); Pt=E([-t+(t+1)/3,0])
159 Q4=E([u^((q+1)/2)+(t+1)/3,u^((q+1)/2)*(u^((q+1)/2)+1)]) # a point of order 4
160 ##
161 ## Generators:
162 def point(i):
163     return E([zeta^i*u+(t+1)/3,zeta^i*u*(zeta^i*u+1)^((q+1)/2)])
164 P=[]
165 for i in range(q+1):
166     P.append(point(i))
167 print 'points created'
168 ##
169 ## checks when q=7:
170 ## P[0]+P[2]+P[4]+P[6] == Q4+P1
171 ## P[1]+P[3]+P[5]+P[7]==Q4
172 ##
173 ## Descents:
174 L=[]
175 for i in range(q+1):
176     L.append(mu(P[i]))
177 print 'descents done'
178 ##
179 ## the L[i] (miraculously) turn out to be polynomials
180 ## strip out the coefficients and turn them into vectors with Fp entries:
181 N=L[0].numerator().degree()+1
182 m=matrix(GF(p),q+1,2*f*N)
183 for pt in range(q+1):
184     x=L[pt]; print 'row', pt, 'created'
185     y=x.numerator().coeffs()
186     for i in range(N):
187         z=y[i]._vector_()
188         for j in range(2*f):
189             m[pt,2*f*i+j]=z[j]
190 ##
191 ## rank of m is the dimension of the image of the points under the descent map
192 (q-1)-rank(m)
```

## Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
• [get | view] (2010-05-28 14:13:13, 5.9 KB) [[attachment:p-descent-experiments.txt]]
• [get | view] (2010-05-28 23:05:44, 3.0 KB) [[attachment:pdescent.sage]]
All files | Selected Files: delete move to page copy to page