4 static long Xm1
,Xm2
,Xa1
,Xa2
,Xcg1
[32],Xcg2
[32],Xa1w
,Xa2w
,Xig1
[32],Xig2
[32],
5 Xlg1
[32],Xlg2
[32],Xa1vw
,Xa2vw
;
6 static long Xqanti
[32];
9 **********************************************************************
12 Advances the state of the current generator by 2^K values and
13 resets the initial seed to that value.
14 This is a transcription from Pascal to Fortran of routine
15 Advance_State from the paper
16 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
17 with Splitting Facilities." ACM Transactions on Mathematical
18 Software, 17:98-111 (1991)
20 k -> The generator is advanced by2^K values
21 **********************************************************************
25 extern void gsrgs(long getset
,long *qvalue
);
26 extern void gscgn(long getset
,long *g
);
27 extern long Xm1
,Xm2
,Xa1
,Xa2
,Xcg1
[],Xcg2
[];
28 static long g
,i
,ib1
,ib2
;
31 Abort unless random number generator initialized
35 fputs(" ADVNST called before random generator initialized - ABORT\n",
43 ib1
= mltmod(ib1
,ib1
,Xm1
);
44 ib2
= mltmod(ib2
,ib2
,Xm2
);
46 setsd(mltmod(ib1
,*(Xcg1
+g
-1),Xm1
),mltmod(ib2
,*(Xcg2
+g
-1),Xm2
));
48 NOW, IB1 = A1**K AND IB2 = A2**K
52 void getsd(long *iseed1
,long *iseed2
)
54 **********************************************************************
55 void getsd(long *iseed1,long *iseed2)
57 Returns the value of two integer seeds of the current generator
58 This is a transcription from Pascal to Fortran of routine
59 Get_State from the paper
60 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
61 with Splitting Facilities." ACM Transactions on Mathematical
62 Software, 17:98-111 (1991)
64 iseed1 <- First integer seed of generator G
65 iseed2 <- Second integer seed of generator G
66 **********************************************************************
70 extern void gsrgs(long getset
,long *qvalue
);
71 extern void gscgn(long getset
,long *g
);
72 extern long Xcg1
[],Xcg2
[];
76 Abort unless random number generator initialized
80 fprintf(stderr
,"%s\n",
81 " GETSD called before random number generator initialized -- abort!");
85 *iseed1
= *(Xcg1
+g
-1);
86 *iseed2
= *(Xcg2
+g
-1);
91 **********************************************************************
93 GeNerate LarGe Integer
94 Returns a random integer following a uniform distribution over
95 (1, 2147483562) using the current generator.
96 This is a transcription from Pascal to Fortran of routine
98 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
99 with Splitting Facilities." ACM Transactions on Mathematical
100 Software, 17:98-111 (1991)
101 **********************************************************************
105 extern void gsrgs(long getset
,long *qvalue
);
106 extern void gssst(long getset
,long *qset
);
107 extern void gscgn(long getset
,long *g
);
108 extern void inrgcm(void);
109 extern long Xm1
,Xm2
,Xa1
,Xa2
,Xcg1
[],Xcg2
[];
110 extern long Xqanti
[];
111 static long ignlgi
,curntg
,k
,s1
,s2
,z
;
112 static long qqssd
,qrgnin
;
114 IF THE RANDOM NUMBER PACKAGE HAS NOT BEEN INITIALIZED YET, DO SO.
115 IT CAN BE INITIALIZED IN ONE OF TWO WAYS : 1) THE FIRST CALL TO
116 THIS ROUTINE 2) A CALL TO SETALL.
119 if(!qrgnin
) inrgcm();
121 if(!qqssd
) setall(1234567890L,123456789L);
123 Get Current Generator
126 s1
= *(Xcg1
+curntg
-1);
127 s2
= *(Xcg2
+curntg
-1);
129 s1
= Xa1
*(s1
-k
*53668L)-k
*12211;
130 if(s1
< 0) s1
+= Xm1
;
132 s2
= Xa2
*(s2
-k
*52774L)-k
*3791;
133 if(s2
< 0) s2
+= Xm2
;
134 *(Xcg1
+curntg
-1) = s1
;
135 *(Xcg2
+curntg
-1) = s2
;
137 if(z
< 1) z
+= (Xm1
-1);
138 if(*(Xqanti
+curntg
-1)) z
= Xm1
-z
;
143 void initgn(long isdtyp
)
145 **********************************************************************
146 void initgn(long isdtyp)
147 INIT-ialize current G-e-N-erator
148 Reinitializes the state of the current generator
149 This is a transcription from Pascal to C of routine
150 Init_Generator from the paper
151 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
152 with Splitting Facilities." ACM Transactions on Mathematical
153 Software, 17:98-111 (1991)
155 isdtyp -> The state to which the generator is to be set
156 isdtyp = -1 => sets the seeds to their initial value
157 isdtyp = 0 => sets the seeds to the first value of
159 isdtyp = 1 => sets the seeds to the first value of
161 WGR, 12/19/00: replaced S10, S20, etc. with C blocks {} per
163 **********************************************************************
167 extern void gsrgs(long getset
,long *qvalue
);
168 extern void gscgn(long getset
,long *g
);
169 extern long Xm1
,Xm2
,Xa1w
,Xa2w
,Xig1
[],Xig2
[],Xlg1
[],Xlg2
[],Xcg1
[],Xcg2
[];
173 Abort unless random number generator initialized
177 fprintf(stderr
,"%s\n",
178 " INITGN called before random number generator initialized -- abort!");
183 if(isdtyp
== -1) { /* Initial seed */
184 *(Xlg1
+g
-1) = *(Xig1
+g
-1);
185 *(Xlg2
+g
-1) = *(Xig2
+g
-1);
187 else if (isdtyp
== 0) { ; } /* Last seed */
188 else if (isdtyp
== 1) { /* New seed */
189 *(Xlg1
+g
-1) = mltmod(Xa1w
,*(Xlg1
+g
-1),Xm1
);
190 *(Xlg2
+g
-1) = mltmod(Xa2w
,*(Xlg2
+g
-1),Xm2
);
192 fprintf(stderr
,"%s\n","isdtyp not in range in INITGN");
196 *(Xcg1
+g
-1) = *(Xlg1
+g
-1);
197 *(Xcg2
+g
-1) = *(Xlg2
+g
-1);
203 **********************************************************************
205 INitialize Random number Generator CoMmon
207 Initializes common area for random number generator. This saves
208 the nuisance of a BLOCK DATA routine and the difficulty of
209 assuring that the routine is loaded with the other routines.
210 **********************************************************************
214 extern void gsrgs(long getset
,long *qvalue
);
215 extern long Xm1
,Xm2
,Xa1
,Xa2
,Xa1w
,Xa2w
,Xa1vw
,Xa2vw
;
216 extern long Xqanti
[];
221 A1W = MOD(A1**(2**W),M1) A2W = MOD(A2**(2**W),M2)
222 A1VW = MOD(A1**(2**(V+W)),M1) A2VW = MOD(A2**(2**(V+W)),M2)
223 If V or W is changed A1W, A2W, A1VW, and A2VW need to be recomputed.
224 An efficient way to precompute a**(2*j) MOD m is to start with
225 a and square it j times modulo m using the function MLTMOD.
235 for(i
=0; i
<numg
; i
++) *(Xqanti
+i
) = 0;
238 Tell the world that common has been initialized
243 void setall(long iseed1
,long iseed2
)
245 **********************************************************************
246 void setall(long iseed1,long iseed2)
247 SET ALL random number generators
248 Sets the initial seed of generator 1 to ISEED1 and ISEED2. The
249 initial seeds of the other generators are set accordingly, and
250 all generators states are set to these seeds.
251 This is a transcription from Pascal to Fortran of routine
252 Set_Initial_Seed from the paper
253 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
254 with Splitting Facilities." ACM Transactions on Mathematical
255 Software, 17:98-111 (1991)
257 iseed1 -> First of two integer seeds
258 iseed2 -> Second of two integer seeds
259 **********************************************************************
263 extern void gsrgs(long getset
,long *qvalue
);
264 extern void gssst(long getset
,long *qset
);
265 extern void gscgn(long getset
,long *g
);
266 extern long Xm1
,Xm2
,Xa1vw
,Xa2vw
,Xig1
[],Xig2
[];
272 TELL IGNLGI, THE ACTUAL NUMBER GENERATOR, THAT THIS ROUTINE
278 Initialize Common Block if Necessary
281 if(!qrgnin
) inrgcm();
285 for(g
=2; g
<=numg
; g
++) {
286 *(Xig1
+g
-1) = mltmod(Xa1vw
,*(Xig1
+g
-2),Xm1
);
287 *(Xig2
+g
-1) = mltmod(Xa2vw
,*(Xig2
+g
-2),Xm2
);
294 void setant(long qvalue
)
296 **********************************************************************
297 void setant(long qvalue)
299 Sets whether the current generator produces antithetic values. If
300 X is the value normally returned from a uniform [0,1] random
301 number generator then 1 - X is the antithetic value. If X is the
302 value normally returned from a uniform [0,N] random number
303 generator then N - 1 - X is the antithetic value.
304 All generators are initialized to NOT generate antithetic values.
305 This is a transcription from Pascal to Fortran of routine
306 Set_Antithetic from the paper
307 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
308 with Splitting Facilities." ACM Transactions on Mathematical
309 Software, 17:98-111 (1991)
311 qvalue -> nonzero if generator G is to generating antithetic
312 values, otherwise zero
313 **********************************************************************
317 extern void gsrgs(long getset
,long *qvalue
);
318 extern void gscgn(long getset
,long *g
);
319 extern long Xqanti
[];
323 Abort unless random number generator initialized
327 fprintf(stderr
,"%s\n",
328 " SETANT called before random number generator initialized -- abort!");
332 Xqanti
[g
-1] = qvalue
;
335 void setsd(long iseed1
,long iseed2
)
337 **********************************************************************
338 void setsd(long iseed1,long iseed2)
339 SET S-ee-D of current generator
340 Resets the initial seed of the current generator to ISEED1 and
341 ISEED2. The seeds of the other generators remain unchanged.
342 This is a transcription from Pascal to Fortran of routine
343 Set_Seed from the paper
344 L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
345 with Splitting Facilities." ACM Transactions on Mathematical
346 Software, 17:98-111 (1991)
348 iseed1 -> First integer seed
349 iseed2 -> Second integer seed
350 **********************************************************************
354 extern void gsrgs(long getset
,long *qvalue
);
355 extern void gscgn(long getset
,long *g
);
356 extern long Xig1
[],Xig2
[];
360 Abort unless random number generator initialized
364 fprintf(stderr
,"%s\n",
365 " SETSD called before random number generator initialized -- abort!");
369 *(Xig1
+g
-1) = iseed1
;
370 *(Xig2
+g
-1) = iseed2
;