Sei sulla pagina 1di 7

Software PARI/GP dellarticolo Aggirandosi tra i plot della zeta di Riemann

Rosario Turco

Introduzione
Nel seguito viene riportato il listato della parte software sviluppata in PARI/GP per lanalisi grafica e computazionale della zeta di Riemann, usata nellarticolo Aggirandosi tra i plot della zeta di Riemann dallautore. Il software utilizza principalmente funzionalit base di PARI/GP come il solve per la ricerca degli zeri, implementa funzionalit di calcolo come le derivate prima e seconda, il metodo di Newton-Raphson (Metodo delle tangenti) e funzionalit grafiche. Sono ben accette segnalazioni, ampliamenti, approfondimenti, articoli e/o miglioramenti del software della zeta di Riemann e soprattutto ulteriori funzionalit grafiche introducibili con PARI/GP, che i lettori vorranno segnalare tramite e-mail a rosario_turco@virgilio.it

Parte calcolo e grafici Zeta di Riemann


/* * Utility & Plot for Riemann's Zeta * * Authors: Rosario Turco (IT) * Version: 2.5 (C) 2010 * * Product: Tested with PARI/GP version 2.4.2 * * Blog: http://MATHBuildingBlock.blogspot.com * * Site: www.gruppoeratostene.com * www.scribd.com/rosario_turco * * Papers: Database CNR Solar * * * * SOFTW ARE WITHOUT ANY W ARRANTY WHATSO EVER. * * Attention: for Gram points you must also load lambert.txt * */ debug=0;

/* Complex Utility */ ModComplex(z)=local();{

return(sqrt((real(z))^2 + (imag(z))^2)); } TetaComplex(z)=local();{ return(atan(imag(z)/real(z))); } /* r*exp(I*teta) */ ModTetaComplex(z)=local();{ r = ModComplex(z); teta = TetaComplex(z) ; print("z= ",z, "-> ", r, "*exp(j", teta,")"); } /* Cerca gli zeri della zeta di Riemann sulla retta critica sigma=1/2. */ GetCriticalZero(n,pz=14)=local(k=0,i=1);{ pz2=pz+1; b = n+1 ; v=vector(n); while(i<b, z=-1; while(z == -1, pz2 = pz2 + 1; z = GetZeroZetaHardy(pz,pz2); if(z != -1, v[i]=z; i = i + 1; z = 0; ); pz = pz2 ; ); ); return(v); } GetZeroZetaHardy(b1,b2)=local(k=0,a=-1);{ trap( , return(-1), a=solve(k=b1,b2,real(RiemannSiegelZ(k))); return(a); ); } /* ** for s=1/2+I*t */

RiemannSiegelZ(t)=local(Teta=0,Zeta=0);{ Teta = RiemannSiegelTeta(t); Zeta = exp(I*Teta) * zeta(1/2+I*t); return(Zeta); } RiemannSiegelTeta(t)=local(Teta=0);{ Teta = imag(lngamma(1/4+1/2*I*t)) - ((t/2) * log(Pi)); return(Teta); } /* ** for s=si+I*t */ RiemannSiegelZSigma(t,si)=local(Teta=0,Zeta=0);{ Teta = RiemannSiegelTetaSigma(t,si); Zeta = exp(I*Teta) * zeta(si+I*t); return(Zeta); } RiemannSiegelTetaSigma(t,si)=local(Teta=0);{ Teta = imag(lngamma(1/4+si*I*t)) - ((t/2) * log(Pi)); return(Teta); } DerivRiemannSiegelSigma(s)=local(DRS=0);{ DRS = lngamma(s) - log(2*Pi)/2; return(DRS); } Argzeta(t)=local(Arg=0);{ z = zeta(1/2+I*t); Arg = atan(imag(z)/real(z)); return(Arg); } S(t)=local(Si=0);{ Si = 1/Pi * (Argzeta(t)); return(Si); } N(T)=local(Num=0);{ Num = (T/(2*Pi)) * log(T/(2*Pi)) - (T/(2 *Pi)) + 1; return(ceil(Num)); }

