fprintf "table4", "\n"; fprintf "table4", "\\begin{table}\n"; fprintf "table4", "\\caption{Timings for $ \\Li n {1+(\\z-1)\\pi} $.}\n"; fprintf "table4", "\\label{table4}\n"; fprintf "table4", "\\vskip-.7cm\n"; fprintf "table4", "$$\n"; fprintf "table4", "\\begin{array}{lrrrrrrr}\n"; fprintf "table4", "\\hline\n"; fprintf "table4", "\\vphantom{b^{b^b}}\n"; fprintf "table4", "\\vphantom{p_{p_{p_p}}}\n"; fprintf "table4", "q(x) & n & p & e & f & N & \\text{Time 1} & \\text{Time 2}\\cr\n"; fprintf "table4", "\\hline\n"; fprintf "table4", "\\vphantom{b^{b^b}}\n"; load "lippapertablesdata"; for example in gothrough do print "==================================="; p:=example[1]; N:=example[2]; n:=example[3]; f:=example[4]; pol:=example[5]; print "p:", p; resfsize:=p^f; e:=Degree(pol); Ne:=e*N+1; // add 1 since we define precision using >, not >= // So the role of N in the paper is played by Ne since Magma does renormalize the valuation on F // // A basic function: mink:=function(c1,c2,c3) // This function returns, if c1,c2>0, the smallest integer k ge 2 such that c1*m-c2*Log(m)>c3 for all m ge k. k1:=Maximum(1,Floor(c2/c1));k2:=Ceiling(c2/c1); if Minimum(c1*k1-c2*Log(k1), c1*k2-c2*Log(k2)) gt c3 then return 2; else while c1*k1-c2*Log(k1) le c3 do; k1:=k1+Ceiling((c2*Log(k1)-c1*k1+c3)/c1); end while; return k1; end if; end function; // And now for the actual computation... hsl:=mink(1/e,n/Log(p),N); // The extra condition for p=2 is redundant in this case since 1/e le 1. print "hsl:", hsl; // // Prepare for the logarithm. // First find the minimum (unnormalized) valuation we can find for log(z) when z is in U_1: the minimum of k/e-log_p(k) for k \ge 1 mytime:=Cputime(); k1:=Maximum(1,Floor(e/Log(p)));k2:=Ceiling(e/Log(p)); V:=Floor(Minimum(k1/e-Log(k1)/Log(p),k2/e-Log(k2)/Log(p))); // We'll write log(1-z) as log(z')/(e*(p^f-1)) where z'=(z-1)^{e*(p^f-1)}. So we compute // log^{n-1}(z)*log(z') up to precision N + v_p((n-1)!*e) and divide it by (n-1)!*e*(p^f-1). logsl:=mink( 1/e,1/Log(p),Maximum(V, N+Valuation(e*Factorial(n-1),p)-(n-1)*V) ); print"logsl:", logsl; LOG:=-&+[(-x)^k/k : k in [1..logsl-1]]; // The polynomial ring Qx=PolynomialRing(Rationals()) is already defined in lippapertablesdata!. print "Computed LOG"; firstQpprecision:=N+Floor(n*Log(hsl-1)/Log(p))+1; Qpprecision:=Maximum( firstQpprecision, Maximum(V, N+Valuation(e*Factorial(n-1),p)-(n-1)*V)+Floor(Log(logsl-1)/Log(p))+1 ); print "Qpprecision:", Qpprecision; if Qpprecision gt firstQpprecision then printf "Qpprecision was increased from %o to %o for the log.", firstQpprecision, Qpprecision; end if; Qp:=pAdicField(p,Qpprecision); Qpt:=PowerSeriesRing(Qp,hsl); if p eq 2 then // LOGS contains the powers of log(1+t) that we need: log^j(1+t)/j!, j=1,...,n-1. LOGS:=Vector(Qpt,n-1,[i gt 1 select Integral(Self(i-1)/(1+t)) else -&+[(-t)^k/Qp!k : k in [1..hsl]] : i in [1..n-1]] ); Hns:=Vector(Qpt,n,[0 : i in [1..n]]); Hns[2]:=-&+[(-t)^k/Qp!k^2 : k in [1..hsl-1]]; for i in [3..n] do Hns[i]:=Integral(Hns[i-1]/(1+t) + LOGS[i-1]/t); if IsOdd(i) then Hns[i]:=Hns[i]+2^(i-1)*Evaluate(Hns[i],-2)/(1-2^i); end if; end for; else gsl:=2; for m in [2..n] do cmp:=p/(p-1)-(n-1)/Log(p)+(n-1)*Log(n*(p-1)/Log(p))/Log(p)+Log(2*p*(p-1)*n/Log(p))/Log(p); gsl:=Maximum(gsl,mink(1/(p-1), 1/Log(p), N-m+cmp+Valuation(1-2^(m-1),p)+(n-m)*Log(hsl-1)/Log(p))); end for; print "gsl:", gsl; Qpspecialprecision:=1; for m in [2..n] do Qpspecialprecision:=Maximum(Qpspecialprecision,N-m+Valuation(1-2^(m-1),p)+Floor((n-m)*Log(hsl-1)/Log(p))+m*Floor(Log(gsl-1)/Log(p))); end for; print "Qpspecialprecision:", Qpspecialprecision; Qpspecial:=pAdicField(p,Qpspecialprecision); Qpv:=PowerSeriesRing(Qpspecial,gsl); gns:=Vector(Qpv, n,[i gt 1 select Integral(-Self(i-1)*&+[v^j: j in [0..gsl-1]]/v) else Integral(-(v-1-(v-1)^p/(v^p-(v-1)^p))*&+[v^j: j in [0..gsl-1]]/v) : i in [1..n]]); Liminusones:=Vector(Qpspecial,n,[IsEven(i) select 0 else p^i*Evaluate(gns[i],1/Qpspecial!2)/(p^i-1): i in [1..n] ]); print "Computed Liminusones"; // // LOGS contains the powers of log(1+t) that we need: log^j(1+t)/j!, j=1,...,n-1. QptLOGS:=PowerSeriesRing(Qp,hsl); LOGS:=Vector(QptLOGS,n-1,[i gt 1 select Integral(Self(i-1)/(1+t)) else -&+[(-t)^k/Qp!k : k in [1..hsl]] : i in [1..n-1]] ); Hns:=Vector(Qpt,n,[0 : i in [1..n]]); Hns[2]:=-&+[(-t)^k/Qp!k^2 : k in [1..hsl-1]]; for i in [3..n] do Hns[i]:=Integral(Hns[i-1]/(1+t) + LOGS[i-1]/t); if IsOdd(i) then Hns[i]:=Hns[i]+2^(i-1)*Qp!Liminusones[i]/(1-2^(i-1)); end if; end for; end if; TIME1:=Cputime(mytime); print "CPUtime1:", TIME1; // Now define the fields Funr:=ext; Funrprecision:=Qpprecision; print "Funrprecision:", Funrprecision; F:=ext; Fprecision:=e*Funrprecision; print "Fprecision:", Fprecision; Funrz:=PolynomialRing(Funr); Tmgen:=HenselLift(z^(resfsize-1)-1, Funr!PrimitiveElement(ResidueClassField(IntegerRing(Funr))), Funrprecision); print "Computed Tmgen"; pp:=UniformizingElement(F); print "Ne", Ne; testz:=1+(Tmgen-1)*pp+O(pp^Fprecision); // Now we can define the function that we really need Lione:=function(n,z) return O(pp^Ne) + Evaluate(Hns[n],z-1) - Evaluate(LOG,F!z-1)^(n-1)*Evaluate(LOG, ((F!z-1)^e/p^Valuation(F!z-1))^(resfsize-1)-1) / ((resfsize-1)*e*Factorial(n-1)); end function; mytime:=Cputime(); A:=Lione(n,testz); TIME2:=Cputime(mytime); print "CPUtime2:", TIME2; // print "TEST compatibility:" A-Evaluate(Hns[n],F!testz-1)-Log(F!testz)^(n-1)*Log(((F!testz-1)^e/p^Valuation(F!testz-1))^(resfsize-1))/((resfsize-1)*e*Factorial(n-1)); fprintf "table4", "%o & %o & %o & %o & %o & %o & %o & %o \\cr\n", pol, n, p, e, f, N, TIME1, TIME2; end for; print "==================================="; fprintf "table4", "\\hline\n"; fprintf "table4", "\\end{array}\n"; fprintf "table4", "$$\n"; fprintf "table4", "\\end{table}\n"; fprintf "table4", "\n";