#include #include #include /* timing test program for normal RNG generators */ #define N 2000000 static unsigned long jz,jsr=123456789; #define SHR3 (jz=jsr, jsr^=(jsr<<13), jsr^=(jsr>>17), jsr^=(jsr<<5),jz+jsr) #define UNI (.5 + (signed) SHR3 * .2328306e-9) #define IUNI SHR3 static long hz; static int seed=331; static unsigned long iz, kn[128], ke[256]; static float wn[128],fn[128], we[256],fe[256]; #define RNOR (hz=SHR3, iz=hz&127, (abs(hz)0)? r+x : -r-x; } /* iz>0, handle the wedges of other strips */ if( fn[iz]+ggl(&seed)*(fn[iz-1]-fn[iz]) < exp(-.5*x*x) ) return x; /* start all over */ hz=SHR3; iz=hz&127; if(abs(hz)=1;i--){ dn = sqrt(-2.*log(vn/dn+exp(-.5*dn*dn))); kn[i+1] = (dn/tn)*m1; tn = dn; fn[i] = exp(-.5*dn*dn); wn[i] = dn/m1; } /* Set up tables for REXP */ q = ve/exp(-de); ke[0] = (de/q) * m2; ke[1] = 0; we[0] = q/m2; we[255] = de/m2; fe[0] = 1.; fe[255] = exp(-de); for(i=254;i>=1;i--){ de = -log(ve/de+exp(-de)); ke[i+1] = (de/te)*m2; te = de; fe[i] = exp(-de); we[i] = de/m2; } } float xv[N],yv[N],zv[N]; main() { /* compares performance of Box-Muller, Ziggurat vs. the Polar methods for generating normals */ float r1,r2,s,x1,x2,y1,y2,z1,z2,z3,z4,twopi; float t1,t2,u1,u2,ts,te; float ggl(); void zigset(); static float seed=331.0; int i,iter,n,nv; twopi = 6.2831853071795862; n = 10000; for(nv=0;nv<4;nv++){ /* Box-Muller method */ ts = ((float)clock())/((float) CLOCKS_PER_SEC); for(iter=0;iter<10;iter++){ #pragma ivdep for(i=0;i float ggl(float *ds) { /* generate u(0,1) distributed random numbers. Seed ds must be saved between calls. ggl is essentially the same as the IMSL routine RNUM. W. Petersen and M. Troyer, 24 Oct. 2002, ETHZ */ double t,d2=0.2147483647e10; t = (double) *ds; t = fmod(0.16807e5*t,d2); *ds = (float) t; return((float)((t-1.0e0)/(d2-1.0e0))); }