/* ** The first Derivative zeta with ** s=si+I*t ** */ TheFirstDerivzeta(s, delta=1.0 E-20)=local(DerivZeta=0);{ DerivZeta = (zeta(s+delta/2) - zeta(s-delta/2))/delta; return(DerivZeta); } /* ** The second Derivative zeta with ** s=si+I*t ** */ TheSecondDerivzeta(s, delta=1.0 E-20)=local(SecDerivZeta=0);{ SecDerivZeta = (TheFirstDerivzeta(s+delta/2) - TheFirstDerivzeta(s-delta/2))/delta; return(SecDerivZeta); } /* ** Newton-Raphson Method for zeta ** s=si+I*t ** * */ TangMzeta(s0,delta=1.0E-20, c=200) = local(i=0); { s = s0; if( c > 1, for(i=2,c, trap( , return(s), a = zeta(s)/TheFirstDerivzeta(s,delta); s = s - a; ); ); ); return(s); } /* ** Newton-Raphson Method for derivative of zeta ** s=si+I*t ** * */ TangMTSzeta(s0,delta=1.0E-20, c=200) = local(i=0); { s = s0; if( c > 1,

for(i=2,c, trap( , return(s), a = TheFirstDerivzeta(s,delta)/TheSecondDerivzeta(s,delta); s = s - a; ); ); ); return(s); } /* ** It returns a vector of n Gram points */ GetGramPoints(n)=local(i=0);{ g=vector(n); for(i=1,n, g[i]=GramPoint(i-1); ); return(g); } /* ** It returns the gn Gram point ** */ GramPoint(n)=local(gn=0);{ gn=2*Pi*exp(1+lambertw((8 *n+1)/(8 *exp(1)))); return(gn); } /* ** ** Plotting Ar ea ** */ /* Imag of zeta */ PlotImZeta(b1=0.0,b2=55.0)=local();{ ploth(X=b1,b2,imag(zeta(1/2+X*I)),"Recursive"); } /* Modulus of zeta */ PlotModZeta(b1=0.0,b2 =55.0)=local();{ ploth(X=b1,b2,sqrt(real(zeta(1/2+X*I))^2 + imag(zeta(1/2+X*I))^2),"Recursive"); } PlotModSquareZeta(b1=0.0,b2 =55.0)=local();{ ploth(X=b1,b2,real(zeta(1/2+X*I))^2 + imag(zeta(1/2+X*I))^2,"Recursive");

} /* Real and Imag of zeta */ PlotZeta(b1=0.0,b2=55.0)=local();{ ploth(X=b1,b2,[real(zeta(1/2+X*I)),imag(zeta(1/2+X*I))]); } /* Plot Real Zeta * * example: * PlotRealZeta(-5,5) or * PlotRealZeta(-18.5,10) or * PlotRealZeta(-15.5,0) */ PlotRealZeta(b1,b2)=local();{ ploth(t=b1,b2,zeta(t), ,100); } PlotHardyZeta(b1,b2)=local(t=0);{ ploth(t=b1,b2,real(RiemannSiegelZ(t))); }

Parte Lambert

\\ Lambert's W function. \\ Method: solve the equation w*exp(w)=x by a handcrafted iterative method. \\ lambertw(x,w): initial value supplied. \\ lambertw(x): initial value is ln(1+x). This is OK for x>=0 and may well \\ work elsewher e. \\ We actually have three func tions. The basic engine is lambertw1, \\ which does a single iteration. A really sophisticated user would \\ monitor his own calls to lambertw1, but we provide an automatic \\ driver lambertw2, which generates an initial value i f none is \\ supplied and iterates to convergence, usually making an unnecessary \\ evaluation of exp(w) as a check on the final value. The recommended \\ highest level routine lambertw calls lambertw2 for a low-precision \\ initial value that nevertheless is accurate enough so that one call \\ to lambertw1 should suffice. debug=0; {lambertw(x,w)=local(low,high); high=precision(0.); low=max(9,ceil(high/7.5)); default(realprecision,low); w=lambertw2(precision(x,low),precision(w,low)); if(debug, print(precision(w));); default(realprecision,high); w=lambertw1(x,precision(w,high)); return(w);}

global LAMBERTW _CONVERGE; {lambertw2(x,w)=local(err,oldw,olderr); if (x==0,return(x)); if (w==0, w=lplog1(x)); err=100; while (1, oldw=w; w=lambertw1(x,w); olderr=err; err=abs(w-oldw); if (LAMBERTW_CO NVERGE | err==0 | err>=olderr, break); ); return(w); } \\ improve approximate value w using Taylor series up to N-th derivative; \\ N=0 means stop after smallest term, but use at most 7 ter ms. {lambertw1(x,w,N)=local(s,a,h,hn,p,d,dn,c,term,oldterm,olds,vary); if (x==0, return(x)); s=w; a=w*exp(w); h=x-a; if (h==0, r eturn(w)); hn=1; p=1; d=w/(1 +w)/a; dn=d; c=d; term=1e100; vary=N==0; if (vary, N=7); for (n=1,N, hn=hn*h/n; oldter m=ter m; ter m=hn*dn; olds=s; s=s+ter m; LAMBERTW _CONVERGE=s==olds; if (LAMBERTW_CO NVERGE | (vary & abs(term)>=abs(oldterm)), s=olds; break); p=(1-3*n-n*q_)*p+(1+q_)*deriv(p,q_); c=c*w/(1 +w)^2/a; dn=c*subst(p,q_,w)); return(s); } \\ low precision log(1+x) {lplog1(x)=if (abs(x)<0.5, x-x^2/2, /*else*/ precision(log(precision(1+x,9)),precision(0.))) }

Uso
Copiare le due parti su due file txt: zeta.txt e lambert.txt. Eseguire il caricamento con PARI/GP nel seguente modo: \r lambert.txt \r zeta.txt A questo punto possibile usare le varie funzionalit dei due file testo, secondo larticolo Aggirandosi tra i plot della zeta di Riemann. La parte Lambert utile nello studio dei Gram point.