// Above the dashed line, this file includes Magma code for determining the point // counts of X^+(mu(3)) and X^-(mu(3)) over F_q, for a suitable prime power q. // Below the dashed line, the output when q=11 is given and compared with the // information from the zeta function of Y(mu(3)). For the code that computes // the latter zeta function, see the file "zeta-function-A5-example.txt". function AConst(F,C) // Given elliptic curve F over a finite field with // 2-torsion point C, returns the constant A:=g0*g1. if #F eq 2 then F2:=BaseExtend(F,2); C2:=F2!C; return BaseRing(F)!AConst(F2,C2); end if; repeat f:=Random(F); until f ne F!0 and f ne C; return (f[1]-C[1])*((f+C)[1]-C[1]); end function; function fiberList(F, C, f, a) // Given elliptic curve F over a finite field with 2-torsion point C // and arbitrary point f, and a in P^6, returns a list of points on the fiber // of Y(a) over the point f. P:= PolynomialRing(BaseRing(F)); if f ne F!0 and f ne C then g0:= f[1]-C[1]; h0:= f[2]; g1:= (f+C)[1]-C[1]; h1:= (f+C)[2]; phi0:= g0*Z^6 + g1; phi1:= g0^2*Z^6 + g1^2; phi2:= g0*Z^5 + g1*Z; phi3:= h0*Z^5 + h1*Z; phi4:= Z^4 + Z^2; phi5:= g0*Z^4 + g1*Z^2; phi6:= Z^3; q:= a[1]*phi0 + a[2]*phi1 + a[3]*phi2 + a[4]*phi3 + a[5]*phi4 + a[6]*phi5 + a[7]*phi6; else // Note: This is actually just the equation of the fiber over 0, and this is what // is being returned when f = C; for many purposes, this is probably okay, but in // general it should not be used to list the points in the fiber over C. (REMOVE THIS COMMENT???) A:=AConst(F,C); q:=a[1]*A + a[2]*Z^6 + a[4]*(Z^5-A*Z) + a[5]*Z^2 + a[6]*Z^4; end if; // print "y^2 = ", q; R := PolynomialRing(BaseRing(F)); fiberPtList := []; // Create points away from infinity for x in BaseRing(F) do for y in AllRoots(Evaluate(R!q,x),2) do Append(~fiberPtList,Coordinates(f) cat [x,y,1]); end for; end for; // Create points at infinity lead := BaseRing(F)!Coefficient(q,6); for y in AllRoots(lead,2) do Append(~fiberPtList,Coordinates(f) cat [1,y,0]); end for; return fiberPtList; end function; procedure countOrbits(base) // Given a prime power 'base', this returns the number of points on X^+(mu(3)) // and X^-(mu(3)) over the field GF(base). k := GF(base^2); tau := 3; E := EllipticCurve([k!0,(1-6*tau^2-3*tau^4),0,16*tau^6,0]); C := E![0,0,1]; phi := FrobeniusMap(E); P6 := ProjectiveSpace(Rationals(),6); a := P6![ -4*tau^2*(1 + tau)^6, (1 + 6*tau + tau^2)^2, 4*(-1 + tau)^2*tau^2*(1 + 14*tau + 34*tau^2 + 14*tau^3 + tau^4), 0, 4*tau^4*(1 + 12*tau + 40*tau^2 + 164*tau^3 + 334*tau^4 + 164*tau^5 + 40*tau^6 + 12*tau^7 + tau^8), -8*tau^3*(3 + 28*tau + 34*tau^2 + 28*tau^3 + 3*tau^4), -8*(-1 + tau)^2*tau^4*(1 + 14*tau + 71*tau^2 + 84*tau^3 + 71*tau^4 + 14*tau^5 + tau^6) ]; // Creates the list of points P on E\{0,C} such that phi(Q) = Q or phi(Q) = Q+C. generalBasePoints := {@ @}; for Q in Points(E) do if phi(Q) in {@ Q, Q+C @} then Include(~generalBasePoints,Q); end if; end for; // Counts Frobenius-invariant pairs {P,iota+(P)} for points P away from fibers over 0,C. generalIotaPairs := {@ @}; for Q in generalBasePoints do if Q ne E!0 and Q ne C then for P in fiberList(E,C,Q,a) do // Version 1: iota(Q,(Z0:y:Z1)) = (Q+C,(Z1:y:Z0) iotaP := Coordinates(Q+C) cat [P[6],P[5],P[4]]; // If iotaP is a finite point, then normalize so that last coordinate is 1: if iotaP[6] ne 0 then iotaP := [iotaP[1],iotaP[2],iotaP[3],iotaP[4]/iotaP[6],iotaP[5]/(iotaP[6])^3,1]; end if; // Note that we don't need to normalize the points at infinity (with Z1=0) because the fiberList command already does this: it gives them in the form [1,y,0]. Include(~generalIotaPairs, {@ P,iotaP @}); end for; end if; end for; total := 5*base; for pair in generalIotaPairs do frobOfFirstElt := [pair[1][1]^base,pair[1][2]^base,pair[1][3]^base,pair[1][4]^base,pair[1][5]^base,pair[1][6]^base]; if frobOfFirstElt in pair then total +:= 1; end if; end for; // Since we haven't written down the equation for the fiber over C, we have not included // them in the count above. But given that 0\in E is defined over the base field, the // only way for an iota-orbit of a point P over 0 to be Frobenius-invariant is if the point // itself is Frobenius-invariant. In brief, to count the orbits of points over 0 and C // we just need to determine the number of points on the fiber over 0 that are defined // over the base field, and add that to the total. for P in fiberList(E,C,E!0,a) do if P eq [P[1]^base,P[2]^base,P[3]^base,P[4]^base,P[5]^base,P[6]^base] then total +:= 1; end if; end for; print "Size of X^+(",base,") = ",total; // Counts Frobenius-invariant pairs {P,iota-(P)} for points P away from fibers over 0,C. generalIotaPairs := {@ @}; for Q in generalBasePoints do if Q ne E!0 and Q ne C then for P in fiberList(E,C,Q,a) do // Version 2: iota(Q,(Z0:y:Z1)) = (Q+C,(Z1:-y:Z0) iotaP := Coordinates(Q+C) cat [P[6],-P[5],P[4]]; // If iotaP is a finite point, then normalize so that last coordinate is 1: if iotaP[6] ne 0 then iotaP := [iotaP[1],iotaP[2],iotaP[3],iotaP[4]/iotaP[6],iotaP[5]/(iotaP[6])^3,1]; end if; // Note that we don't need to normalize the points at infinity (with Z1=0) because the fiberList command already does this: it gives them in the form [1,y,0]. Include(~generalIotaPairs, {@ P,iotaP @}); end for; end if; end for; total := 5*base; for pair in generalIotaPairs do frobOfFirstElt := [pair[1][1]^base,pair[1][2]^base,pair[1][3]^base,pair[1][4]^base,pair[1][5]^base,pair[1][6]^base]; if frobOfFirstElt in pair then total +:= 1; end if; end for; // Since we haven't written down the equation for the fiber over C, we have not included // them in the count above. But given that 0\in E is defined over the base field, the // only way for an iota-orbit of a point P over 0 to be Frobenius-invariant is if the point // itself is Frobenius-invariant. In brief, to count the orbits of points over 0 and C // we just need to determine the number of points on the fiber over 0 that are defined // over the base field, and add that to the total. for P in fiberList(E,C,E!0,a) do if P eq [P[1]^base,P[2]^base,P[3]^base,P[4]^base,P[5]^base,P[6]^base] then total +:= 1; end if; end for; print "Size of X^-(",base,") = ",total; end procedure; // Type the command: countOrbits(q); function expandZeta(q,P2part) tau := 3; F := EllipticCurve([GF(q)!0,(1-6*tau^2-3*tau^4),0,16*tau^6,0]); Z := ZetaFunction(F); K := PowerSeriesRing(RationalField()); P0 := 1-t; P1 := Evaluate(Numerator(Z),t); P2 := (1-q*t)^7*K!P2part; P3 := Evaluate(Numerator(Z),q*t); P4 := 1-q^2*t; zetaFn := P1*P3/(P0*P2*P4); return Log(zetaFn); end function; ---- RESULTS FROM USING THESE PROCEDURES --- The following gives the point count of X^+(mu(3)) and X^-(mu(3)) over F_11: > countOrbits(11); Size of X^+( 11 ) = 204 Size of X^-( 11 ) = 218 The command computeZeta4(11) (from the file "zeta-function-A5-example.txt") says that the H^2-part of the zeta function of the double cover surface Y over F_11 is (1-11*t)^8*(1+11*t)^6*(1 - 30*t + 429*t^2 - 3630*t^3 + 14641*t^4)*(1 + 6*t - 99*t^2 + 726*t^3 + 14641*t^4). // Need to include this before running expandZeta: K := PowerSeriesRing(RationalField()); Options for zeta function of X^- : expandZeta(11,(1 - 11*t)*(1 - 30*t + 429*t^2 - 3630*t^3 + 14641*t^4)); --> This gives a point count of X^-(11) = 240 expandZeta(11,(1 - 11*t)*(1 + 6*t - 99*t^2 + 726*t^3 + 14641*t^4)); --> This gives a point count of X^-(11) = 204 expandZeta(11,(1 - 11*t)*(1+11*t)^4); --> This gives a point count of X^-(11) = 166 Options for zeta function of X^+ include all of the options for X^- above, as well as: expandZeta(11,(1 + 11*t)*(1 - 30*t + 429*t^2 - 3630*t^3 + 14641*t^4)); --> This gives a point count of X^-(11) = 218 expandZeta(11,(1 + 11*t)*(1 + 6*t - 99*t^2 + 726*t^3 + 14641*t^4)); --> This gives a point count of X^-(11) = 182 expandZeta(11,(1+11*t)^5); --> This gives a point count of X^-(11) = 144 CONCLUSION: Over F_11, the H^2-part of the zeta function of X^- is (1-11*t)^8*(1 + 6*t - 99*t^2 + 726*t^3 + 14641*t^4) and the H^2-part of the zeta function of X^+ is (1-11*t)^7*(1 + 11*t)*(1 - 30*t + 429*t^2 - 3630*t^3 + 14641*t^4)