(* ::Package:: *) BeginPackage["GridZeta`",{"ComplexUtilities`"}] from::inverse = "Inverse functions are being used, and values will be missed."; (* Conversions only involving hyperbolic space *) tfrom\[Tau]::usage= "Convert \[Tau] \[Element] H to t=\!\(\*SqrtBox[\(q\)]\)."; qfrom\[Tau]::usage= "Convert \[Tau] \[Element] H to q."; \[Tau]fromq::usage= "Convert q to (one value of) \[Tau] \[Element] H. (Warning: logarithm)"; \[Tau]fromt::usage= "Convert t=\!\(\*SqrtBox[\(q\)]\) to (one value of) \[Tau] \[Element] H. (Warning: logarithm)"; qfromt::usage = "Convert t to q=\!\(\*SuperscriptBox[\(t\), \(2\)]\)."; tfromq::usage = "Convert q to t=\!\(\*SqrtBox[\(q\)]\). (Warning: square root)"; (* Conversions involving elliptic parameters m and k *) mfromk::usage = "Convert k to m=\!\(\*SuperscriptBox[\(k\), \(2\)]\)."; kfromm::usage = "Convert m=\!\(\*SuperscriptBox[\(k\), \(2\)]\) to k. (Warning: square root)"; mfromq::usage = "Convert the nome q to m=\!\(\*SuperscriptBox[\(k\), \(2\)]\). Uses InverseEllipticNomeQ."; mfromt::usage = "Convert t=\!\(\*SqrtBox[\(q\)]\) to m=\!\(\*SuperscriptBox[\(k\), \(2\)]\). Uses InverseEllipticNomeQ."; mfrom\[Tau]::usage = "Convert m=\!\(\*SuperscriptBox[\(k\), \(2\)]\) to \[Tau] \[Element] H. Uses InverseEllipticNomeQ."; kfromq::usage = "Convert q to k. (Warning: square root, use kfromt if possible.)"; kfromt::usage = "Convert t=\!\(\*SqrtBox[\(q\)]\) to k. Uses QPochhammer."; kfrom\[Tau]::usage = "Convert \[Tau] \[Element] H to k. Uses QPochhammer."; qfromm::usage = "Convert m=\!\(\*SuperscriptBox[\(k\), \(2\)]\) to q. Uses EllipticNomeQ."; \[Tau]fromm::usage = "Convert m=\!\(\*SuperscriptBox[\(k\), \(2\)]\) to \[Tau] \[Element] H. Uses EllipticK."; tfromm::usage = "Convert m=\!\(\*SuperscriptBox[\(k\), \(2\)]\) to t=\!\(\*SqrtBox[\(q\)]\). Uses EllipticK."; \[Tau]fromk::usage = "Convert k to \[Tau] \[Element] H. Built piecewise from \[Tau]fromm."; tfromk::usage = "Convert k to t=\!\(\*SqrtBox[\(q\)]\). Uses \[Tau]fromk."; qfromk::usage = "Convert k to q. Uses qfromm[\!\(\*SuperscriptBox[\(k\), \(2\)]\)]."; (* Conversions Involving u *) kfromu::usage = "Convert u to k"; mfromu::usage = "Convert u to m=\!\(\*SuperscriptBox[\(k\), \(2\)]\)"; ufromk::usage = "Convert k to a list of two u values."; tfromu::usage = "Convert u to t=\!\(\*SqrtBox[\(q\)]\)"; ufromt::usage = "Convert t=\!\(\*SqrtBox[\(q\)]\)to a list of two u values."; (* Modular group and fundamental domains *) fundDomain\[Tau]m::usage = "Graphics directives describing the edge of the fundamental domain for m in the \[Tau] plane."; fundDomain\[Tau]k::usage = "Graphics directives describing the edge of the fundamental domain for k in the \[Tau] plane."; fundDomaintk::usage = "Graphics directives describing the edge of the fundamental domain for k in the t disk."; fundDomainqm::usage = "Graphics directives describing the edge of the fundamental domain for m in the q disk."; fundtk::usage = "fundtk[g] plots the fundamental domain for k in the t disk, after applying the mobius transformation given by 2x2 matrix g."; fund\[Tau]::usage = "fund\[Tau][x,y] runs over the fundamental domain in the \[Tau] plane.\ Using (x,y)\[Element](-1,1]\[Times][0,1) gives the fundamental domain for m,\ and using (x,y)\[Element](-2,2]\[Times][0,1) gives the fundamental domain for k."; generatorU::usage = "The 2x2 matrix (\[NoBreak]\*GridBox[{ {1, 2}, {0, 1} }]\[NoBreak]), a generator for \[CapitalGamma](2)."; generatorV::usage = "The 2x2 matrix (\[NoBreak]\*GridBox[{ {1, 0}, {2, 1} }]\[NoBreak]), a generator for \[CapitalGamma](2)."; (* Elliptic integrals *) Kfromq::usage = "The elliptic integral K as a function of q. Equal to EllipticK[mfromq[q]] for q \[Element] (-1,1), but analytic on the disk."; (* Zeta Function Related *) gridZetaf::usage = "This is f(t) = (1-\!\(\*SuperscriptBox[SubscriptBox[\(\[Theta]\), \(3\)], \(2\)]\)\!\(\*SuperscriptBox[SubscriptBox[\(\[Theta]\), \(4\)], \(4\)]\))/t from the zetagrid paper."; gridZetaF::usage = "This is F(t), the primitive for zetaf[t] = f(t)."; gridZetat::usage = "This is the zeta function for the grid, as a function of t. It is a list of the two values for each t."; gridZeta::usage = "This is the zeta function for the grid, as a function of u."; trLogDeltaCoefficient::usage = "trLogDeltaCoefficient[n] is the coefficient of \!\(\*SuperscriptBox[\(u\), \(2 n\)]\) in the power series for \!\(\*SubscriptBox[\(Tr\), \(\[Pi]\)]\)\!\(\*SubscriptBox[\(Log\[CapitalDelta]\), \(u\)]\), as a function of u. Computed using the combinatorical formula."; baduSet3D::usage = "baduSet3D[edgeform,height] gives the set on which u has issues, at given height (default is 1)."; baduSet::usage = "baduSet[edgeform] gives the set on which u has issues."; Begin["`Private`"] Kfromq[q_]:=(Pi/2)*EllipticTheta[3,0,q]^2 (* Conversions only involving hyperbolic space *) tfrom\[Tau][\[Tau]_]:=Exp[I Pi \[Tau]/2] qfrom\[Tau][\[Tau]_]:=Exp[I Pi \[Tau]] \[Tau]fromq[q_]:=(Message[from::inverse]; Log[q]/(I Pi)) \[Tau]fromt[t_]:=(Message[from::inverse]; 2 Log[t]/(I Pi)) qfromt[t_]:=t^2 tfromq[q_]:=(Message[from::inverse]; Sqrt[q]) (* Conversions involving elliptic parameters m and k *) mfromk[k_]:=k^2 kfromm[m_]:=(Message[from::inverse]; Sqrt[m]) mfromq[q_]:=InverseEllipticNomeQ[q] mfromt[t_]:=InverseEllipticNomeQ[t^2] mfrom\[Tau][\[Tau]_]:=InverseEllipticNomeQ[qfrom\[Tau][\[Tau]]] kfromq[q_]:=kfromm[mfromq[q]] kfromt[t_]:=(4t)/(QPochhammer[-t^2,t^4]QPochhammer[t^4,t^8])^4 kfrom\[Tau][\[Tau]_]:=kfromt[tfrom\[Tau][\[Tau]]] qfromm[m_]:=EllipticNomeQ[m] \[Tau]fromm[m_]:=(I EllipticK[1-m])/EllipticK[m] tfromm[m_]:=tfrom\[Tau][\[Tau]fromm[m]] qfromk[k_]:=qfromm[k^2] \[Tau]fromk[k_]:= If[Re[k]>=0,\[Tau]fromm[k^2], If[Im[k]>=0,\[Tau]fromm[k^2]+2, \[Tau]fromm[k^2]-2]] tfromk[k_]:=tfrom\[Tau][\[Tau]fromk[k]] (* Conversions Involving u *) kfromu[u_]:=(4u)/(1+3u^2) mfromu[u_]:=kfromu[u]^2 ufromk[k_]:={(2-Sqrt[4-3 k^2])/(3 k),(2+Sqrt[4-3 k^2])/(3 k)} tfromu[u_]:=tfromk[kfromu[u]] ufromt[t_]:=ufromk[kfromt[t]] fundDomain\[Tau]m = {Arrow[{{1,0},{1,4}}],Arrow[{{-1,0},{-1,4}}], Circle[{1/2,0},1/2,{0,Pi}],Circle[{-1/2,0},1/2,{0,Pi}]}; fundDomain\[Tau]k = {Arrow[{{2,0},{2,4}}],Arrow[{{-2,0},{-2,4}}], Circle[{1/2,0},1/2,{0,Pi}],Circle[{-1/2,0},1/2,{0,Pi}], Circle[{3/2,0},1/2,{0,Pi}],Circle[{-3/2,0},1/2,{0,Pi}]}; fundDomaintk = (ParametricPlot[ Evaluate[Table[ComplexSplit[tfrom\[Tau][c/2+Exp[2I x]/2]],{c,{1,3,-3,-1}}]], {x,0,\[Pi]/2}] //Graphics)[[1]]//Flatten//Cases[#,_Line]&; fundDomainqm = (ParametricPlot[ Evaluate[Table[ComplexSplit[qfrom\[Tau][c/2+Exp[2I x]/2]],{c,{1,-1}}]], {x,0,\[Pi]/2}] //Graphics)[[1]]//Flatten//Cases[#,_Line]&; fundtk[g_,options___]:=ParametricPlot[Evaluate[ ComplexSplit/@ (tfrom\[Tau]/@ (MobiusTransformation[g,#]&/@ {-2+I t^3,-3/2+(1/2)Exp[I t],-1/2+(1/2)Exp[I t], 1/2+(1/2)Exp[I t],3/2+(1/2)Exp[I t],2+I t^3}) ) ],{t,0,Pi},Axes->None,options] (* smoothedge numerically solves the heat equation to get a smooth approximation to the edge of the \[Tau] fundamental domain, which consists of half circles and has cusps at each integer. *) smoothedge=f/.NDSolve[{D[f[x,t],t] == D[f[x,t],x,x], f[x,0]==Sqrt[1/4-(Abs[x]-1/2)^2]-1/2, f[-1/2,t]==0, f[1/2,t]==0}, f,{x,-1/2,1/2},{t,0,1}][[1]]; (* To produce the fundamental domain for k in the \[Tau] half plane, replicate the smoothed edge periodically and add some ad-hoc terms to stretch it out nicely over the domain *) fund\[Tau][x_,y_]:=x+I * (smoothedge[Mod[x-1/2,1]-1/2,y^4]+1/(2-2y)) (* Some routines for working with the modular group \[CapitalGamma](2) *) generatorU = {{1,2},{0,1}}; generatorV = {{1,0},{2,1}}; Kfromq[q_]:=(Pi/2)*EllipticTheta[3,0,q]^2 (* This gives the grid zeta function using elliptic theta functions *) gridZetaf[t_]:=(1-(EllipticTheta[3,0,t^2]^2)(EllipticTheta[4,0,t^2]^4))/t; gridZetaF[t_]:=Evaluate[Normal[Integrate[Series[gridZetaf[t],{t,0,256}],t]]]; gridZetat[t_]:=t Exp[-gridZetaF[t]]/((#-#^3)&@ufromt[t]); gridZeta[u_]:=((#*Exp[-gridZetaF[#]])&@tfromu[u])/(u-u^3); trLogDeltaCoefficient[n_] := -Sum[(-3)^(n-k)/(n+k) Binomial[n+k,2k]Binomial[2k,k]^2,{k,0,n}] baduSet3D[edge_List,height_:1] := Graphics3D[Join[ {{FaceForm[None],EdgeForm[edge], Polygon[Table[{(1/Sqrt[3])Cos[x],(1/Sqrt[3])Sin[x],height},{x,0,2Pi,Pi/32}]]}}, edge,{Line[{{-1,0,height},{-1/3,0,height}}],Line[{{1,0,height},{1/3,0,height}}]} ]] baduSet3D[edge_,height_:1]:=baduSet3D[{edge},height] baduSet[edge_List] := Graphics[Join[ {{FaceForm[None],EdgeForm[edge], Polygon[Table[(1/Sqrt[3]){Cos[x],Sin[x]},{x,0,2Pi,Pi/32}]]}}, edge,{Line[{{-1,0},{-1/3,0}}],Line[{{1,0},{1/3,0}}]} ]] baduSet[edge_]:=baduSet[{edge}] End[] (*`Private`*) EndPackage[]