Attachment 'p-descent-experiments.txt'

Download

   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

You are not allowed to attach a file to this page.