load "X_1_n.m"; function pIsogeniesFiniteField1(E,p); //Returns the p+1 elliptic curves that are p-isogenous to an initial E //curve defined over a finite field //Raises an error in characteristic 2,3 or if E is supersingular Fq := BaseRing(E); jE := jInvariant(E); fp := ClassicalModularPolynomial(p); fp := ChangeRing(Parent(fp),Fq) ! fp; fpjE := UnivariatePolynomial(Evaluate(fp,2,jE)); Fqn := SplittingField(fpjE); A2 := AffineSpace(Fqn,2); X0p := ModularCurve(A2,"Canonical",p); mp := ModuliPoints(X0p,BaseChange(E,Fqn)); assert #mp eq p+1; return [Isogeny(BaseChange(E,Fqn),x) : x in mp]; end function; function pIsogeniesFiniteField(E,p); //Returns the p+1 elliptic curves that are p-isogenous to an initial E //curve defined over a finite field assert IsPrime(p); //assert p ne 2; Fq := BaseRing(E); fp := DivisionPolynomial(E,p); Fqn := SplittingField(fp); Fq2n := RandomExtension(Fqn, 2); xi := Roots(ChangeRing(fp,Fq2n)); Eq2n := BaseChange(E,Fq2n); fE := DefiningEquation(Eq2n); yi := [Roots(UnivariatePolynomial(Evaluate(Evaluate(fE,3,1),1,x[1])))[1][1] : x in xi]; Pi := [E(Fq2n) ! [xi[i][1],yi[i]] : i in [1..#xi]]; //now Pi is a list with all torsion points R := PolynomialRing(Fq2n); kernel_polynomials := {&*[X-(j*P)[1] : j in [1..Ceiling((p-1)/2)]] : P in Pi}; isogenies := [PowerStructure(MapSch) | ]; for f in kernel_polynomials do; Ef,phi := IsogenyFromKernel(Eq2n,f); Append(~isogenies,phi); end for; return isogenies; end function; function TateNormalForm_bc(E,P); //Return the b,c of the tate normal form of (E,P) as in equation (2) of http://arxiv.org/pdf/1307.5719v1.pdf assert P[3] eq 1; x0:=P[1]; y0:=P[2]; a1,a2,a3,a4,a6:=Explode(aInvariants(E)); aa1:=a1; aa3:=2*y0+a3+a1*x0; aa2:=3*x0+a2; aa4:=3*x0^2+2*x0*a2+a4-a1*y0; aaa1:=2*aa4/aa3+aa1; aaa3:=aa3; aaa2:=aa2-(aa4/aa3)^2-aa1*aa4/aa3; b:=-aaa2^3/aaa3^2; c:=-(aaa1*aaa2-aaa3)/aaa3; return [b,c]; end function; function TateNormalForm_xy(E,P); //return the x,y of the tate normal form of (E,P) as in section 2.1 http://arxiv.org/pdf/1307.5719v1.pdf b,c := Explode(TateNormalForm_bc(E,P)); r := b/c; s := c^2/(b-c); t := (r*s-2*r+1); x := (s-r)/t; y := t/(s^2-s-r+1); return [x,y]; end function; function MyMultiset(itterable); uniques := []; for i in itterable do; if i notin uniques then; Append(~uniques,i); end if; end for; return [ : j in uniques]; end function; function Tp_X1N_noncuspidal_place(P,p); assert IsPrime(p); ZZ := IntegerRing(); E := EllipticCurveFromX1Place(P); X1N := Curve(P); assert Characteristic(BaseRing(X1N)) ne p; isogenies := pIsogeniesFiniteField(E,p); Eq2n := Domain(isogenies[1]); Fq2n := BaseRing(Eq2n); Pi := [ : phi in isogenies]; xyi := [TateNormalForm_xy(P[1],P[2]) : P in Pi]; places := [Places(X1N(Fq2n) ! xy) : xy in xyi]; assert &and[#p eq 1 : p in places]; places := MyMultiset(&cat places); d := Degree(P); return &+[ (ZZ ! (place[2]*d/Degree(place[1])))*place[1] : place in places]; end function; function Tp_X1N_noncuspidal(D,p); P,e := Support(D); return &+[e[i]*Tp_X1N_noncuspidal_place(P[i],p) : i in [1..#P]]; end function; function diamond_operator_X1N_noncuspidal_place(P,d); E := EllipticCurveFromX1Place(P); X1N := Curve(P); Fq := BaseRing(E); xy := TateNormalForm_xy(E,d*(E ! [0,0])); dP := Places(X1N(Fq) ! xy); assert #dP eq 1; return dP[1]; end function; function diamond_operator_X1N_noncuspidal(D,p); P,e := Support(D); return &+[e[i]*diamond_operator_X1N_noncuspidal_place(P[i],p) : i in [1..#P]]; end function; function Tp_pdp_1_noncuspidal_place(P,p); return Tp_X1N_noncuspidal_place(P,p)-p*diamond_operator_X1N_noncuspidal_place(P,p)-P; end function; function Tp_pdp_1_noncuspidal(D,p); P,e := Support(D); return &+[e[i]*Tp_pdp_1_noncuspidal_place(P[i],p) : i in [1..#P]]; end function; function PositiveRankHeckePolynomial(S,n); //Returns the characteristic polynomial of the hecke operator n on the subspace //of the cuspidal modular symbol spaces S corresponding to the part where the LRatio is 0 //Under BSD this is exactly the part corresponding to the part of S where the corresponding abelian variety has positive rank return &*[HeckePolynomial(Si,n) : Si in NewformDecomposition(S) | LRatio(AssociatedNewSpace(Si),1) eq 0]; end function; function PositiveRankHeckePolynomialX1N(N,n,chars); //The input space needs to be cuspidal of sign 0 //Returns the characteristic polynomial of the hecke operator n on the subspace //of the cuspidal modular symbol spaces S corresponding to the part where the LRatio is 0 //with respect to at least one of the characters in chars //Under BSD this is exactly the part corresponding to the part of S where the corresponding abelian variety when twisted by one of the characters has positive rank D := FullDirichletGroup(N); chars := [D ! chi : chi in chars]; ann_pol := 1; for d in Elements(D) do; M := ModularSymbols(d,2,0); S := CuspidalSubspace(M); for Si in NewformDecomposition(S) do; Snew := AssociatedNewSpace(Si); rank_0 := &or[Dimension(Snew)/2 ne Dimension(TwistedWindingSubmodule(Snew,1,chi)) : chi in chars]; if rank_0 then; ann_pol := ann_pol*Sqrt(HeckePolynomial(Si,n)); end if; end for; end for; return ann_pol; end function;