# This file contains code related to two elliptic curves which are # quotients of PX(a). One is denoted by E^+ in LaTeX and Ep in Maple, # the other is E^- or Em. The curves Ep and Em are defined as # subvarieties of CP^4, but there are affine curves Ep_0 and # Em_0 in C^2 which are isomorphic to dense open subvarieties of # Ep and Em respectively. These are quartic curves which pass through # the origin, and we take the origin (not a point at infinity) as the # zero element for a group structure. #@ is_equal_CP2 is_equal_CP2 := proc(z,w) local i,j; for i from 1 to 2 do for j from i+1 to 3 do if simplify(conjugate(simplify(z[i]*w[j] - z[j]*w[i]))) <> 0 then return(false); fi; od; od; return(true); end: #@ d_CP2 d_CP2 := (u,v) -> sqrt(add(add(abs(u[i]*v[j]-u[j]*v[i])^2,j=i+1..3),i=1..2)/ (add(abs(u[i])^2,i=1..3)*add(abs(v[i])^2,i=1..3))); #@ d_CP2_0 d_CP2_0 := (u,v) -> d_CP2([u[1],u[2],1],[v[1],v[2],1]); #@ ss ss := [seq(s[i],i=1..5)]; # The curves Ep_0 and Em_0 have equations y^2 = q_Ep(x) and # y^2 = q_Em(x) respectively, where q_Ep and q_Em are given below. q_Ep := (x) -> 2*x*(x-1)*((1/a_P+a_P)^2/4*x^2-1); #@ q_Ep q_Em := (x) -> 2*x*(x-1)*((1/a_P-a_P)^2/4*x^2+1); #@ q_Em is_member_Ep_0 := (yx) -> yx[1]^2 - q_Ep(yx[2]); #@ is_member_Ep_0 is_member_Em_0 := (yx) -> yx[1]^2 - q_Em(yx[2]); #@ is_member_Em_0 #@ Ep_rel Ep_rel[0] := (z) -> z[1]^2 - 2*(z[4]-z[3])*((1/a_P+a_P)^2/4*z[4]-z[2]); Ep_rel[1] := (z) -> z[2]*z[4] - z[3]^2; #@ Em_rel Em_rel[0] := (z) -> z[1]^2 - 2*(z[4]-z[3])*((1/a_P-a_P)^2/4*z[4]+z[2]); Em_rel[1] := (z) -> z[2]*z[4] - z[3]^2; is_member_Ep := (z) -> simplify_P([seq(Ep_rel[i](z),i=0..1)]) = [0$2]; #@ is_member_Ep is_member_Em := (z) -> simplify_P([seq(Em_rel[i](z),i=0..1)]) = [0$2]; #@ is_member_Em #@ is_equal_Ep_list is_equal_Ep_list := (z,w) -> [seq(seq(z[i]*w[j]-z[j]*w[i],j=i+1..4),i=1..3)]; #@ is_equal_Ep is_equal_Ep := proc(z,w) local L,u; L := is_equal_Ep_list(z,w); for u in L do if simplify_P(conjugate(simplify_P(expand(u)))) <> 0 then return(false); fi; od; return(true); end: #@ is_equal_Em_list is_equal_Em_list := (z,w) -> [seq(seq(z[i]*w[j]-z[j]*w[i],j=i+1..4),i=1..3)]; #@ is_equal_Em is_equal_Em := proc(z,w) local L,u; L := is_equal_Em_list(z,w); for u in L do if simplify_P(conjugate(simplify_P(expand(u)))) <> 0 then return(false); fi; od; return(true); end: Ep_vars := tdeg(z[1],z[2],z[3],z[4]); #@ Ep_vars Ep_rels := Basis([Ep_rel[0](z),Ep_rel[1](z)],Ep_vars); #@ Ep_rels NF_Ep := (u) -> NormalForm(u,Ep_rels,Ep_vars); #@ NF_Ep Em_vars := tdeg(z[1],z[2],z[3],z[4]); #@ Em_vars Em_rels := Basis([Em_rel[0](z),Em_rel[1](z)],Em_vars); #@ Em_rels NF_Em := (u) -> NormalForm(u,Em_rels,Em_vars); #@ NF_Em j_Ep := (yx) -> [yx[1],1,yx[2],yx[2]^2]; #@ j_Ep j_inv_Ep := (x) -> [x[1]/x[2],x[3]/x[2]]; #@ j_inv_Ep j_Em := (yx) -> [yx[1],1,yx[2],yx[2]^2]; #@ j_Em j_inv_Em := (x) -> [x[1]/x[2],x[3]/x[2]]; #@ j_inv_Em #@ d_CP3 d_CP3 := (u,v) -> sqrt(add(add(abs(u[i]*v[j]-u[j]*v[i])^2,j=i+1..4),i=1..3)/ (add(abs(u[i])^2,i=1..4)*add(abs(v[i])^2,i=1..4))); # This function takes values in Ep_0, and has second component exp(I*t). # It is well-behaved for small positive values of t. #@ l_Ep l_Ep := (t) -> [(1/2+1/2*I)*sqrt(2)*(-a_P^2+1)*sqrt(tan((1/2)*t))* sqrt(1+I*tan((1/2)*t)*(1-a_P)^2/(1+a_P)^2)* sqrt(1+I*tan((1/2)*t)*(1+a_P)^2/(1-a_P)^2)* exp((1/2*I)*t)/((1-I*tan((1/2)*t))^(3/2)*a_P), exp(I*t)]; # The function P_to_Ep_0 gives a map from (the affine model) of # PX(a) to Ep_0, which induces an isomorphism from # PX(a)/\mu to Ep. #@ P_to_Ep_0 P_to_Ep_0 := proc(wz) local w,z; w,z := op(wz); return([2*w*(1-z)/((1+z^2)^2),2*z/(1+z^2)]); end: #@ Ep_to_P_0 Ep_to_P_0 := proc(yx) local y,x; y,x := op(yx); return [y*((2-x)*sqrt(1-x^2)-(x+2)*(x-1))/(x^3*(x-1)),(1+sqrt(1-x^2))/x]; end: #@ P_to_Ep P_to_Ep := (z) -> [2*(z[2]-z[3])*z[1], z[2]^2+2*z[2]*z[4]+z[3]*z[5], 2*z[2]*(z[3]+z[5]), 4*z[2]*z[4]]; # The function P_to_Em_0 gives a map from (the affine model) of # PX(a) to Em_0, which induces an isomorphism from # PX(a)/\lambda\mu to Em. #@ P_to_Em_0 P_to_Em_0 := proc(wz) local w,z; w,z := op(wz); return([-(1+I)*sqrt(2)*w*(I+z)/((1-z^2)^2),2*I*z/(1-z^2)]); end: #@ Em_to_P_0 Em_to_P_0 := proc(yx) local y,x; y,x := op(yx); return [(1+I)/sqrt(2)*y*((x-2)*sqrt(1-x^2)-(x+2)*(x-1))/(x^3*(x-1)), -I*(1-sqrt(1-x^2))/x]; end: #@ P_to_Em P_to_Em := (z) -> [(1-I)*sqrt(2)*z[1]*(z[2]-I*z[3]), z[2]^2-2*z[2]*z[4]+z[3]*z[5], 2*I*z[2]*(z[3]-z[5]), -4*z[2]*z[4]]; #@ P_to_Epm_0 P_to_Epm_0 := (wz) -> [op(P_to_Ep_0(wz)),op(P_to_Em_0(wz))]; #@ PJ_trans PJ_trans := (u) -> [op(Em_0_trans[1]([u[1],u[2]])),op(Ep_0_trans[1]([u[3],u[4]]))]; #@ PJ_trans P_to_PJ := proc(wz,u_) local w,z,u; w,z := op(wz); u := `if`(nargs>1,u_,sqrt(z)); return [ 1/sqrt(2)*u*(1-z)*(2*bp_P^2*(1-z)^2-bm_P^2*(w/u+1+z^2))/(bm_P^2*z- (1-z)^2)^2, (w/u - (1-z)^2)/(bm_P^2*z- (1-z)^2)/2, (1+I)/2 *u*(I+z)*(2*bm_P^2*(I+z)^2+bp_P^2*(w/u+1-z^2))/(bp_P^2*z+I*(I+z)^2)^2, I*(w/u + (I+z)^2)/(bp_P^2*z+I*(I+z)^2)/2 ]; end: #@ PJ_to_Epm_0 PJ_to_Epm_0 := (u) -> [op(Em_0_to_Ep_0([u[1],u[2]])),op(Ep_0_to_Em_0([u[3],u[4]]))]; ###################################################################### # Note that only the normaliser of M acts on Ep, and only the # normaliser of LM acts on Em. #@ act_Ep_0 act_Ep_0[1] := yx -> [ yx[1],yx[2]]; act_Ep_0[LL] := yx -> [-yx[1],yx[2]]; act_Ep_0[M] := yx -> [ yx[1],yx[2]]; act_Ep_0[LLM] := yx -> [-yx[1],yx[2]]; act_Ep_0[N] := yx -> [ conjugate(yx[1]),conjugate(yx[2])]; act_Ep_0[LLN] := yx -> [-conjugate(yx[1]),conjugate(yx[2])]; act_Ep_0[MN] := yx -> [ conjugate(yx[1]),conjugate(yx[2])]; act_Ep_0[LLMN] := yx -> [-conjugate(yx[1]),conjugate(yx[2])]; #@ act_Ep act_Ep[1] := z -> [ z[1], z[2], z[3], z[4]]; act_Ep[LL] := z -> [-z[1], z[2], z[3], z[4]]; act_Ep[M] := z -> [ z[1], z[2], z[3], z[4]]; act_Ep[LLM] := z -> [-z[1], z[2], z[3], z[4]]; act_Ep[N] := z -> map(conjugate,[ z[1], z[2], z[3], z[4]]); act_Ep[LLN] := z -> map(conjugate,[-z[1], z[2], z[3], z[4]]); act_Ep[MN] := z -> map(conjugate,[ z[1], z[2], z[3], z[4]]); act_Ep[LLMN] := z -> map(conjugate,[-z[1], z[2], z[3], z[4]]); #@ act_Em_0 act_Em_0[1] := yx -> yx; act_Em_0[LL] := yx -> [-yx[1],yx[2]]; act_Em_0[LM] := yx -> yx; act_Em_0[LLLM] := yx -> [-yx[1],yx[2]]; act_Em_0[LN] := yx -> [ conjugate(yx[1]),conjugate(yx[2])]; act_Em_0[LLLN] := yx -> [-conjugate(yx[1]),conjugate(yx[2])]; act_Em_0[MN] := yx -> [ conjugate(yx[1]),conjugate(yx[2])]; act_Em_0[LLMN] := yx -> [-conjugate(yx[1]),conjugate(yx[2])]; #@ act_Em act_Em[1] := z -> [ z[1], z[2], z[3], z[4]]; act_Em[LL] := z -> [-z[1], z[2], z[3], z[4]]; act_Em[LM] := z -> [ z[1], z[2], z[3], z[4]]; act_Em[LLLM] := z -> [-z[1], z[2], z[3], z[4]]; act_Em[LN] := z -> map(conjugate,[ z[1], z[2], z[3], z[4]]); act_Em[LLLN] := z -> map(conjugate,[-z[1], z[2], z[3], z[4]]); act_Em[MN] := z -> map(conjugate,[ z[1], z[2], z[3], z[4]]); act_Em[LLMN] := z -> map(conjugate,[-z[1], z[2], z[3], z[4]]); ###################################################################### #@ v_Ep_0 v_Ep_0[ 0] := [0,0]; v_Ep_0[ 1] := [0,0]; v_Ep_0[ 2] := [a_P-1/a_P,-1]; v_Ep_0[ 3] := [0,1]; v_Ep_0[ 4] := [1/a_P-a_P,-1]; v_Ep_0[ 5] := [0,1]; v_Ep_0[ 6] := [infinity,infinity]; v_Ep_0[ 7] := [infinity,infinity]; v_Ep_0[ 8] := [infinity,infinity]; v_Ep_0[ 9] := [infinity,infinity]; v_Ep_0[10] := [0,-2*a_P/(1+a_P^2)]; v_Ep_0[11] := [0, 2*a_P/(1+a_P^2)]; v_Ep_0[12] := [0,-2*a_P/(1+a_P^2)]; v_Ep_0[13] := [0, 2*a_P/(1+a_P^2)]; v_Ep_0[14] := [ 2*sqrt(2)*a_P*(1-a_P^2)^2/(1+a_P^2)^3, 4*a_P^2/(1+a_P^2)^2]; v_Ep_0[15] := [-2*sqrt(2)*a_P*(1-a_P^2)^2/(1+a_P^2)^3, 4*a_P^2/(1+a_P^2)^2]; #@ v_Ep for i from 0 to 15 do if not(has(v_Ep_0[i],infinity)) then v_Ep[i] := j_Ep(v_Ep_0[i]); fi; od: v_Ep[ 6] := [ a_P+1/a_P,0,0,-sqrt(2)]; v_Ep[ 7] := [-a_P-1/a_P,0,0,-sqrt(2)]; v_Ep[ 8] := [-a_P-1/a_P,0,0,-sqrt(2)]; v_Ep[ 9] := [ a_P+1/a_P,0,0,-sqrt(2)]; #@ omega_Em omega_Em := (1+I)/sqrt(2); #@ v_Em_0 v_Em_0[ 0] := [0,0]; v_Em_0[ 1] := [0,0]; v_Em_0[ 2] := [infinity,infinity]; v_Em_0[ 3] := [infinity,infinity]; v_Em_0[ 4] := [infinity,infinity]; v_Em_0[ 5] := [infinity,infinity]; v_Em_0[ 6] := [ (a_P+1/a_P),-1]; v_Em_0[ 7] := [0,1]; v_Em_0[ 8] := [-(a_P+1/a_P),-1]; v_Em_0[ 9] := [0,1]; v_Em_0[10] := [0,-2*I*a_P/(1-a_P^2)]; v_Em_0[11] := [0, 2*I*a_P/(1-a_P^2)]; v_Em_0[12] := [0, 2*I*a_P/(1-a_P^2)]; v_Em_0[13] := [0,-2*I*a_P/(1-a_P^2)]; #@ v_Em for i from 0 to 13 do if not(has(v_Em_0[i],infinity)) then v_Em[i] := j_Em(v_Em_0[i]); fi; od: v_Em[ 2] := [ a_P-1/a_P,0,0,-sqrt(2)]; v_Em[ 3] := [ a_P-1/a_P,0,0,-sqrt(2)]; v_Em[ 4] := [-a_P+1/a_P,0,0,-sqrt(2)]; v_Em[ 5] := [-a_P+1/a_P,0,0,-sqrt(2)]; for i from 0 to 8 do c_Ep_0[i] := unapply(simplify(P_to_Ep_0(pq_P(c_P[i](t)))),t); #@ c_Ep_0 c_Em_0[i] := unapply(simplify(P_to_Em_0(pq_P(c_P[i](t)))),t); #@ c_Em_0 c_Ep[i] := unapply(simplify(P_to_Ep(c_P[i](t))),t); #@ c_Ep c_Em[i] := unapply(simplify(P_to_Em(c_P[i](t))),t); #@ c_Em od: ###################################################################### # We make Ep into a group in the usual way, with the point (0,0) in Ep_0 # as the zero element, and similarly for Em. The points of order two are # as follows. #@ Ep_0_e Ep_0_e[0] := [0,0]; Ep_0_e[1] := [0,1]; Ep_0_e[2] := [0, 2*a_P/(1+a_P^2)]; Ep_0_e[3] := [0,-2*a_P/(1+a_P^2)]; #@ Ep_0_e Em_0_e[0] := [0,0]; Em_0_e[1] := [0,1]; Em_0_e[2] := [0, 2*I*a_P/(1-a_P^2)]; Em_0_e[3] := [0,-2*I*a_P/(1-a_P^2)]; for i from 0 to 3 do Ep_e[i] := j_Ep(Ep_0_e[i]); #@ Ep_e Em_e[i] := j_Em(Em_0_e[i]); #@ Em_e od: # The map Ep_0_trans[i] is u |-> u + Ep_0_e[i]. #@ Ep_0_trans Ep_0_trans[0] := (yx) -> yx; Ep_0_trans[1] := (yx) -> [ 4*a_P^2*(1-a_P^2)^2 * yx[1]/((1+a_P^2)^2*yx[2] - 4*a_P^2)^2, 4*a_P^2*(yx[2]-1)/((1+a_P^2)^2*yx[2] - 4*a_P^2) ]; Ep_0_trans[2] := (yx) -> [ -8*a_P^2*(1-a_P)^2/(1+a_P^2)*yx[1]/((1-a_P)^2*yx[2]+2*a_P*(1-yx[2]))^2, 2*a_P/(1+a_P^2)*(2*a_P-(1+a_P^2)*yx[2])/((1-a_P)^2*yx[2]+2*a_P*(1-yx[2])) ]; Ep_0_trans[3] := (yx) -> [ -8*a_P^2*(1+a_P)^2/(1+a_P^2)*yx[1]/((1+a_P)^2*yx[2]-2*a_P*(1-yx[2]))^2, 2*a_P/(1+a_P^2)*(2*a_P+(1+a_P^2)*yx[2])/((1+a_P)^2*yx[2]-2*a_P*(1-yx[2])) ]; #@ Ep_trans Ep_trans[0] := (z) -> [z[1],z[2],z[3],z[4]]; Ep_trans[1] := (z) -> [bm_P^2*z[1], z[2]-2*bp_P^2*z[3]+bp_P^4*z[4], z[2] - (1+bp_P^2)*z[3] + bp_P^2*z[4], z[2]-2*z[3]+z[4]] /~ bm_P^2; Ep_trans[2] := (z) -> [ 2*(1-bp_P)*z[1], bp_P*z[2]+(2*bp_P^2-4*bp_P)*z[3]+(bp_P^3-4*bp_P^2+4*bp_P)*z[4], z[2]-2*z[3]-(bp_P^2-2*bp_P)*z[4], z[2]/bp_P-2*z[3]+bp_P*z[4]] /~ ( 2*(1-bp_P)); Ep_trans[3] := (z) -> [-2*(1+bp_P)*z[1], bp_P*z[2]-(2*bp_P^2+4*bp_P)*z[3]+(bp_P^3+4*bp_P^2+4*bp_P)*z[4], -z[2]+2*z[3]+(bp_P^2+2*bp_P)*z[4], z[2]/bp_P+2*z[3]+bp_P*z[4]] /~ (-2*(1+bp_P)); # The map Em_0_trans[i] is u |-> u + Em_0_e[i]. #@ Em_0_trans Em_0_trans[0] := (yx) -> yx; Em_0_trans[1] := (yx) -> [ -4*a_P^2*(1+a_P^2)^2*yx[1]/((1-a_P^2)^2*yx[2]+4*a_P^2)^2, -(4*a_P^2*(yx[2]-1)/((1-a_P^2)^2*yx[2]+4*a_P^2)) ]; Em_0_trans[2] := (yx) -> [ -8*a_P^2*(I+a_P)^2/(1-a_P^2)*yx[1]/((I+a_P)^2*yx[2]+2*I*a_P*(yx[2]-1))^2, -2*I*a_P/(1-a_P^2)*(2*I*a_P-(1-a_P^2)*yx[2])/((I+a_P)^2*yx[2]+2*I*a_P*(yx[2]-1)) ]; Em_0_trans[3] := (yx) -> [ -8*a_P^2*(I-a_P)^2/(1-a_P^2)*yx[1]/((I-a_P)^2*yx[2]-2*I*a_P*(yx[2]-1))^2, -2*I*a_P/(1-a_P^2)*(2*I*a_P+(1-a_P^2)*yx[2])/((I-a_P)^2*yx[2]-2*I*a_P*(yx[2]-1)) ]; #@ Em_trans Em_trans[0] := (z) -> [z[1],z[2],z[3],z[4]]; Em_trans[1] := (z) -> [bp_P^2*z[1], -z[2]-2*bm_P^2*z[3]-bm_P^4*z[4], -z[2] + (1-bm_P^2)*z[3] + bm_P^2*z[4], -z[2] + 2*z[3] - z[4]] /~ (bp_P^2); Em_trans[2] := (z) -> [(I-bm_P)*z[1], -(-bm_P/2*z[2]+bm_P*(bm_P-2*I)^2/2*z[4]+(bm_P*2+I*bm_P^2)*z[3]), -(-I/2*z[2]+I*z[3]-(I/2*bm_P^2+bm_P)*z[4]), -(z[2]/(2*bm_P)+I*z[3]-bm_P/2*z[4])] /~ (I-bm_P); Em_trans[3] := (z) -> [(I+bm_P)*z[1], (-bm_P/2*z[2]+bm_P*(bm_P+2*I)^2/2*z[4]+(bm_P*2-I*bm_P^2)*z[3]), (I/2*z[2]-I*z[3]-(-I/2*bm_P^2+bm_P)*z[4]), (z[2]/(2*bm_P)-I*z[3]-bm_P/2*z[4])] /~ ((bm_P+I)); ###################################################################### # It turns out that Ep and Em are isogenous. It should be possible to # see this abstractly using some representation theory and duality # theory for Jacobians. More specifically, the function # Ep_0_to_Em_0 defines an isogeny Ep -> Em with kernel generated by # the point Ep_0_e[1], whereas Em_0_to_Ep_0 is an isogeny in the # opposite direction with kernel generated by Em_0_e[1]. #@ Ep_0_to_Em_0 Ep_0_to_Em_0 := proc(yx) local y,x; y,x := op(yx); return [y*sqrt(2)*((1-x)^2+bm_P^2*x^2)/((1-x)^2-bm_P^2*x^2)^2, 2*x*(x-1)/((1-x)^2-bm_P^2*x^2)]; end: #@ Em_0_to_Ep_0 Em_0_to_Ep_0 := proc(yx) local y,x; y,x := op(yx); return [y*sqrt(2)*((1-x)^2-bp_P^2*x^2)/((1-x)^2+bp_P^2*x^2)^2, 2*x*(x-1)/((1-x)^2+bp_P^2*x^2)]; end: #@ Ep_to_Em Ep_to_Em := (z) -> [ sqrt(2)*z[1]*(z[2]-2*z[3]+bp_P^2*z[4]), (2-bp_P^2)^2*z[4]^2 +(z[2]-2*z[3]+2*(2-bp_P^2)*z[4])*(z[2]-2*z[3]), 2*(z[2]-bp_P^2*z[4])*(z[4]-z[3])+4*(z[4]^2-2*z[3]*z[4]+z[2]*z[4]), 4*(z[4]^2-2*z[3]*z[4]+z[2]*z[4]) ]; #@ Em_to_Ep Em_to_Ep := (z) -> [ sqrt(2)*z[1]*(z[2]-2*z[3]-bm_P^2*z[4]), (2+bm_P^2)^2*z[4]^2 +(z[2]-2*z[3]+2*(2+bm_P^2)*z[4])*(z[2]-2*z[3]), 2*(z[2]+bm_P^2*z[4])*(z[4]-z[3])+4*(z[4]^2-2*z[3]*z[4]+z[2]*z[4]), 4*(z[4]^2-2*z[3]*z[4]+z[2]*z[4]) ]; #@ Epm_w Epm_w[1] := [ 2*bm_P/(1+bm_P)^2, 1/(1+bm_P)]; Epm_w[2] := [ 2*bm_P/(1-bm_P)^2, 1/(1-bm_P)]; Epm_w[3] := [-2*bm_P/(1+bm_P)^2, 1/(1+bm_P)]; Epm_w[4] := [-2*bm_P/(1-bm_P)^2, 1/(1-bm_P)]; ###################################################################### #@ P_0_to_J_0 P_0_to_J_0 := proc(wz) local w,z,ym,xm,yp,xp; w,z := op(wz); ym := 1/sqrt(2)*sqrt(z)*(1-z)*(2*bp_P^2*(1-z)^2-bm_P^2*(w/sqrt(z)+1+z^2))/(bm_P^2*z- (1-z)^2)^2; yp := (1+I)/2 *sqrt(z)*(I+z)*(2*bm_P^2*(I+z)^2+bp_P^2*(w/sqrt(z)+1-z^2))/(bp_P^2*z+I*(I+z)^2)^2; xm := (w/sqrt(z) - (1-z)^2)/(bm_P^2*z- (1-z)^2)/2; xp := I*(w/sqrt(z) + (I+z)^2)/(bp_P^2*z+I*(I+z)^2)/2; return [ym,xm,yp,xp]; end: ###################################################################### # The curves Ep_0 and Em_0 can be parametrised using the # Weierstrass P-function and its derivative. More specifically, the # function C_to_Ep_0 gives a universal covering of Ep by C, with kernel # generated by latt_a (in R) and latt_b (in iR). Similarly, the function # C_to_Em_0 gives a universal covering of Em by C, with kernel # generated by latt_e and latt_f. The numbers latt_c (in R) and # latt_d (in iR) generate a subgroup of index 2 in the kernel. Wg2p := 4*(1/3+bp_P^2); #@ Wg2p Wg3p := 8/3*(1/9-bp_P^2); #@ Wg3p WPp := (z) -> WeierstrassP(z/sqrt(2),Wg2p,Wg3p): #@ WPp WPPp := (z) -> WeierstrassPPrime(z/sqrt(2),Wg2p,Wg3p): #@ WPPp Wg2m := 4*(1/3-bm_P^2); #@ Wg2m Wg3m := 8/3*(1/9+bm_P^2); #@ Wg3m WPm := (z) -> WeierstrassP(I*z/sqrt(2),Wg2m,Wg3m): #@ WPm WPPm := (z) -> WeierstrassPPrime(I*z/sqrt(2),Wg2m,Wg3m): #@ WPPm C_to_Ep_0 := (z) -> [- WPPp(z)/(WPp(z)+1/3)^2/sqrt(2), 1/(WPp(z)+1/3)]; #@ C_to_Ep_0 C_to_Em_0 := (z) -> [I*WPPm(z)/(WPm(z)+1/3)^2/sqrt(2), 1/(WPm(z)+1/3)]; #@ C_to_Em_0 latt_a := ap_period; #@ latt_a latt_b := am_period*I; #@ latt_b latt_c := ap_period*sqrt(2); #@ latt_c latt_d := am_period*sqrt(2)*I; #@ latt_d latt_e := (ap_period+am_period*I)/sqrt(2); #@ latt_e latt_f := (ap_period-am_period*I)/sqrt(2); #@ latt_f # These are isomorphisms C -> R^2 that send the relevant lattices to Z^2 #@ div_Ep div_Ep := (z) -> [ Im(z/latt_b0)/Im(latt_a0/latt_b0), Im(z/latt_a0)/Im(latt_b0/latt_a0)]; #@ div_Em div_Em := (z) -> [ Im(z/latt_e0)/Im(latt_f0/latt_e0), Im(z/latt_f0)/Im(latt_e0/latt_f0)]; #@ div_Emq div_Emq := (z) -> [-2*Im(z/latt_c0)/Im(latt_d0/latt_c0), 2*Im(z/latt_d0)/Im(latt_c0/latt_d0)]; ###################################################################### #@ d_Ep d_Ep[0] := (t) -> [(1+a_P)^2*sin(t)*sqrt((1-a_P)^2/a_P + (1+a_P)^2/a_P*sin(t/2)^2)/(4*a_P), (1/a_P)*((a_P+1)^2/4*cos(t)-(1-a_P)^2/4)]; d_Ep[1] := (t) -> [I*(1-a_P)^2*sin(t)*sqrt((1+a_P)^2/a_P+(1-a_P)^2/a_P*sin(t/2)^2)/(4*a_P), (1/a_P)*((1+a_P)^2/4-(1-a_P)^2/4*cos(t))]; ###################################################################### # Near v[0], the functions below are inverse to C_to_Ep_0 and C_to_Em_0 #@ Ep_0_to_C Ep_0_to_C := (yx) -> 2/(sqrt(a_P)-1/sqrt(a_P))* EllipticF((sqrt(a_P)-1/sqrt(a_P))*yx[1]/2/(1-yx[2])/sqrt(1-yx[2]^2/4*(a_P+1/a_P)^2), I*(1+a_P)/(1-a_P)); #@ Em_0_to_C Em_0_to_C := (yx) -> sqrt(2)*(1-I)/(1/sqrt(a_P)-I*sqrt(a_P))* EllipticF((1+I)/sqrt(2)*yx[1]/2*(1/sqrt(a_P)-I*sqrt(a_P))/(1-yx[2])/sqrt(1+yx[2]^2/4*(1/a_P-a_P)^2), -I*(1+I*a_P)/(1-I*a_P)); ###################################################################### #@ find_ca #@ ca #@ ca_string find_ca := proc() global i,ca,ca_string; ca[0] := fsolve(Re(C_to_Ep0_0(t*latt_a0+latt_b0/2)[2])+1=0,t=0.271..0.272); ca[1] := Re(fsolve(Ep0_0_trans[1](C_to_Ep0_0(t*latt_a0 + latt_b0/2))[2] - v_Ep0_0[14][2],t = 0.33)); ca[2] := brent_fsolve((t) -> table(["err" = Re(1/C_to_Em0_0(t*latt_c0)[2])]),0.37,0.4,false,false,10.^(-90))[1]; ca[3] := brent_fsolve((t) -> table(["err" = Re(3*C_to_Em0_0(latt_c0/2+t*latt_d0)[2]-1)]),0.1,0.2,false,false,10.^(-90))[1]; ca[4] := evalf(1/4 - 1/sqrt(8) + ca[1]/sqrt(2)); ca_string := ""; for i from 0 to 4 do ca_string := cat(ca_string,sprintf("ca[%d] := %A;\n",i,ca[i])); od: end: ca[0] := .2712198345337267409183751260826859683620639254846839852546832980918572068609141666452521341087864403; ca[1] := .3380191917841065905435356360705057573602229775275223773576731512721457153287874464581375181454782068; ca[2] := .3856099172668633704591875630413429841810319627423419926273416490459286034304570833226260670543932199; ca[3] := .1690819268841186594794124671806576109783450143041054095003132968033979158300508721043901321239984256; ca[4] := .1354622720884641394270016572560535181460733569063074476782555872580258479260520219330188552098104961; #@ v_TEp v_TEp[ 0] := 0; v_TEp[ 1] := 0; v_TEp[ 2] := ca[0]*latt_a0 + latt_b0/2; v_TEp[ 3] := 1/2*latt_a0 + latt_b0/2; v_TEp[ 4] := -ca[0]*latt_a0 + latt_b0/2; v_TEp[ 5] := 1/2*latt_a0 + latt_b0/2; v_TEp[10] := latt_b0/2; v_TEp[12] := latt_b0/2; ###################################################################### # These are maps R -> C such that the composite with C_to_Ep_0 is # approximately the same as the composite # # c[k] # R ------> PX_0 ----> Ep_0 #@ c_TEp_approx c_TEp_approx[0] := (t) -> (1/2 - (1/2 - ca[0])*cos(t))*latt_a0+latt_b0/2; c_TEp_approx[1] := (t) -> latt_b0 * t/Pi + c_TEp_a[1,1]*sin(t) + c_TEp_a[1,2]*sin(2*t)*I + c_TEp_a[1,3]*sin(3*t); c_TEp_approx[2] := (t) -> latt_b0 * t/Pi - c_TEp_a[1,1]*sin(t) + c_TEp_a[1,2]*sin(2*t)*I - c_TEp_a[1,3]*sin(3*t); c_TEp_approx[3] := (t) -> latt_a0/2 + t*latt_b0/Pi + c_TEp_a[3,2] * sin(2*t) * I; c_TEp_approx[4] := (t) -> latt_b0/2 - c_TEp_a[4,1] * sin(t) - c_TEp_a[4,3] * sin(3*t); c_TEp_approx[5] := (t) -> t*latt_a0/(2*Pi) + c_TEp_a[5,1] * sin(t) + c_TEp_a[5,2] * sin(2*t) + c_TEp_a[5,3] * sin(3*t); c_TEp_approx[6] := (t) -> t*latt_b0/(2*Pi) + (c_TEp_a[6,1] * sin(t) + c_TEp_a[6,2] * sin(2*t) + c_TEp_a[6,3] * sin(3*t)) * I; c_TEp_approx[7] := unapply(c_TEp_approx[5]( t),t); c_TEp_approx[8] := unapply(c_TEp_approx[6](-t),t); #@ c_TEp_a c_TEp_a[1,1] := 0.6247347995397494979304990644922278959925160558822906310627061638472069242981199313035975369049495378; c_TEp_a[1,2] := 0.1271025486963173673053533258315918977758877826348357864853356763913426014752169850359977340543651160; c_TEp_a[1,3] := 0.04381746206649332486668820474497225695049799820309213349946374104678578367977790428958078654155281204; c_TEp_a[3,2] := 0.1042805083196201573848763132278556884018577757032944082115538163208094109327358933030888052414138109; c_TEp_a[4,1] := 0.4968296088425958313893062468630599274335873218089671291381643204020161460960238235450241440954199888; c_TEp_a[4,3] := 0.03071315983358916926430176920663159406977183930465613106149221110811287954564497454251589873134635628; c_TEp_a[5,1] := 0.03427325618888229644323397515847565305897064093054365551658309204485785383605755460381667885437777016; c_TEp_a[5,2] := 0.002482478177069518908910207898024965359042928275607876444506771571486982421239589861216569732858358200; c_TEp_a[5,3] := 0.000238565053005790472482742854541616044857974248413386109265566228277239808644583552185718631302795458; c_TEp_a[6,1] := 0.0558713002227124085540383146452715943529179849726750467583063953157534082410475171178334557306278623; c_TEp_a[6,2] := 0.00332541457691846974120052631026377039577655088554540434419946854408626923142436070630415134361428515; c_TEp_a[6,3] := 0.00030771228226226118360872862753417350317298244674914294818400377809424655149917305792839447143257881; #@ c_Ep_0_approx[k] for k from 0 to 8 do c_Ep_0_approx[k] := unapply(C_to_Ep0_0(c_TEp_approx[k](t)),t); od: #@ c_TEm_approx c_TEm_approx[0] := (t) -> (1/2 - (1/2-ca[1])*sin(t+Pi/4))*latt_c0; c_TEm_approx[1] := (t) -> c_TEm_a[1,1] * sin(t) + c_TEm_a[1,3] * sin(3*t); c_TEm_approx[2] := (t) -> latt_d0 * t/Pi + c_TEm_a[2,2] * sin(2*t) * I; c_TEm_approx[3] := (t) -> latt_c0/4 + (t/(2*Pi)-1/4)*latt_d0 + c_TEm_a[3,1] * sin(t) + c_TEm_a[3,2] * sin(2*t) * I + c_TEm_a[3,3] * sin(3*t); c_TEm_approx[4] := (t) -> latt_c0/4 + (t/(2*Pi)+1/4)*latt_d0 - c_TEm_a[3,1] * sin(t) + c_TEm_a[3,2] * sin(2*t) * I - c_TEm_a[3,3] * sin(3*t); c_TEm_approx[5] := (t) -> t/(4*Pi)*(latt_c0 - latt_d0) + add(c_TEm_a[5,k] * sin(k*t),k=1..3); c_TEm_approx[6] := (t) -> t/(4*Pi)*(latt_c0 + latt_d0) + add(conjugate(c_TEm_a[5,k]) * sin(k*t),k=1..3); c_TEm_approx[7] := eval(c_TEm_approx[6]); c_TEm_approx[8] := eval(c_TEm_approx[5]); #@ c_TEm_a c_TEm_a[1,1] := 0.8835084263955505585783987716840000325926615540942614052941584433964337822854465613444230237701180424; c_TEm_a[1,3] := 0.06196724912320348395700677267078302081353815486017812159352605843249840400768595265032504859994172416; c_TEm_a[2,2] := 0.1797501481785187719080376142790183135790694888474575684045644044454056920630789380074211242867244138; c_TEm_a[3,1] := 0.3511321628863063015929856160517480228866539212422554128973412749459584607846880678817297806565675990; c_TEm_a[3,2] := 0.07373745457838359930142006274768329182000846163947333927778741589054611329411213393198338264266919790; c_TEm_a[3,3] := 0.0218969062105503030917796584579880912692573475308448365690517306473414539254961242930202103669553839; c_TEm_a[4,1] := 0.3511321628863063015929856160517480228866539212422554128973412749459584607846880678817297806565675990; c_TEm_a[4,2] := 0.0737374545783835993014200627476832918200084616394733392777874158905461132941121339319833826426691980; c_TEm_a[4,3] := 0.0218969062105503030917796584579880912692573475308448365690517306473414539254961242930202103669553839; c_TEm_a[5,1] := 0.2423485186450247972105483564735158211534303209384437520256882975599151270558722587190358743762353599e-1- 0.3950697526118940704300624129705708722011083550171984012465296564337878450572058529379116267915483335e-1*I; c_TEm_a[5,2] := 0.1755377153153475687209569034468230122971514325013707849129110392164278545559798591021656717836478500e-2- 0.2351423197595643895076828999665351369198735842034167404505480689584486014610436048646424754749428350e-2*I; c_TEm_a[5,3] := 0.1686909667345225954045278047227347451235211096899810957501328202832040081462419337428583331437649896e-3- 0.2175854414420338678065767392569984415709072283534971244700121606992596899087070672886264959461280586e-3*I; #@ c_Em_0_approx c_Em_0_approx[0] := (t) -> C_to_Em0_0(c_TEm_approx[0](t)); c_Em_0_approx[1] := (t) -> C_to_Em0_0(c_TEm_approx[1](t)); c_Em_0_approx[2] := (t) -> C_to_Em0_0(c_TEm_approx[2](t)); c_Em_0_approx[3] := (t) -> C_to_Em0_0(c_TEm_approx[3](t)); c_Em_0_approx[4] := (t) -> C_to_Em0_0(c_TEm_approx[4](t)); c_Em_0_approx[5] := (t) -> C_to_Em0_0(c_TEm_approx[5](t)); c_Em_0_approx[6] := (t) -> C_to_Em0_0(c_TEm_approx[6](t)); c_Em_0_approx[7] := (t) -> C_to_Em0_0(c_TEm_approx[7](t)); c_Em_0_approx[8] := (t) -> C_to_Em0_0(c_TEm_approx[8](t)); ###################################################################### # The second component of C_to_Ep0_0 gives a doubly periodic map from C # to C, which is real on the lines of a square grid, and purely # imaginary on curves corresponding to C1 and C2. It is useful to # understand the preimage of the unit circle under this map. One # component of the preimage (which we call the base component) is a # figure eight centred at the point (latt_a0+latt_b0)/2. This should # be thought of as two separate lobes that happen to meet. The other # components are translates of the base component by multiples of # latt_a0 and latt_b0. # These maps land in the relevant locus, but are discontinuous. #@ Ep0_circle_lift_a Ep0_circle_lift_a := unapply(evalf(subs(a_P=a_P0,simplify(Ep_0_to_C( l_Ep(t))))),t): #@ Ep0_circle_lift_b Ep0_circle_lift_b := unapply(evalf(subs(a_P=a_P0,simplify(Ep_0_to_C([-1,1] *~ l_Ep(t))))),t): # This map is a continuous parametrisation of the right hand lobe of # the base component, satisfying # C_to_Ep0_0(Ep0_circle_lift_c(t))[2] = exp(I*t). #@ Ep0_circle_lift_c Ep0_circle_lift_c := proc(t) local s0,n0; s0 := evalf(t/(2*Pi)); n0 := floor(s0); s0 := s0 - n0; if s0 < 0.5 then Ep0_circle_lift_a(Pi*( 2*s0)) + latt_a0 + latt_b0; else Ep0_circle_lift_b(Pi*(-2+2*s0)) + latt_a0; fi; end: # This map is a continuous parametrisation of the left hand lobe of # the base component, satisfying # C_to_Ep0_0(Ep0_circle_lift_d(t))[2] = exp(I*t). #@ Ep0_circle_lift_d Ep0_circle_lift_d := (t) -> latt_a0 + latt_b0 - Ep0_circle_lift_c(t); # This is an approximation to Ep0_circle_lift_c #@ Ep0_circle_lift_e Ep0_circle_lift_e := (t) -> sqrt(0.077410-0.076893*cos(t)-0.00051645*cos(2*t)+ I*(0.076738*sin(t)+0.00033641*sin(2*t))) + (latt_a0+latt_b0)/2; # The image of this map is approximately the same as the base # component, but the parametrisation is arbitrary. #@ Ep0_circle_lift_f Ep0_circle_lift_f := (t) -> latt_a0/2+latt_b0/2+ 0.393*sin(t)+I*(0.13254*sin(2.*t)+0.01876*sin(4.*t)); # These functions give implicit equations for the relevant locus. #@ Ep0_circle_cos_equation Ep0_circle_cos_equation := (u) -> 0.331208-0.0885156*u[1]^3-0.367140*u[1]^2*u[2]-0.269277*u[1]*u[2]^2- 0.0788400*u[2]^3-0.165916*u[1]^2-0.715646*u[1]*u[2]-0.338685*u[2]^2- 0.116555*u[1]+0.0312848*u[2]; #@ Ep0_circle_equation Ep0_circle_equation := (z) -> Ep0_circle_cos_equation([cos(Re(z)/latt_a0*2*Pi),cos(Im(z)/abs(latt_b0)*2*Pi)]);