#include #include "smpl.h" extern double drand48(); #define then static long In[16]= {0L, /* seeds for streams 1 thru 15 */ 1973272912L, 747177549L, 20464843L, 640830765L, 1098742207L, 78126602L, 84743774L, 831312807L, 124667236L, 1172177002L, 1124933064L, 1223960546L, 1878892440L, 1449793615L, 553303732L}; static int strm=1; /* index of current stream */ /*-------------------- SELECT GENERATOR STREAM ---------------------*/ int stream(n) int n; { /* set stream for 1<=n<=15, return stream for n=0 */ if ((n<0)||(n>15)) then error(0,"stream Argument Error"); if (n) then strm=n; return(strm); } /*-------------------------- SET/GET SEED --------------------------*/ long seed(Ik,n) long Ik; int n; { /* set seed of stream n for Ik>0, return current seed for Ik=0 */ if ((n<1)||(n>15)) then error(0,"seed Argument Error"); if (Ik>0L) then In[n]=Ik; return(In[n]); } /*------------ UNIFORM [a, b] RANDOM VARIATE GENERATOR -------------*/ real uniform(a,b) real a,b; { /* 'uniform' returns a psuedo-random variate from a uniform */ /* distribution with lower bound a and upper bound b. */ if (a>b) then error(0,"uniform Argument Error: a > b"); return(a+(b-a)*drand48()); } /*-------------------- RANDOM INTEGER GENERATOR --------------------*/ int random(i,n) int i,n; { /* 'random' returns an integer equiprobably selected from the */ /* set of integers i, i+1, i+2, . . , n. */ if (i>n) then error(0,"random Argument Error: i > n"); n-=i; n=(n+1.0)*drand48(); return(i+n); } /*-------------- EXPONENTIAL RANDOM VARIATE GENERATOR --------------*/ real expntl(x) real x; { /* 'expntl' returns a psuedo-random variate from a negative */ /* exponential distribution with mean x. */ return(-x*log(drand48())); } /*---------------- ERLANG RANDOM VARIATE GENERATOR -----------------*/ real erlang(x,s) real x,s; { /* 'erlang' returns a psuedo-random variate from an erlang */ /* distribution with mean x and standard deviation s. */ int i,k; real z; if (s>x) then error(0,"erlang Argument Error: s > x"); z=x/s; k=(int)z*z; z=1.0; for (i=0; ix. */ real cv,z,p; if (s<=x) then error(0,"hyperx Argument Error: s not > x"); cv=s/x; z=cv*cv; p=0.5*(1.0-sqrt((z-1.0)/(z+1.0))); z=(drand48()>p)? (x/(1.0-p)):(x/p); return(-0.5*z*log(drand48())); } /*----------------- NORMAL RANDOM VARIATE GENERATOR ----------------*/ real normal(x,s) real x,s; { /* 'normal' returns a psuedo-random variate from a normal dis- */ /* tribution with mean x and standard deviation s. */ real v1,v2,w,z1; static real z2=0.0; if (z2!=0.0) then {z1=z2; z2=0.0;} /* use value from previous call */ else { do {v1=2.0*drand48()-1.0; v2=2.0*drand48()-1.0; w=v1*v1+v2*v2;} while (w>=1.0); w=sqrt((-2.0*log(w))/w); z1=v1*w; z2=v2*w; } return(x+z1*s); }