void initgn(long isdtyp) /* ********************************************************************** void initgn(long isdtyp) INIT-ialize current G-e-N-erator Reinitializes the state of the current generator This is a transcription from Pascal to Fortran of routine Init_Generator from the paper L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package with Splitting Facilities." ACM Transactions on Mathematical Software, 17:98-111 (1991) Arguments isdtyp -> The state to which the generator is to be set isdtyp = -1 => sets the seeds to their initial value isdtyp = 0 => sets the seeds to the first value of the current block isdtyp = 1 => sets the seeds to the first value of the next block ********************************************************************** */ { #define numg 32L extern void gsrgs(long getset,long *qvalue); extern void gscgn(long getset,long *g); extern long Xm1,Xm2,Xa1w,Xa2w,Xig1[],Xig2[],Xlg1[],Xlg2[],Xcg1[],Xcg2[]; long g; long qrgnin; /* Abort unless random number generator initialized */ gsrgs(0L,&qrgnin); if(qrgnin) goto S10; fprintf(stderr,"%s\n", " INITGN called before random number generator initialized -- abort!"); exit(1); S10: gscgn(0L,&g); if(-1 != isdtyp) goto S20; *(Xlg1+g-1) = *(Xig1+g-1); *(Xlg2+g-1) = *(Xig2+g-1); goto S50; S20: if(0 != isdtyp) goto S30; goto S50; S30: /* do nothing */ if(1 != isdtyp) goto S40; *(Xlg1+g-1) = mltmod(Xa1w,*(Xlg1+g-1),Xm1); *(Xlg2+g-1) = mltmod(Xa2w,*(Xlg2+g-1),Xm2); goto S50; S40: fprintf(stderr,"%s\n","isdtyp not in range in INITGN"); exit(1); S50: *(Xcg1+g-1) = *(Xlg1+g-1); *(Xcg2+g-1) = *(Xlg2+g-1); #undef numg }
void setall(long iseed1,long iseed2) /* ********************************************************************** void setall(long iseed1,long iseed2) SET ALL random number generators Sets the initial seed of generator 1 to ISEED1 and ISEED2. The initial seeds of the other generators are set accordingly, and all generators states are set to these seeds. This is a transcription from Pascal to Fortran of routine Set_Initial_Seed from the paper L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package with Splitting Facilities." ACM Transactions on Mathematical Software, 17:98-111 (1991) Arguments iseed1 -> First of two integer seeds iseed2 -> Second of two integer seeds ********************************************************************** */ { #define numg 32L extern void gsrgs(long getset,long *qvalue); extern void gssst(long getset,long *qset); extern void gscgn(long getset,long *g); extern long Xm1,Xm2,Xa1vw,Xa2vw,Xig1[],Xig2[]; long T1; long g,ocgn; long qrgnin; T1 = 1; /* TELL IGNLGI, THE ACTUAL NUMBER GENERATOR, THAT THIS ROUTINE HAS BEEN CALLED. */ gssst(1,&T1); gscgn(0L,&ocgn); /* Initialize Common Block if Necessary */ gsrgs(0L,&qrgnin); if(!qrgnin) inrgcm(); *Xig1 = iseed1; *Xig2 = iseed2; initgn(-1L); for(g=2; g<=numg; g++) { *(Xig1+g-1) = mltmod(Xa1vw,*(Xig1+g-2),Xm1); *(Xig2+g-1) = mltmod(Xa2vw,*(Xig2+g-2),Xm2); gscgn(1L,&g); initgn(-1L); } gscgn(1L,&ocgn); #undef numg }
void advnst(long k) /* ********************************************************************** void advnst(long k) ADV-a-N-ce ST-ate Advances the state of the current generator by 2^K values and resets the initial seed to that value. This is a transcription from Pascal to Fortran of routine Advance_State from the paper L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package with Splitting Facilities." ACM Transactions on Mathematical Software, 17:98-111 (1991) Arguments k -> The generator is advanced by2^K values ********************************************************************** ** Buttrey note: replaced all exit() calls with return()s -- Jan 2015. ** Also replaced all fprintf's with Rprintf ********************************************************************** */ { #define numg 32L extern void gsrgs(long getset,long *qvalue); extern void gscgn(long getset,long *g); extern long Xm1,Xm2,Xa1,Xa2,Xcg1[],Xcg2[]; static long g,i,ib1,ib2; static long qrgnin; /* Abort unless random number generator initialized */ gsrgs(0L,&qrgnin); if(qrgnin) goto S10; Rprintf(" ADVNST called before random generator initialized - ABORT"); return; S10: gscgn(0L,&g); ib1 = Xa1; ib2 = Xa2; for(i=1; i<=k; i++) { ib1 = mltmod(ib1,ib1,Xm1); ib2 = mltmod(ib2,ib2,Xm2); } setsd(mltmod(ib1,*(Xcg1+g-1),Xm1),mltmod(ib2,*(Xcg2+g-1),Xm2)); /* NOW, IB1 = A1**K AND IB2 = A2**K */ #undef numg }