File Coverage

randlib.c
Criterion Covered Total %
statement 446 767 58.1
branch 192 390 49.2
condition n/a
subroutine n/a
pod n/a
total 638 1157 55.1


line stmt bran cond sub pod time code
1             #include "randlib.h"
2             #include
3             #include
4             #include
5             #define ABS(x) ((x) >= 0 ? (x) : -(x))
6             #define min(a,b) ((a) <= (b) ? (a) : (b))
7             #define max(a,b) ((a) >= (b) ? (a) : (b))
8             void ftnstop(char*);
9              
10 6           double genbet(double aa,double bb)
11             /*
12             **********************************************************************
13             double genbet(double aa,double bb)
14             GeNerate BETa random deviate
15             Function
16             Returns a single random deviate from the beta distribution with
17             parameters A and B. The density of the beta is
18             x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1
19             Arguments
20             aa --> First parameter of the beta distribution
21            
22             bb --> Second parameter of the beta distribution
23              
24             Method
25             R. C. H. Cheng
26             Generating Beta Variates with Nonintegral Shape Parameters
27             Communications of the ACM, 21:317-322 (1978)
28             (Algorithms BB and BC)
29             **********************************************************************
30             */
31             {
32             /* JJV changed expmax (log(1.0E38)==87.49823), and added minlog */
33             #define expmax 87.4982335337737
34             #define infnty 1.0E38
35             #define minlog 1.0E-37
36             static double olda = -1.0E37;
37             static double oldb = -1.0E37;
38             static double genbet,a,alpha,b,beta,delta,gamma,k1,k2,r,s,t,u1,u2,v,w,y,z;
39             static long qsame;
40              
41 6 100         qsame = olda == aa && oldb == bb;
    50          
42 6 100         if(qsame) goto S20;
43 1 50         if(!(aa < minlog || bb < minlog)) goto S10;
    50          
44 0           fputs(" AA or BB < 1.0E-37 in GENBET - Abort!\n",stderr);
45 0           fprintf(stderr," AA: %16.6E BB %16.6E\n",aa,bb);
46 0           exit(1);
47 1           S10:
48 1           olda = aa;
49 1           oldb = bb;
50 6           S20:
51 6 50         if(!(min(aa,bb) > 1.0)) goto S100;
    50          
52             /*
53             Algorithm BB
54             Initialize
55             */
56 6 100         if(qsame) goto S30;
57 1 50         a = min(aa,bb);
58 1 50         b = max(aa,bb);
59 1           alpha = a+b;
60 1           beta = sqrt((alpha-2.0)/(2.0*a*b-alpha));
61 1           gamma = a+1.0/beta;
62 0           S30:
63 6           u1 = ranf();
64             /*
65             Step 1
66             */
67 6           u2 = ranf();
68 6           v = beta*log(u1/(1.0-u1));
69             /* JJV altered this */
70 6 50         if(v > expmax) goto S55;
71             /*
72             * JJV added checker to see if a*exp(v) will overflow
73             * JJV S50 _was_ w = a*exp(v); also note here a > 1.0
74             */
75 6           w = exp(v);
76 6 50         if(w > infnty/a) goto S55;
77 6           w *= a;
78 6           goto S60;
79 0           S55:
80 0           w = infnty;
81 6           S60:
82 6           z = pow(u1,2.0)*u2;
83 6           r = gamma*v-1.38629436111989;
84 6           s = a+r-w;
85             /*
86             Step 2
87             */
88 6 100         if(s+2.60943791243410 >= 5.0*z) goto S70;
89             /*
90             Step 3
91             */
92 2           t = log(z);
93 2 50         if(s > t) goto S70;
94             /*
95             * Step 4
96             *
97             * JJV added checker to see if log(alpha/(b+w)) will
98             * JJV overflow. If so, we count the log as -INF, and
99             * JJV consequently evaluate conditional as true, i.e.
100             * JJV the algorithm rejects the trial and starts over
101             * JJV May not need this here since alpha > 2.0
102             */
103 0 0         if(alpha/(b+w) < minlog) goto S30;
104 0 0         if(r+alpha*log(alpha/(b+w)) < t) goto S30;
105 0           S70:
106             /*
107             Step 5
108             */
109 6 50         if(aa == a) {
110 6           genbet = w/(b+w);
111             } else {
112 0           genbet = b/(b+w);
113             }
114 6           goto S230;
115 0           S100:
116             /*
117             Algorithm BC
118             Initialize
119             */
120 0 0         if(qsame) goto S110;
121 0 0         a = max(aa,bb);
122 0 0         b = min(aa,bb);
123 0           alpha = a+b;
124 0           beta = 1.0/b;
125 0           delta = 1.0+a-b;
126 0           k1 = delta*(1.38888888888889E-2+4.16666666666667E-2*b) /
127 0           (a*beta-0.777777777777778);
128 0           k2 = 0.25+(0.5+0.25/delta)*b;
129 0           S110:
130 0           S120:
131 0           u1 = ranf();
132             /*
133             Step 1
134             */
135 0           u2 = ranf();
136 0 0         if(u1 >= 0.5) goto S130;
137             /*
138             Step 2
139             */
140 0           y = u1*u2;
141 0           z = u1*y;
142 0 0         if(0.25*u2+z-y >= k1) goto S120;
143 0           goto S170;
144 0           S130:
145             /*
146             Step 3
147             */
148 0           z = pow(u1,2.0)*u2;
149 0 0         if(!(z <= 0.25)) goto S160;
150 0           v = beta*log(u1/(1.0-u1));
151             /*
152             * JJV instead of checking v > expmax at top, I will check
153             * JJV if a < 1, then check the appropriate values
154             */
155 0 0         if(a > 1.0) goto S135;
156             /* JJV a < 1 so it can help out if exp(v) would overflow */
157 0 0         if(v > expmax) goto S132;
158 0           w = a*exp(v);
159 0           goto S200;
160 0           S132:
161 0           w = v + log(a);
162 0 0         if(w > expmax) goto S140;
163 0           w = exp(w);
164 0           goto S200;
165 0           S135:
166             /* JJV in this case a > 1 */
167 0 0         if(v > expmax) goto S140;
168 0           w = exp(v);
169 0 0         if(w > infnty/a) goto S140;
170 0           w *= a;
171 0           goto S200;
172 0           S140:
173 0           w = infnty;
174 0           goto S200;
175             /*
176             * JJV old code
177             * if(!(v > expmax)) goto S140;
178             * w = infnty;
179             * goto S150;
180             *S140:
181             * w = a*exp(v);
182             *S150:
183             * goto S200;
184             */
185 0           S160:
186 0 0         if(z >= k2) goto S120;
187 0           S170:
188             /*
189             Step 4
190             Step 5
191             */
192 0           v = beta*log(u1/(1.0-u1));
193             /* JJV same kind of checking as above */
194 0 0         if(a > 1.0) goto S175;
195             /* JJV a < 1 so it can help out if exp(v) would overflow */
196 0 0         if(v > expmax) goto S172;
197 0           w = a*exp(v);
198 0           goto S190;
199 0           S172:
200 0           w = v + log(a);
201 0 0         if(w > expmax) goto S180;
202 0           w = exp(w);
203 0           goto S190;
204 0           S175:
205             /* JJV in this case a > 1.0 */
206 0 0         if(v > expmax) goto S180;
207 0           w = exp(v);
208 0 0         if(w > infnty/a) goto S180;
209 0           w *= a;
210 0           goto S190;
211 0           S180:
212 0           w = infnty;
213             /*
214             * JJV old code
215             * if(!(v > expmax)) goto S180;
216             * w = infnty;
217             * goto S190;
218             *S180:
219             * w = a*exp(v);
220             */
221 0           S190:
222             /*
223             * JJV here we also check to see if log overlows; if so, we treat it
224             * JJV as -INF, which means condition is true, i.e. restart
225             */
226 0 0         if(alpha/(b+w) < minlog) goto S120;
227 0 0         if(alpha*(log(alpha/(b+w))+v)-1.38629436111989 < log(z)) goto S120;
228 0           S200:
229             /*
230             Step 6
231             */
232 0 0         if(a == aa) {
233 0           genbet = w/(b+w);
234             } else {
235 0           genbet = b/(b+w);
236             }
237 6           S230:
238 6           return genbet;
239             #undef expmax
240             #undef infnty
241             #undef minlog
242             }
243              
244 6           double genchi(double df)
245             /*
246             **********************************************************************
247             double genchi(double df)
248             Generate random value of CHIsquare variable
249             Function
250             Generates random deviate from the distribution of a chisquare
251             with DF degrees of freedom random variable.
252             Arguments
253             df --> Degrees of freedom of the chisquare
254             (Must be positive)
255            
256             Method
257             Uses relation between chisquare and gamma.
258             **********************************************************************
259             */
260             {
261             static double genchi;
262              
263 6 50         if(!(df <= 0.0)) goto S10;
264 0           fputs(" DF <= 0 in GENCHI - ABORT\n",stderr);
265 0           fprintf(stderr," Value of DF: %16.6E\n",df);
266 0           exit(1);
267 6           S10:
268             /*
269             * JJV changed the code to call SGAMMA directly
270             * genchi = 2.0*gengam(1.0,df/2.0); <- OLD
271             */
272 6           genchi = 2.0*sgamma(df/2.0);
273 6           return genchi;
274             }
275              
276 6           double genexp(double av)
277             /*
278             **********************************************************************
279             double genexp(double av)
280             GENerate EXPonential random deviate
281             Function
282             Generates a single random deviate from an exponential
283             distribution with mean AV.
284             Arguments
285             av --> The mean of the exponential distribution from which
286             a random deviate is to be generated.
287             JJV (av >= 0)
288             Method
289             Renames SEXPO from TOMS as slightly modified by BWB to use RANF
290             instead of SUNIF.
291             For details see:
292             Ahrens, J.H. and Dieter, U.
293             Computer Methods for Sampling From the
294             Exponential and Normal Distributions.
295             Comm. ACM, 15,10 (Oct. 1972), 873 - 882.
296             **********************************************************************
297             */
298             {
299             static double genexp;
300              
301             /* JJV added check that av >= 0 */
302 6 50         if(av >= 0.0) goto S10;
303 0           fputs(" AV < 0 in GENEXP - ABORT\n",stderr);
304 0           fprintf(stderr," Value of AV: %16.6E\n",av);
305 0           exit(1);
306 6           S10:
307 6           genexp = sexpo()*av;
308 6           return genexp;
309             }
310              
311 6           double genf(double dfn,double dfd)
312             /*
313             **********************************************************************
314             double genf(double dfn,double dfd)
315             GENerate random deviate from the F distribution
316             Function
317             Generates a random deviate from the F (variance ratio)
318             distribution with DFN degrees of freedom in the numerator
319             and DFD degrees of freedom in the denominator.
320             Arguments
321             dfn --> Numerator degrees of freedom
322             (Must be positive)
323             dfd --> Denominator degrees of freedom
324             (Must be positive)
325             Method
326             Directly generates ratio of chisquare variates
327             **********************************************************************
328             */
329             {
330             static double genf,xden,xnum;
331              
332 6 50         if(!(dfn <= 0.0 || dfd <= 0.0)) goto S10;
    50          
333 0           fputs(" Degrees of freedom nonpositive in GENF - abort!\n",stderr);
334 0           fprintf(stderr," DFN value: %16.6E DFD value: %16.6E\n",dfn,dfd);
335 0           exit(1);
336 6           S10:
337             /*
338             * JJV changed this to call SGAMMA directly
339             *
340             * GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD )
341             * xnum = genchi(dfn)/dfn; <- OLD
342             * xden = genchi(dfd)/dfd; <- OLD
343             */
344 6           xnum = 2.0*sgamma(dfn/2.0)/dfn;
345 6           xden = 2.0*sgamma(dfd/2.0)/dfd;
346             /*
347             * JJV changed constant to prevent underflow at compile time.
348             * if(!(xden <= 9.999999999998E-39*xnum)) goto S20;
349             */
350 6 50         if(!(xden <= 1.0E-37*xnum)) goto S20;
351 0           fputs(" GENF - generated numbers would cause overflow\n",stderr);
352 0           fprintf(stderr," Numerator %16.6E Denominator %16.6E\n",xnum,xden);
353             /*
354             * JJV changed next 2 lines to reflect constant change above in the
355             * JJV truncated value returned.
356             * fputs(" GENF returning 1.0E38\n",stderr);
357             * genf = 1.0E38;
358             */
359 0           fputs(" GENF returning 1.0E37\n",stderr);
360 0           genf = 1.0E37;
361 0           goto S30;
362 6           S20:
363 6           genf = xnum/xden;
364 6           S30:
365 6           return genf;
366             }
367              
368 6           double gengam(double a,double r)
369             /*
370             **********************************************************************
371             double gengam(double a,double r)
372             GENerates random deviates from GAMma distribution
373             Function
374             Generates random deviates from the gamma distribution whose
375             density is
376             (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)
377             Arguments
378             a --> Location parameter of Gamma distribution
379             JJV (a > 0)
380             r --> Shape parameter of Gamma distribution
381             JJV (r > 0)
382             Method
383             Renames SGAMMA from TOMS as slightly modified by BWB to use RANF
384             instead of SUNIF.
385             For details see:
386             (Case R >= 1.0)
387             Ahrens, J.H. and Dieter, U.
388             Generating Gamma Variates by a
389             Modified Rejection Technique.
390             Comm. ACM, 25,1 (Jan. 1982), 47 - 54.
391             Algorithm GD
392             JJV altered following to reflect argument ranges
393             (Case 0.0 < R < 1.0)
394             Ahrens, J.H. and Dieter, U.
395             Computer Methods for Sampling from Gamma,
396             Beta, Poisson and Binomial Distributions.
397             Computing, 12 (1974), 223-246/
398             Adapted algorithm GS.
399             **********************************************************************
400             */
401             {
402             static double gengam;
403             /* JJV added argument checker */
404 6 50         if(a > 0.0 && r > 0.0) goto S10;
    50          
405 0           fputs(" A or R nonpositive in GENGAM - abort!\n",stderr);
406 0           fprintf(stderr," A value: %16.6E R value: %16.6E\n",a,r);
407 0           exit(1);
408 6           S10:
409 6           gengam = sgamma(r);
410 6           gengam /= a;
411 6           return gengam;
412             }
413              
414 4           void genmn(double *parm,double *x,double *work)
415             /*
416             **********************************************************************
417             void genmn(double *parm,double *x,double *work)
418             GENerate Multivariate Normal random deviate
419             Arguments
420             parm --> Parameters needed to generate multivariate normal
421             deviates (MEANV and Cholesky decomposition of
422             COVM). Set by a previous call to SETGMN.
423             1 : 1 - size of deviate, P
424             2 : P + 1 - mean vector
425             P+2 : P*(P+3)/2 + 1 - upper half of cholesky
426             decomposition of cov matrix
427             x <-- Vector deviate generated.
428             work <--> Scratch array
429             Method
430             1) Generate P independent standard normal deviates - Ei ~ N(0,1)
431             2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM
432             3) trans(A)E + MEANV ~ N(MEANV,COVM)
433             **********************************************************************
434             */
435             {
436             static long i,icount,j,p,D1,D2,D3,D4;
437             static double ae;
438              
439 4           p = (long) (*parm);
440             /*
441             Generate P independent normal deviates - WORK ~ N(0,1)
442             */
443 12 100         for(i=1; i<=p; i++) *(work+i-1) = snorm();
444 12 100         for(i=1,D3=1,D4=(p-i+D3)/D3; D4>0; D4--,i+=D3) {
445             /*
446             PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky
447             decomposition of the desired covariance matrix.
448             trans(A)(1,1) = PARM(P+2)
449             trans(A)(2,1) = PARM(P+3)
450             trans(A)(2,2) = PARM(P+2+P)
451             trans(A)(3,1) = PARM(P+4)
452             trans(A)(3,2) = PARM(P+3+P)
453             trans(A)(3,3) = PARM(P+2-1+2P) ...
454             trans(A)*WORK + MEANV ~ N(MEANV,COVM)
455             */
456 8           icount = 0;
457 8           ae = 0.0;
458 20 100         for(j=1,D1=1,D2=(i-j+D1)/D1; D2>0; D2--,j+=D1) {
459 12           icount += (j-1);
460 12           ae += (*(parm+i+(j-1)*p-icount+p)**(work+j-1));
461             }
462 8           *(x+i-1) = ae+*(parm+i);
463             }
464 4           }
465              
466 2           void genmul(long n,double *p,long ncat,long *ix)
467             /*
468             **********************************************************************
469            
470             void genmul(int n,double *p,int ncat,int *ix)
471             GENerate an observation from the MULtinomial distribution
472             Arguments
473             N --> Number of events that will be classified into one of
474             the categories 1..NCAT
475             P --> Vector of probabilities. P(i) is the probability that
476             an event will be classified into category i. Thus, P(i)
477             must be [0,1]. Only the first NCAT-1 P(i) must be defined
478             since P(NCAT) is 1.0 minus the sum of the first
479             NCAT-1 P(i).
480             NCAT --> Number of categories. Length of P and IX.
481             IX <-- Observation from multinomial distribution. All IX(i)
482             will be nonnegative and their sum will be N.
483             Method
484             Algorithm from page 559 of
485            
486             Devroye, Luc
487            
488             Non-Uniform Random Variate Generation. Springer-Verlag,
489             New York, 1986.
490            
491             **********************************************************************
492             */
493             {
494             static double prob,ptot,sum;
495             static long i,icat,ntot;
496 2 50         if(n < 0) ftnstop("N < 0 in GENMUL");
497 2 50         if(ncat <= 1) ftnstop("NCAT <= 1 in GENMUL");
498 2           ptot = 0.0F;
499 6 100         for(i=0; i
500 4 50         if(*(p+i) < 0.0F) ftnstop("Some P(i) < 0 in GENMUL");
501 4 50         if(*(p+i) > 1.0F) ftnstop("Some P(i) > 1 in GENMUL");
502 4           ptot += *(p+i);
503             }
504 2 50         if(ptot > 0.99999F) ftnstop("Sum of P(i) > 1 in GENMUL");
505             /*
506             Initialize variables
507             */
508 2           ntot = n;
509 2           sum = 1.0F;
510 8 100         for(i=0; i
511             /*
512             Generate the observation
513             */
514 6 100         for(icat=0; icat
515 4           prob = *(p+icat)/sum;
516 4           *(ix+icat) = ignbin(ntot,prob);
517 4           ntot -= *(ix+icat);
518 4 50         if(ntot <= 0) return;
519 4           sum -= *(p+icat);
520             }
521 2           *(ix+ncat-1) = ntot;
522             /*
523             Finished
524             */
525 2           return;
526             }
527              
528 6           double gennch(double df,double xnonc)
529             /*
530             **********************************************************************
531             double gennch(double df,double xnonc)
532             Generate random value of Noncentral CHIsquare variable
533             Function
534             Generates random deviate from the distribution of a noncentral
535             chisquare with DF degrees of freedom and noncentrality parameter
536             xnonc.
537             Arguments
538             df --> Degrees of freedom of the chisquare
539             (Must be >= 1.0)
540             xnonc --> Noncentrality parameter of the chisquare
541             (Must be >= 0.0)
542             Method
543             Uses fact that noncentral chisquare is the sum of a chisquare
544             deviate with DF-1 degrees of freedom plus the square of a normal
545             deviate with mean XNONC and standard deviation 1.
546             **********************************************************************
547             */
548             {
549             static double gennch;
550              
551 6 50         if(!(df < 1.0 || xnonc < 0.0)) goto S10;
    50          
552 0           fputs("DF < 1 or XNONC < 0 in GENNCH - ABORT\n",stderr);
553 0           fprintf(stderr,"Value of DF: %16.6E Value of XNONC: %16.6E\n",df,xnonc);
554 0           exit(1);
555             /* JJV changed code to call SGAMMA, SNORM directly */
556 6           S10:
557 6 50         if(df >= 1.000000001) goto S20;
558             /*
559             * JJV case df == 1.0
560             * gennch = pow(gennor(sqrt(xnonc),1.0),2.0); <- OLD
561             */
562 0           gennch = pow(snorm()+sqrt(xnonc),2.0);
563 0           goto S30;
564 6           S20:
565             /*
566             * JJV case df > 1.0
567             * gennch = genchi(df-1.0)+pow(gennor(sqrt(xnonc),1.0),2.0); <- OLD
568             */
569             /* the following expression is split to ensure consistent evaluation
570             across platforms. since sgamma() and snorm() both change the state
571             of the random number generator, it is important that they be evaluated
572             in the same order, regardless of how the compiler chooses to order
573             things
574              
575             gennch = 2.0*sgamma((df-1.0)/2.0)+pow(snorm()+sqrt(xnonc),2.0;
576             */
577             {
578             double t1, t2;
579 6           t1 = 2.0*sgamma((df-1.0)/2.0);
580 6           t2 = pow(snorm()+sqrt(xnonc),2.0);
581 6           gennch = t1 + t2;
582             }
583 6           S30:
584 6           return gennch;
585             }
586              
587 6           double gennf(double dfn,double dfd,double xnonc)
588             /*
589             **********************************************************************
590             double gennf(double dfn,double dfd,double xnonc)
591             GENerate random deviate from the Noncentral F distribution
592             Function
593             Generates a random deviate from the noncentral F (variance ratio)
594             distribution with DFN degrees of freedom in the numerator, and DFD
595             degrees of freedom in the denominator, and noncentrality parameter
596             XNONC.
597             Arguments
598             dfn --> Numerator degrees of freedom
599             (Must be >= 1.0)
600             dfd --> Denominator degrees of freedom
601             (Must be positive)
602             xnonc --> Noncentrality parameter
603             (Must be nonnegative)
604             Method
605             Directly generates ratio of noncentral numerator chisquare variate
606             to central denominator chisquare variate.
607             **********************************************************************
608             */
609             {
610             static double gennf,xden,xnum;
611             static long qcond;
612              
613             /* JJV changed qcond, error message to allow dfn == 1.0 */
614 6 50         qcond = dfn < 1.0 || dfd <= 0.0 || xnonc < 0.0;
    50          
    50          
615 6 50         if(!qcond) goto S10;
616 0           fputs("In GENNF - Either (1) Numerator DF < 1.0 or\n",stderr);
617 0           fputs(" (2) Denominator DF <= 0.0 or\n",stderr);
618 0           fputs(" (3) Noncentrality parameter < 0.0\n",stderr);
619 0           fprintf(stderr,
620             "DFN value: %16.6E DFD value: %16.6E XNONC value: \n%16.6E\n",dfn,dfd,
621             xnonc);
622 0           exit(1);
623 6           S10:
624             /*
625             * JJV changed the code to call SGAMMA and SNORM directly
626             * GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD )
627             * xnum = gennch(dfn,xnonc)/dfn; <- OLD
628             * xden = genchi(dfd)/dfd; <- OLD
629             */
630 6 50         if(dfn >= 1.000001) goto S20;
631             /* JJV case dfn == 1.0, dfn is counted as exactly 1.0 */
632 0           xnum = pow(snorm()+sqrt(xnonc),2.0);
633 0           goto S30;
634 6           S20:
635             /* JJV case df > 1.0 */
636             /* the following expression is split to ensure consistent evaluation
637             across platforms. since sgamma() and snorm() both change the state
638             of the random number generator, it is important that they be evaluated
639             in the same order, regardless of how the compiler chooses to order
640             things
641              
642             xnum = (2.0*sgamma((dfn-1.0)/2.0)+pow(snorm()+sqrt(xnonc),2.0))/dfn;
643             */
644             {
645             double t1, t2;
646 6           t1 = 2.0*sgamma((dfn-1.0)/2.0);
647 6           t2 = pow(snorm()+sqrt(xnonc),2.0);
648 6           xnum = (t1 + t2) / dfn;
649             }
650 6           S30:
651 6           xden = 2.0*sgamma(dfd/2.0)/dfd;
652             /*
653             * JJV changed constant to prevent underflow at compile time.
654             * if(!(xden <= 9.999999999998E-39*xnum)) goto S40;
655             */
656 6 50         if(!(xden <= 1.0E-37*xnum)) goto S40;
657 0           fputs(" GENNF - generated numbers would cause overflow\n",stderr);
658 0           fprintf(stderr," Numerator %16.6E Denominator %16.6E\n",xnum,xden);
659             /*
660             * JJV changed next 2 lines to reflect constant change above in the
661             * JJV truncated value returned.
662             * fputs(" GENNF returning 1.0E38\n",stderr);
663             * gennf = 1.0E38;
664             */
665 0           fputs(" GENNF returning 1.0E37\n",stderr);
666 0           gennf = 1.0E37;
667 0           goto S50;
668 6           S40:
669 6           gennf = xnum/xden;
670 6           S50:
671 6           return gennf;
672             }
673              
674 6           double gennor(double av,double sd)
675             /*
676             **********************************************************************
677             double gennor(double av,double sd)
678             GENerate random deviate from a NORmal distribution
679             Function
680             Generates a single random deviate from a normal distribution
681             with mean, AV, and standard deviation, SD.
682             Arguments
683             av --> Mean of the normal distribution.
684             sd --> Standard deviation of the normal distribution.
685             JJV (sd >= 0)
686             Method
687             Renames SNORM from TOMS as slightly modified by BWB to use RANF
688             instead of SUNIF.
689             For details see:
690             Ahrens, J.H. and Dieter, U.
691             Extensions of Forsythe's Method for Random
692             Sampling from the Normal Distribution.
693             Math. Comput., 27,124 (Oct. 1973), 927 - 937.
694             **********************************************************************
695             */
696             {
697             static double gennor;
698              
699             /* JJV added argument checker */
700 6 50         if(sd >= 0.0) goto S10;
701 0           fputs(" SD < 0 in GENNOR - ABORT\n",stderr);
702 0           fprintf(stderr," Value of SD: %16.6E\n",sd);
703 0           exit(1);
704 6           S10:
705 6           gennor = sd*snorm()+av;
706 6           return gennor;
707             }
708              
709 4           void genprm(long *iarray,int larray)
710             /*
711             **********************************************************************
712             void genprm(long *iarray,int larray)
713             GENerate random PeRMutation of iarray
714             Arguments
715             iarray <--> On output IARRAY is a random permutation of its
716             value on input
717             larray <--> Length of IARRAY
718             **********************************************************************
719             */
720             {
721             static long i,itmp,iwhich,D1,D2;
722              
723 38 100         for(i=1,D1=1,D2=(larray-i+D1)/D1; D2>0; D2--,i+=D1) {
724 34           iwhich = ignuin(i,larray);
725 34           itmp = *(iarray+iwhich-1);
726 34           *(iarray+iwhich-1) = *(iarray+i-1);
727 34           *(iarray+i-1) = itmp;
728             }
729 4           }
730              
731 14           double genunf(double low,double high)
732             /*
733             **********************************************************************
734             double genunf(double low,double high)
735             GeNerate Uniform Real between LOW and HIGH
736             Function
737             Generates a real uniformly distributed between LOW and HIGH.
738             Arguments
739             low --> Low bound (exclusive) on real value to be generated
740             high --> High bound (exclusive) on real value to be generated
741             **********************************************************************
742             */
743             {
744             static double genunf;
745              
746 14 50         if(!(low > high)) goto S10;
747 0           fprintf(stderr,"LOW > HIGH in GENUNF: LOW %16.6E HIGH: %16.6E\n",low,high);
748 0           fputs("Abort\n",stderr);
749 0           exit(1);
750 14           S10:
751 14           genunf = low+(high-low)*ranf();
752 14           return genunf;
753             }
754              
755 1535           void gscgn(long getset,long *g)
756             /*
757             **********************************************************************
758             void gscgn(long getset,long *g)
759             Get/Set GeNerator
760             Gets or returns in G the number of the current generator
761             Arguments
762             getset --> 0 Get
763             1 Set
764             g <-- Number of the current random number generator (1..32)
765             **********************************************************************
766             */
767             {
768             #define numg 32L
769             static long curntg = 1;
770 1535 100         if(getset == 0) *g = curntg;
771             else {
772 513 50         if(*g < 0 || *g > numg) {
    50          
773 0           fputs(" Generator number out of range in GSCGN\n",stderr);
774 0           exit(0);
775             }
776 513           curntg = *g;
777             }
778             #undef numg
779 1535           }
780              
781 1022           void gsrgs(long getset,long *qvalue)
782             /*
783             **********************************************************************
784             void gsrgs(long getset,long *qvalue)
785             Get/Set Random Generators Set
786             Gets or sets whether random generators set (initialized).
787             Initially (data statement) state is not set
788             If getset is 1 state is set to qvalue
789             If getset is 0 state returned in qvalue
790             **********************************************************************
791             */
792             {
793             static long qinit = 0;
794              
795 1022 100         if(getset == 0) *qvalue = qinit;
796 3           else qinit = *qvalue;
797 1022           }
798              
799 485           void gssst(long getset,long *qset)
800             /*
801             **********************************************************************
802             void gssst(long getset,long *qset)
803             Get or Set whether Seed is Set
804             Initialize to Seed not Set
805             If getset is 1 sets state to Seed Set
806             If getset is 0 returns T in qset if Seed Set
807             Else returns F in qset
808             **********************************************************************
809             */
810             {
811             static long qstate = 0;
812 485 100         if(getset != 0) qstate = 1;
813 469           else *qset = qstate;
814 485           }
815              
816 10           long ignbin(long n,double pp)
817             /*
818             **********************************************************************
819             long ignbin(long n,double pp)
820             GENerate BINomial random deviate
821             Function
822             Generates a single random deviate from a binomial
823             distribution whose number of trials is N and whose
824             probability of an event in each trial is P.
825             Arguments
826             n --> The number of trials in the binomial distribution
827             from which a random deviate is to be generated.
828             JJV (N >= 0)
829             pp --> The probability of an event in each trial of the
830             binomial distribution from which a random deviate
831             is to be generated.
832             JJV (0.0 <= PP <= 1.0)
833             ignbin <-- A random deviate yielding the number of events
834             from N independent trials, each of which has
835             a probability of event P.
836             Method
837             This is algorithm BTPE from:
838             Kachitvichyanukul, V. and Schmeiser, B. W.
839             Binomial Random Variate Generation.
840             Communications of the ACM, 31, 2
841             (February, 1988) 216.
842             **********************************************************************
843             SUBROUTINE BTPEC(N,PP,ISEED,JX)
844             BINOMIAL RANDOM VARIATE GENERATOR
845             MEAN .LT. 30 -- INVERSE CDF
846             MEAN .GE. 30 -- ALGORITHM BTPE: ACCEPTANCE-REJECTION VIA
847             FOUR REGION COMPOSITION. THE FOUR REGIONS ARE A TRIANGLE
848             (SYMMETRIC IN THE CENTER), A PAIR OF PARALLELOGRAMS (ABOVE
849             THE TRIANGLE), AND EXPONENTIAL LEFT AND RIGHT TAILS.
850             BTPE REFERS TO BINOMIAL-TRIANGLE-PARALLELOGRAM-EXPONENTIAL.
851             BTPEC REFERS TO BTPE AND "COMBINED." THUS BTPE IS THE
852             RESEARCH AND BTPEC IS THE IMPLEMENTATION OF A COMPLETE
853             USABLE ALGORITHM.
854             REFERENCE: VORATAS KACHITVICHYANUKUL AND BRUCE SCHMEISER,
855             "BINOMIAL RANDOM VARIATE GENERATION,"
856             COMMUNICATIONS OF THE ACM, FORTHCOMING
857             WRITTEN: SEPTEMBER 1980.
858             LAST REVISED: MAY 1985, JULY 1987
859             REQUIRED SUBPROGRAM: RAND() -- A UNIFORM (0,1) RANDOM NUMBER
860             GENERATOR
861             ARGUMENTS
862             N : NUMBER OF BERNOULLI TRIALS (INPUT)
863             PP : PROBABILITY OF SUCCESS IN EACH TRIAL (INPUT)
864             ISEED: RANDOM NUMBER SEED (INPUT AND OUTPUT)
865             JX: RANDOMLY GENERATED OBSERVATION (OUTPUT)
866             VARIABLES
867             PSAVE: VALUE OF PP FROM THE LAST CALL TO BTPEC
868             NSAVE: VALUE OF N FROM THE LAST CALL TO BTPEC
869             XNP: VALUE OF THE MEAN FROM THE LAST CALL TO BTPEC
870             P: PROBABILITY USED IN THE GENERATION PHASE OF BTPEC
871             FFM: TEMPORARY VARIABLE EQUAL TO XNP + P
872             M: INTEGER VALUE OF THE CURRENT MODE
873             FM: FLOATING POINT VALUE OF THE CURRENT MODE
874             XNPQ: TEMPORARY VARIABLE USED IN SETUP AND SQUEEZING STEPS
875             P1: AREA OF THE TRIANGLE
876             C: HEIGHT OF THE PARALLELOGRAMS
877             XM: CENTER OF THE TRIANGLE
878             XL: LEFT END OF THE TRIANGLE
879             XR: RIGHT END OF THE TRIANGLE
880             AL: TEMPORARY VARIABLE
881             XLL: RATE FOR THE LEFT EXPONENTIAL TAIL
882             XLR: RATE FOR THE RIGHT EXPONENTIAL TAIL
883             P2: AREA OF THE PARALLELOGRAMS
884             P3: AREA OF THE LEFT EXPONENTIAL TAIL
885             P4: AREA OF THE RIGHT EXPONENTIAL TAIL
886             U: A U(0,P4) RANDOM VARIATE USED FIRST TO SELECT ONE OF THE
887             FOUR REGIONS AND THEN CONDITIONALLY TO GENERATE A VALUE
888             FROM THE REGION
889             V: A U(0,1) RANDOM NUMBER USED TO GENERATE THE RANDOM VALUE
890             (REGION 1) OR TRANSFORMED INTO THE VARIATE TO ACCEPT OR
891             REJECT THE CANDIDATE VALUE
892             IX: INTEGER CANDIDATE VALUE
893             X: PRELIMINARY CONTINUOUS CANDIDATE VALUE IN REGION 2 LOGIC
894             AND A FLOATING POINT IX IN THE ACCEPT/REJECT LOGIC
895             K: ABSOLUTE VALUE OF (IX-M)
896             F: THE HEIGHT OF THE SCALED DENSITY FUNCTION USED IN THE
897             ACCEPT/REJECT DECISION WHEN BOTH M AND IX ARE SMALL
898             ALSO USED IN THE INVERSE TRANSFORMATION
899             R: THE RATIO P/Q
900             G: CONSTANT USED IN CALCULATION OF PROBABILITY
901             MP: MODE PLUS ONE, THE LOWER INDEX FOR EXPLICIT CALCULATION
902             OF F WHEN IX IS GREATER THAN M
903             IX1: CANDIDATE VALUE PLUS ONE, THE LOWER INDEX FOR EXPLICIT
904             CALCULATION OF F WHEN IX IS LESS THAN M
905             I: INDEX FOR EXPLICIT CALCULATION OF F FOR BTPE
906             AMAXP: MAXIMUM ERROR OF THE LOGARITHM OF NORMAL BOUND
907             YNORM: LOGARITHM OF NORMAL BOUND
908             ALV: NATURAL LOGARITHM OF THE ACCEPT/REJECT VARIATE V
909             X1,F1,Z,W,Z2,X2,F2, AND W2 ARE TEMPORARY VARIABLES TO BE
910             USED IN THE FINAL ACCEPT/REJECT TEST
911             QN: PROBABILITY OF NO SUCCESS IN N TRIALS
912             REMARK
913             IX AND JX COULD LOGICALLY BE THE SAME VARIABLE, WHICH WOULD
914             SAVE A MEMORY POSITION AND A LINE OF CODE. HOWEVER, SOME
915             COMPILERS (E.G.,CDC MNF) OPTIMIZE BETTER WHEN THE ARGUMENTS
916             ARE NOT INVOLVED.
917             ISEED NEEDS TO BE DOUBLE PRECISION IF THE IMSL ROUTINE
918             GGUBFS IS USED TO GENERATE UNIFORM RANDOM NUMBER, OTHERWISE
919             TYPE OF ISEED SHOULD BE DICTATED BY THE UNIFORM GENERATOR
920             **********************************************************************
921             *****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY
922             */
923             {
924             /* JJV changed initial values to ridiculous values */
925             static double psave = -1.0E37;
926             static long nsave = -214748365;
927             static long ignbin,i,ix,ix1,k,m,mp,T1;
928             static double al,alv,amaxp,c,f,f1,f2,ffm,fm,g,p,p1,p2,p3,p4,q,qn,r,u,v,w,w2,x,x1,
929             x2,xl,xll,xlr,xm,xnp,xnpq,xr,ynorm,z,z2;
930              
931 10 100         if(pp != psave) goto S10;
932 4 50         if(n != nsave) goto S20;
933 4 50         if(xnp < 30.0) goto S150;
934 0           goto S30;
935 6           S10:
936             /*
937             *****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE
938             JJV added checks to ensure 0.0 <= PP <= 1.0
939             */
940 6 50         if(pp < 0.0F) ftnstop("PP < 0.0 in IGNBIN");
941 6 50         if(pp > 1.0F) ftnstop("PP > 1.0 in IGNBIN");
942 6           psave = pp;
943 6 100         p = min(psave,1.0-psave);
944 6           q = 1.0-p;
945 6           S20:
946             /*
947             JJV added check to ensure N >= 0
948             */
949 6 50         if(n < 0L) ftnstop("N < 0 in IGNBIN");
950 6           xnp = n*p;
951 6           nsave = n;
952 6 50         if(xnp < 30.0) goto S140;
953 0           ffm = xnp+p;
954 0           m = ffm;
955 0           fm = m;
956 0           xnpq = xnp*q;
957 0           p1 = (long) (2.195*sqrt(xnpq)-4.6*q)+0.5;
958 0           xm = fm+0.5;
959 0           xl = xm-p1;
960 0           xr = xm+p1;
961 0           c = 0.134+20.5/(15.3+fm);
962 0           al = (ffm-xl)/(ffm-xl*p);
963 0           xll = al*(1.0+0.5*al);
964 0           al = (xr-ffm)/(xr*q);
965 0           xlr = al*(1.0+0.5*al);
966 0           p2 = p1*(1.0+c+c);
967 0           p3 = p2+c/xll;
968 0           p4 = p3+c/xlr;
969 0           S30:
970             /*
971             *****GENERATE VARIATE
972             */
973 0           u = ranf()*p4;
974 0           v = ranf();
975             /*
976             TRIANGULAR REGION
977             */
978 0 0         if(u > p1) goto S40;
979 0           ix = xm-p1*v+u;
980 0           goto S170;
981 0           S40:
982             /*
983             PARALLELOGRAM REGION
984             */
985 0 0         if(u > p2) goto S50;
986 0           x = xl+(u-p1)/c;
987 0 0         v = v*c+1.0-ABS(xm-x)/p1;
988 0 0         if(v > 1.0 || v <= 0.0) goto S30;
    0          
989 0           ix = x;
990 0           goto S70;
991 0           S50:
992             /*
993             LEFT TAIL
994             */
995 0 0         if(u > p3) goto S60;
996 0           ix = xl+log(v)/xll;
997 0 0         if(ix < 0) goto S30;
998 0           v *= ((u-p2)*xll);
999 0           goto S70;
1000 0           S60:
1001             /*
1002             RIGHT TAIL
1003             */
1004 0           ix = xr-log(v)/xlr;
1005 0 0         if(ix > n) goto S30;
1006 0           v *= ((u-p3)*xlr);
1007 0           S70:
1008             /*
1009             *****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST
1010             */
1011 0           k = ABS(ix-m);
1012 0 0         if(k > 20 && k < xnpq/2-1) goto S130;
    0          
1013             /*
1014             EXPLICIT EVALUATION
1015             */
1016 0           f = 1.0;
1017 0           r = p/q;
1018 0           g = (n+1)*r;
1019 0           T1 = m-ix;
1020 0 0         if(T1 < 0) goto S80;
1021 0 0         else if(T1 == 0) goto S120;
1022 0           else goto S100;
1023 0           S80:
1024 0           mp = m+1;
1025 0 0         for(i=mp; i<=ix; i++) f *= (g/i-r);
1026 0           goto S120;
1027 0           S100:
1028 0           ix1 = ix+1;
1029 0 0         for(i=ix1; i<=m; i++) f /= (g/i-r);
1030 0           S120:
1031 0 0         if(v <= f) goto S170;
1032 0           goto S30;
1033 0           S130:
1034             /*
1035             SQUEEZING USING UPPER AND LOWER BOUNDS ON ALOG(F(X))
1036             */
1037 0           amaxp = k/xnpq*((k*(k/3.0+0.625)+0.1666666666666)/xnpq+0.5);
1038 0           ynorm = -(k*k/(2.0*xnpq));
1039 0           alv = log(v);
1040 0 0         if(alv < ynorm-amaxp) goto S170;
1041 0 0         if(alv > ynorm+amaxp) goto S30;
1042             /*
1043             STIRLING'S FORMULA TO MACHINE ACCURACY FOR
1044             THE FINAL ACCEPTANCE/REJECTION TEST
1045             */
1046 0           x1 = ix+1.0;
1047 0           f1 = fm+1.0;
1048 0           z = n+1.0-fm;
1049 0           w = n-ix+1.0;
1050 0           z2 = z*z;
1051 0           x2 = x1*x1;
1052 0           f2 = f1*f1;
1053 0           w2 = w*w;
1054 0           if(alv <= xm*log(f1/x1)+(n-m+0.5)*log(z/w)+(ix-m)*log(w*p/(x1*q))+(13860.0-
1055 0           (462.0-(132.0-(99.0-140.0/f2)/f2)/f2)/f2)/f1/166320.0+(13860.0-(462.0-
1056 0           (132.0-(99.0-140.0/z2)/z2)/z2)/z2)/z/166320.0+(13860.0-(462.0-(132.0-
1057 0           (99.0-140.0/x2)/x2)/x2)/x2)/x1/166320.0+(13860.0-(462.0-(132.0-(99.0
1058 0 0         -140.0/w2)/w2)/w2)/w2)/w/166320.0) goto S170;
1059 0           goto S30;
1060 6           S140:
1061             /*
1062             INVERSE CDF LOGIC FOR MEAN LESS THAN 30
1063             */
1064             /* The following change was recommended by Paul B. to get around an
1065             error when using gcc under AIX. 2006-09-12. */
1066             /** qn = pow(q,(double)n); <- OLD **/
1067 6           qn = exp( (double)n * log(q) );
1068 6           r = p/q;
1069 6           g = r*(n+1);
1070 10           S150:
1071 10           ix = 0;
1072 10           f = qn;
1073 10           u = ranf();
1074 86           S160:
1075 86 100         if(u < f) goto S170;
1076 76 50         if(ix > 110) goto S150;
1077 76           u -= f;
1078 76           ix += 1;
1079 76           f *= (g/ix-r);
1080 76           goto S160;
1081 10           S170:
1082 10 100         if(psave > 0.5) ix = n-ix;
1083 10           ignbin = ix;
1084 10           return ignbin;
1085             }
1086              
1087 6           long ignnbn(long n,double p)
1088             /*
1089             **********************************************************************
1090            
1091             long ignnbn(long n,double p)
1092             GENerate Negative BiNomial random deviate
1093             Function
1094             Generates a single random deviate from a negative binomial
1095             distribution.
1096             Arguments
1097             N --> The number of trials in the negative binomial distribution
1098             from which a random deviate is to be generated.
1099             JJV (N > 0)
1100             P --> The probability of an event.
1101             JJV (0.0 < P < 1.0)
1102             Method
1103             Algorithm from page 480 of
1104            
1105             Devroye, Luc
1106            
1107             Non-Uniform Random Variate Generation. Springer-Verlag,
1108             New York, 1986.
1109             **********************************************************************
1110             */
1111             {
1112             static long ignnbn;
1113             static double y,a,r;
1114             /*
1115             ..
1116             .. Executable Statements ..
1117             */
1118             /*
1119             Check Arguments
1120             */
1121 6 50         if(n <= 0L) ftnstop("N <= 0 in IGNNBN");
1122 6 50         if(p <= 0.0F) ftnstop("P <= 0.0 in IGNNBN");
1123 6 50         if(p >= 1.0F) ftnstop("P >= 1.0 in IGNNBN");
1124             /*
1125             Generate Y, a random gamma (n,(1-p)/p) variable
1126             JJV Note: the above parametrization is consistent with Devroye,
1127             JJV but gamma (p/(1-p),n) is the equivalent in our code
1128             */
1129 6           r = (double)n;
1130 6           a = p/(1.0F-p);
1131             /*
1132             * JJV changed this to call SGAMMA directly
1133             * y = gengam(a,r); <- OLD
1134             */
1135 6           y = sgamma(r)/a;
1136             /*
1137             Generate a random Poisson(y) variable
1138             */
1139 6           ignnbn = ignpoi(y);
1140 6           return ignnbn;
1141             }
1142              
1143 12           long ignpoi(double mu)
1144             /*
1145             **********************************************************************
1146             long ignpoi(double mu)
1147             GENerate POIsson random deviate
1148             Function
1149             Generates a single random deviate from a Poisson
1150             distribution with mean MU.
1151             Arguments
1152             mu --> The mean of the Poisson distribution from which
1153             a random deviate is to be generated.
1154             (mu >= 0.0)
1155             ignpoi <-- The random deviate.
1156             Method
1157             Renames KPOIS from TOMS as slightly modified by BWB to use RANF
1158             instead of SUNIF.
1159             For details see:
1160             Ahrens, J.H. and Dieter, U.
1161             Computer Generation of Poisson Deviates
1162             From Modified Normal Distributions.
1163             ACM Trans. Math. Software, 8, 2
1164             (June 1982),163-179
1165             **********************************************************************
1166             **********************************************************************
1167            
1168            
1169             P O I S S O N DISTRIBUTION
1170            
1171            
1172             **********************************************************************
1173             **********************************************************************
1174            
1175             FOR DETAILS SEE:
1176            
1177             AHRENS, J.H. AND DIETER, U.
1178             COMPUTER GENERATION OF POISSON DEVIATES
1179             FROM MODIFIED NORMAL DISTRIBUTIONS.
1180             ACM TRANS. MATH. SOFTWARE, 8,2 (JUNE 1982), 163 - 179.
1181            
1182             (SLIGHTLY MODIFIED VERSION OF THE PROGRAM IN THE ABOVE ARTICLE)
1183            
1184             **********************************************************************
1185             INTEGER FUNCTION IGNPOI(IR,MU)
1186             INPUT: IR=CURRENT STATE OF BASIC RANDOM NUMBER GENERATOR
1187             MU=MEAN MU OF THE POISSON DISTRIBUTION
1188             OUTPUT: IGNPOI=SAMPLE FROM THE POISSON-(MU)-DISTRIBUTION
1189             MUPREV=PREVIOUS MU, MUOLD=MU AT LAST EXECUTION OF STEP P OR B.
1190             TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT
1191             COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL
1192             SEPARATION OF CASES A AND B
1193             */
1194             {
1195             extern double fsign( double num, double sign );
1196             static double a0 = -0.5;
1197             static double a1 = 0.3333333343;
1198             static double a2 = -0.2499998565;
1199             static double a3 = 0.1999997049;
1200             static double a4 = -0.1666848753;
1201             static double a5 = 0.1428833286;
1202             static double a6 = -0.1241963125;
1203             static double a7 = 0.1101687109;
1204             static double a8 = -0.1142650302;
1205             static double a9 = 0.1055093006;
1206             /* JJV changed the initial values of MUPREV and MUOLD */
1207             static double muold = -1.0E37;
1208             static double muprev = -1.0E37;
1209             static double fact[10] = {
1210             1.0,1.0,2.0,6.0,24.0,120.0,720.0,5040.0,40320.0,362880.0
1211             };
1212             /* JJV added ll to the list, for Case A */
1213             static long ignpoi,j,k,kflag,l,ll,m;
1214             static double b1,b2,c,c0,c1,c2,c3,d,del,difmuk,e,fk,fx,fy,g,omega,p,p0,px,py,q,s,
1215             t,u,v,x,xx,pp[35];
1216              
1217 12 100         if(mu == muprev) goto S10;
1218 8 100         if(mu < 10.0) goto S120;
1219             /*
1220             C A S E A. (RECALCULATION OF S,D,LL IF MU HAS CHANGED)
1221             JJV changed l in Case A to ll
1222             */
1223 2           muprev = mu;
1224 2           s = sqrt(mu);
1225 2           d = 6.0*mu*mu;
1226             /*
1227             THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL
1228             PROBABILITIES FK WHENEVER K >= M(MU). LL=IFIX(MU-1.1484)
1229             IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 .
1230             */
1231 2           ll = (long) (mu-1.1484);
1232 6           S10:
1233             /*
1234             STEP N. NORMAL SAMPLE - SNORM(IR) FOR STANDARD NORMAL DEVIATE
1235             */
1236 6           g = mu+s*snorm();
1237 6 50         if(g < 0.0) goto S20;
1238 6           ignpoi = (long) (g);
1239             /*
1240             STEP I. IMMEDIATE ACCEPTANCE IF IGNPOI IS LARGE ENOUGH
1241             */
1242 6 100         if(ignpoi >= ll) return ignpoi;
1243             /*
1244             STEP S. SQUEEZE ACCEPTANCE - SUNIF(IR) FOR (0,1)-SAMPLE U
1245             */
1246 4           fk = (double)ignpoi;
1247 4           difmuk = mu-fk;
1248 4           u = ranf();
1249 4 50         if(d*u >= difmuk*difmuk*difmuk) return ignpoi;
1250 0           S20:
1251             /*
1252             STEP P. PREPARATIONS FOR STEPS Q AND H.
1253             (RECALCULATIONS OF PARAMETERS IF NECESSARY)
1254             .3989423=(2*PI)**(-.5) .416667E-1=1./24. .1428571=1./7.
1255             THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE
1256             APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK.
1257             C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION.
1258             */
1259 0 0         if(mu == muold) goto S30;
1260 0           muold = mu;
1261 0           omega = 0.398942280401433/s;
1262 0           b1 = 4.16666666666667E-2/mu;
1263 0           b2 = 0.3*b1*b1;
1264 0           c3 = 0.142857142857143*b1*b2;
1265 0           c2 = b2-15.0*c3;
1266 0           c1 = b1-6.0*b2+45.0*c3;
1267 0           c0 = 1.0-b1+3.0*b2-15.0*c3;
1268 0           c = 0.1069/mu;
1269 0           S30:
1270 0 0         if(g < 0.0) goto S50;
1271             /*
1272             'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN)
1273             */
1274 0           kflag = 0;
1275 0           goto S70;
1276 0           S40:
1277             /*
1278             STEP Q. QUOTIENT ACCEPTANCE (RARE CASE)
1279             */
1280 0 0         if(fy-u*fy <= py*exp(px-fx)) return ignpoi;
1281 0           S50:
1282             /*
1283             STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL
1284             DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'
1285             (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)
1286             */
1287 0           e = sexpo();
1288 0           u = ranf();
1289 0           u += (u-1.0);
1290 0           t = 1.8+fsign(e,u);
1291 0 0         if(t <= -0.6744) goto S50;
1292 0           ignpoi = (long) (mu+s*t);
1293 0           fk = (double)ignpoi;
1294 0           difmuk = mu-fk;
1295             /*
1296             'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)
1297             */
1298 0           kflag = 1;
1299 0           goto S70;
1300 0           S60:
1301             /*
1302             STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)
1303             */
1304 0 0         if(c*fabs(u) > py*exp(px+e)-fy*exp(fx+e)) goto S50;
1305 0           return ignpoi;
1306 0           S70:
1307             /*
1308             STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY.
1309             CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT
1310             */
1311 0 0         if(ignpoi >= 10) goto S80;
1312 0           px = -mu;
1313 0           py = pow(mu,(double)ignpoi)/ *(fact+ignpoi);
1314 0           goto S110;
1315 0           S80:
1316             /*
1317             CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION
1318             A0-A7 FOR ACCURACY WHEN ADVISABLE
1319             .8333333E-1=1./12. .3989423=(2*PI)**(-.5)
1320             */
1321 0           del = 8.33333333E-2/fk;
1322 0           del -= (4.8*del*del*del);
1323 0           v = difmuk/fk;
1324 0 0         if(fabs(v) <= 0.25) goto S90;
1325 0           px = fk*log(1.0+v)-difmuk-del;
1326 0           goto S100;
1327 0           S90:
1328 0           px = fk*v*v*((((((((a8*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0)-del;
1329 0           S100:
1330 0           py = 0.398942280401433/sqrt(fk);
1331 0           S110:
1332 0           x = (0.5-difmuk)/s;
1333 0           xx = x*x;
1334 0           fx = -0.5*xx;
1335 0           fy = omega*(((c3*xx+c2)*xx+c1)*xx+c0);
1336 0 0         if(kflag <= 0) goto S40;
1337 0           goto S60;
1338 6           S120:
1339             /*
1340             C A S E B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY)
1341             JJV changed MUPREV assignment to initial value
1342             */
1343 6           muprev = -1.0E37;
1344 6 50         if(mu == muold) goto S130;
1345             /* JJV added argument checker here */
1346 6 50         if(mu >= 0.0) goto S125;
1347 0           fprintf(stderr,"MU < 0 in IGNPOI: MU %16.6E\n",mu);
1348 0           fputs("Abort\n",stderr);
1349 0           exit(1);
1350 6           S125:
1351 6           muold = mu;
1352 6           m = max(1L,(long) (mu));
1353 6           l = 0;
1354 6           p = exp(-mu);
1355 6           q = p0 = p;
1356 0           S130:
1357             /*
1358             STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
1359             */
1360 6           u = ranf();
1361 6           ignpoi = 0;
1362 6 100         if(u <= p0) return ignpoi;
1363             /*
1364             STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE
1365             PP-TABLE OF CUMULATIVE POISSON PROBABILITIES
1366             (0.458=PP(9) FOR MU=10)
1367             */
1368 4 50         if(l == 0) goto S150;
1369 0           j = 1;
1370 0 0         if(u > 0.458) j = min(l,m);
1371 0 0         for(k=j; k<=l; k++) {
1372 0 0         if(u <= *(pp+k-1)) goto S180;
1373             }
1374 0 0         if(l == 35) goto S130;
1375 0           S150:
1376             /*
1377             STEP C. CREATION OF NEW POISSON PROBABILITIES P
1378             AND THEIR CUMULATIVES Q=PP(K)
1379             */
1380 4           l += 1;
1381 14 50         for(k=l; k<=35; k++) {
1382 14           p = p*mu/(double)k;
1383 14           q += p;
1384 14           *(pp+k-1) = q;
1385 14 100         if(u <= q) goto S170;
1386             }
1387 0           l = 35;
1388 0           goto S130;
1389 4           S170:
1390 4           l = k;
1391 4           S180:
1392 4           ignpoi = k;
1393 4           return ignpoi;
1394             }
1395              
1396 40           long ignuin(long low,long high)
1397             /*
1398             **********************************************************************
1399             long ignuin(long low,long high)
1400             GeNerate Uniform INteger
1401             Function
1402             Generates an integer uniformly distributed between LOW and HIGH.
1403             Arguments
1404             low --> Low bound (inclusive) on integer value to be generated
1405             high --> High bound (inclusive) on integer value to be generated
1406             Note
1407             If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and
1408             stops the program.
1409             **********************************************************************
1410             IGNLGI generates integers between 1 and 2147483562
1411             MAXNUM is 1 less than maximum generable value
1412             */
1413             {
1414             #define maxnum 2147483561L
1415             static long ignuin,ign,maxnow,range,ranp1;
1416              
1417 40 50         if(!(low > high)) goto S10;
1418 0           fputs(" low > high in ignuin - ABORT\n",stderr);
1419 0           exit(1);
1420              
1421 40           S10:
1422 40           range = high-low;
1423 40 50         if(!(range > maxnum)) goto S20;
1424 0           fputs(" high - low too large in ignuin - ABORT\n",stderr);
1425 0           exit(1);
1426              
1427 40           S20:
1428 40 100         if(!(low == high)) goto S30;
1429 4           ignuin = low;
1430 4           return ignuin;
1431              
1432 36           S30:
1433             /*
1434             Number to be generated should be in range 0..RANGE
1435             Set MAXNOW so that the number of integers in 0..MAXNOW is an
1436             integral multiple of the number in 0..RANGE
1437             */
1438 36           ranp1 = range+1;
1439 36           maxnow = maxnum/ranp1*ranp1;
1440 36           S40:
1441 36           ign = ignlgi()-1;
1442 36 50         if(!(ign <= maxnow)) goto S40;
1443 36           ignuin = low+ign%ranp1;
1444 36           return ignuin;
1445             #undef maxnum
1446             #undef err1
1447             #undef err2
1448             }
1449              
1450 16           long lennob( char *str )
1451             /*
1452             Returns the length of str ignoring trailing blanks but not
1453             other white space.
1454             */
1455             {
1456             long i, i_nb;
1457              
1458 221 100         for (i=0, i_nb= -1L; *(str+i); i++)
1459 205 100         if ( *(str+i) != ' ' ) i_nb = i;
1460 16           return (i_nb+1);
1461             }
1462              
1463 1062           long mltmod(long a,long s,long m)
1464             /*
1465             **********************************************************************
1466             long mltmod(long a,long s,long m)
1467             Returns (A*S) MOD M
1468             This is a transcription from Pascal to C of routine
1469             MultMod_Decompos from the paper
1470             L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
1471             with Splitting Facilities." ACM Transactions on Mathematical
1472             Software, 17:98-111 (1991)
1473             Arguments
1474             a, s, m -->
1475             WGR, 12/19/00: replaced S10, S20, etc. with C blocks {} per
1476             original paper.
1477             **********************************************************************
1478             */
1479             {
1480             #define h 32768L
1481             static long a0,a1,k,p,q,qh,rh;
1482             /*
1483             H = 2**((b-2)/2) where b = 32 because we are using a 32 bit
1484             machine. On a different machine recompute H.
1485             */
1486 1062 50         if (a <= 0 || a >= m || s <= 0 || s >= m) {
    50          
    50          
    50          
1487 0           fputs(" a, m, s out of order in mltmod - ABORT!\n",stderr);
1488 0           fprintf(stderr," a = %12ld s = %12ld m = %12ld\n",a,s,m);
1489 0           fputs(" mltmod requires: 0 < a < m; 0 < s < m\n",stderr);
1490 0           exit(1);
1491             }
1492              
1493 1062 50         if (a < h) {
1494 0           a0 = a;
1495 0           p = 0;
1496             } else {
1497 1062           a1 = a/h;
1498 1062           a0 = a - h*a1;
1499 1062           qh = m/h;
1500 1062           rh = m - h*qh;
1501 1062 100         if (a1 >= h) { /* A2=1 */
1502 529           a1 -= h;
1503 529           k = s/qh;
1504 529           p = h*(s-k*qh) - k*rh;
1505 656 100         while (p < 0) { p += m; }
1506             } else {
1507 533           p = 0;
1508             }
1509             /*
1510             P = (A2*S*H)MOD M
1511             */
1512 1062 50         if (a1 != 0) {
1513 1062           q = m/a1;
1514 1062           k = s/q;
1515 1062           p -= k*(m - a1*q);
1516 1062 100         if (p > 0) { p -= m; }
1517 1062           p += a1*(s - k*q);
1518 1338 100         while (p < 0) { p += m; }
1519             }
1520             /*
1521             P = ((A2*H + A1)*S)MOD M
1522             */
1523 1062           k = p/qh;
1524 1062           p = h*(p-k*qh) - k*rh;
1525 1341 100         while (p < 0) { p += m; }
1526             }
1527             /*
1528             P = ((A2*H + A1)*H*S)MOD M
1529             */
1530 1062 50         if (a0 != 0) {
1531 1062           q = m/a0;
1532 1062           k = s/q;
1533 1062           p -= k*(m-a0*q);
1534 1062 100         if (p > 0) { p -= m; }
1535 1062           p += a0*(s-k*q);
1536 1641 100         while (p < 0) { p += m; }
1537             }
1538 1062           return p;
1539             #undef h
1540             }
1541              
1542 16           void phrtsd(char* phrase,long *seed1,long *seed2)
1543             /*
1544             **********************************************************************
1545             void phrtsd(char* phrase,long *seed1,long *seed2)
1546             PHRase To SeeDs
1547              
1548             Function
1549              
1550             Uses a phrase (character string) to generate two seeds for the RGN
1551             random number generator.
1552             Arguments
1553             phrase --> Phrase to be used for random number generation
1554            
1555             seed1 <-- First seed for generator
1556            
1557             seed2 <-- Second seed for generator
1558            
1559             Note
1560              
1561             Trailing blanks are eliminated before the seeds are generated.
1562             Generated seed values will fall in the range 1..2^30
1563             (1..1,073,741,824)
1564             **********************************************************************
1565             */
1566             {
1567              
1568             static char table[] =
1569             "abcdefghijklmnopqrstuvwxyz\
1570             ABCDEFGHIJKLMNOPQRSTUVWXYZ\
1571             0123456789\
1572             !@#$%^&*()_+[];:'\\\"<>?,./ "; /* WGR added space, 5/19/1999 */
1573              
1574             long ix;
1575              
1576             static long twop30 = 1073741824L;
1577             static long shift[5] = {
1578             1L,64L,4096L,262144L,16777216L
1579             };
1580              
1581             #ifdef PHRTSD_ORIG
1582             /*----------------------------- Original phrtsd */
1583             static long i,ichr,j,lphr,values[5];
1584             extern long lennob(char *str);
1585              
1586             *seed1 = 1234567890L;
1587             *seed2 = 123456789L;
1588             lphr = lennob(phrase);
1589             if(lphr < 1) return;
1590             for(i=0; i<=(lphr-1); i++) {
1591             for (ix=0; table[ix]; ix++) if (*(phrase+i) == table[ix]) break;
1592             /* JJV added ix++; to bring index in line with fortran's index*/
1593             ix++;
1594             if (!table[ix]) ix = 0;
1595             ichr = ix % 64;
1596             if(ichr == 0) ichr = 63;
1597             for(j=1; j<=5; j++) {
1598             *(values+j-1) = ichr-j;
1599             if(*(values+j-1) < 1) *(values+j-1) += 63;
1600             }
1601             for(j=1; j<=5; j++) {
1602             *seed1 = ( *seed1+*(shift+j-1)**(values+j-1) ) % twop30;
1603             *seed2 = ( *seed2+*(shift+j-1)**(values+6-j-1) ) % twop30;
1604             }
1605             }
1606             #else
1607             /*----------------------------- New phrtsd */
1608             static long i,j, ichr,lphr;
1609             static long values[8] = { 8521739, 5266711, 3254959, 2011673,
1610             1243273, 768389, 474899, 293507 };
1611             extern long lennob(char *str);
1612              
1613 16           *seed1 = 1234567890L;
1614 16           *seed2 = 123456789L;
1615 16           lphr = lennob(phrase);
1616 16 50         if(lphr < 1) return;
1617 205 100         for(i=0; i<(lphr-1); i++) {
1618 189           ichr = phrase[i];
1619 189           j = i % 8;
1620 189           *seed1 = ( *seed1 + (values[j] * ichr) ) % twop30;
1621 189           *seed2 = ( *seed2 + (values[7-j] * ichr) ) % twop30;
1622             }
1623             #endif
1624             }
1625              
1626 224           double ranf(void)
1627             /*
1628             **********************************************************************
1629             double ranf(void)
1630             RANDom number generator as a Function
1631             Returns a random floating point number from a uniform distribution
1632             over 0 - 1 (endpoints of this interval are not returned) using the
1633             current generator.
1634             This is a transcription from Pascal to C of routine
1635             Uniform_01 from the paper
1636             L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
1637             with Splitting Facilities." ACM Transactions on Mathematical
1638             Software, 17:98-111 (1991)
1639             WGR, 2/12/01: increased precision.
1640             **********************************************************************
1641             */
1642             {
1643             static double ranf;
1644             /*
1645             4.656613057E-10 is 1/M1 M1 is set in a data statement in IGNLGI
1646             and is currently 2147483563. If M1 changes, change this also.
1647             */
1648 224           ranf = ignlgi()*4.65661305739177E-10;
1649 224           return ranf;
1650             }
1651              
1652 3           void setgmn(double *meanv,double *covm,long p,double *parm)
1653             /*
1654             **********************************************************************
1655             void setgmn(double *meanv,double *covm,long p,double *parm)
1656             SET Generate Multivariate Normal random deviate
1657             Function
1658             Places P, MEANV, and the Cholesky factorization of COVM
1659             in GENMN.
1660             Arguments
1661             meanv --> Mean vector of multivariate normal distribution.
1662             covm <--> (Input) Covariance matrix of the multivariate
1663             normal distribution
1664             (Output) Destroyed on output
1665             p --> Dimension of the normal, or length of MEANV.
1666             parm <-- Array of parameters needed to generate multivariate norma
1667             deviates (P, MEANV and Cholesky decomposition of
1668             COVM).
1669             1 : 1 - P
1670             2 : P + 1 - MEANV
1671             P+2 : P*(P+3)/2 + 1 - Cholesky decomposition of COVM
1672             Needed dimension is (p*(p+3)/2 + 1)
1673             **********************************************************************
1674             */
1675             {
1676             extern void spofa(double *a,long lda,long n,long *info);
1677             static long T1;
1678             static long i,icount,info,j,D2,D3,D4,D5;
1679 3           T1 = p*(p+3)/2+1;
1680             /*
1681             TEST THE INPUT
1682             */
1683 3 50         if(!(p <= 0)) goto S10;
1684 0           fputs("P nonpositive in SETGMN\n",stderr);
1685 0           fprintf(stderr,"Value of P: %12ld\n",p);
1686 0           exit(1);
1687 3           S10:
1688 3           *parm = p;
1689             /*
1690             PUT P AND MEANV INTO PARM
1691             */
1692 9 100         for(i=2,D2=1,D3=(p+1-i+D2)/D2; D3>0; D3--,i+=D2) *(parm+i-1) = *(meanv+i-2);
1693             /*
1694             Cholesky decomposition to find A s.t. trans(A)*(A) = COVM
1695             */
1696 3           spofa(covm,p,p,&info);
1697 3 50         if(!(info != 0)) goto S30;
1698 0           fputs(" COVM not positive definite in SETGMN\n",stderr);
1699 0           exit(1);
1700 3           S30:
1701 3           icount = p+1;
1702             /*
1703             PUT UPPER HALF OF A, WHICH IS NOW THE CHOLESKY FACTOR, INTO PARM
1704             COVM(1,1) = PARM(P+2)
1705             COVM(1,2) = PARM(P+3)
1706             :
1707             COVM(1,P) = PARM(2P+1)
1708             COVM(2,2) = PARM(2P+2) ...
1709             */
1710 9 100         for(i=1,D4=1,D5=(p-i+D4)/D4; D5>0; D5--,i+=D4) {
1711 15 100         for(j=i-1; j
1712 9           icount += 1;
1713 9           *(parm+icount-1) = *(covm+i-1+j*p);
1714             }
1715             }
1716 3           }
1717              
1718 24           double sexpo(void)
1719             /*
1720             **********************************************************************
1721            
1722            
1723             (STANDARD-) E X P O N E N T I A L DISTRIBUTION
1724            
1725            
1726             **********************************************************************
1727             **********************************************************************
1728            
1729             FOR DETAILS SEE:
1730            
1731             AHRENS, J.H. AND DIETER, U.
1732             COMPUTER METHODS FOR SAMPLING FROM THE
1733             EXPONENTIAL AND NORMAL DISTRIBUTIONS.
1734             COMM. ACM, 15,10 (OCT. 1972), 873 - 882.
1735            
1736             ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM
1737             'SA' IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION)
1738            
1739             Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
1740             SUNIF. The argument IR thus goes away.
1741            
1742             **********************************************************************
1743             Q(N) = SUM(ALOG(2.0)**K/K!) K=1,..,N , THE HIGHEST N
1744             (HERE 8) IS DETERMINED BY Q(N)=1.0 WITHIN STANDARD PRECISION
1745             */
1746             {
1747             static double q[8] = {
1748             0.69314718055995, 0.93337368751905, 0.98887779618387, 0.99849592529150,
1749             0.99982928110614, 0.99998331641007, 0.99999856914388, 0.99999989069256
1750             };
1751             static long i;
1752             static double sexpo,a,u,ustar,umin;
1753             static double *q1 = q;
1754 24           a = 0.0;
1755 24           u = ranf();
1756 24           goto S30;
1757 6           S20:
1758 6           a += *q1;
1759 30           S30:
1760 30           u += u;
1761             /*
1762             * JJV changed the following to reflect the true algorithm and prevent
1763             * JJV unpredictable behavior if U is initially 0.5.
1764             * if(u <= 1.0) goto S20;
1765             */
1766 30 100         if(u < 1.0) goto S20;
1767 24           u -= 1.0;
1768 24 100         if(u > *q1) goto S60;
1769 18           sexpo = a+u;
1770 18           return sexpo;
1771 6           S60:
1772 6           i = 1;
1773 6           ustar = ranf();
1774 6           umin = ustar;
1775 6           S70:
1776 6           ustar = ranf();
1777 6 100         if(ustar < umin) umin = ustar;
1778 6           i += 1;
1779 6 50         if(u > *(q+i-1)) goto S70;
1780 6           sexpo = a+umin**q1;
1781 6           return sexpo;
1782             }
1783              
1784 48           double sgamma(double a)
1785             /*
1786             **********************************************************************
1787            
1788            
1789             (STANDARD-) G A M M A DISTRIBUTION
1790            
1791            
1792             **********************************************************************
1793             **********************************************************************
1794            
1795             PARAMETER A >= 1.0 !
1796            
1797             **********************************************************************
1798            
1799             FOR DETAILS SEE:
1800            
1801             AHRENS, J.H. AND DIETER, U.
1802             GENERATING GAMMA VARIATES BY A
1803             MODIFIED REJECTION TECHNIQUE.
1804             COMM. ACM, 25,1 (JAN. 1982), 47 - 54.
1805            
1806             STEP NUMBERS CORRESPOND TO ALGORITHM 'GD' IN THE ABOVE PAPER
1807             (STRAIGHTFORWARD IMPLEMENTATION)
1808            
1809             Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
1810             SUNIF. The argument IR thus goes away.
1811            
1812             **********************************************************************
1813            
1814             PARAMETER 0.0 < A < 1.0 !
1815            
1816             **********************************************************************
1817            
1818             FOR DETAILS SEE:
1819            
1820             AHRENS, J.H. AND DIETER, U.
1821             COMPUTER METHODS FOR SAMPLING FROM GAMMA,
1822             BETA, POISSON AND BINOMIAL DISTRIBUTIONS.
1823             COMPUTING, 12 (1974), 223 - 246.
1824            
1825             (ADAPTED IMPLEMENTATION OF ALGORITHM 'GS' IN THE ABOVE PAPER)
1826            
1827             **********************************************************************
1828             INPUT: A =PARAMETER (MEAN) OF THE STANDARD GAMMA DISTRIBUTION
1829             OUTPUT: SGAMMA = SAMPLE FROM THE GAMMA-(A)-DISTRIBUTION
1830             COEFFICIENTS Q(K) - FOR Q0 = SUM(Q(K)*A**(-K))
1831             COEFFICIENTS A(K) - FOR Q = Q0+(T*T/2)*SUM(A(K)*V**K)
1832             COEFFICIENTS E(K) - FOR EXP(Q)-1 = SUM(E(K)*Q**K)
1833             PREVIOUS A PRE-SET TO ZERO - AA IS A', AAA IS A"
1834             SQRT32 IS THE SQUAREROOT OF 32 = 5.656854249492380
1835             */
1836             {
1837             extern double fsign( double num, double sign );
1838             static double q1 = 4.16666664E-2;
1839             static double q2 = 2.08333723E-2;
1840             static double q3 = 7.9849875E-3;
1841             static double q4 = 1.5746717E-3;
1842             static double q5 = -3.349403E-4;
1843             static double q6 = 3.340332E-4;
1844             static double q7 = 6.053049E-4;
1845             static double q8 = -4.701849E-4;
1846             static double q9 = 1.710320E-4;
1847             static double a1 = 0.333333333;
1848             static double a2 = -0.249999949;
1849             static double a3 = 0.199999867;
1850             static double a4 = -0.166677482;
1851             static double a5 = 0.142873973;
1852             static double a6 = -0.124385581;
1853             static double a7 = 0.110368310;
1854             static double a8 = -0.112750886;
1855             static double a9 = 0.104089866;
1856             static double e1 = 1.0;
1857             static double e2 = 0.499999994;
1858             static double e3 = 0.166666848;
1859             static double e4 = 4.1664508E-2;
1860             static double e5 = 8.345522E-3;
1861             static double e6 = 1.353826E-3;
1862             static double e7 = 2.47453E-4;
1863             static double aa = 0.0;
1864             static double aaa = 0.0;
1865             static double sqrt32 = 5.65685424949238;
1866             /* JJV added b0 to fix rare and subtle bug */
1867             static double sgamma,s2,s,d,t,x,u,r,q0,b,b0,si,c,v,q,e,w,p;
1868 48 100         if(a == aa) goto S10;
1869 30 50         if(a < 1.0) goto S120;
1870             /*
1871             STEP 1: RECALCULATIONS OF S2,S,D IF A HAS CHANGED
1872             */
1873 30           aa = a;
1874 30           s2 = a-0.5;
1875 30           s = sqrt(s2);
1876 30           d = sqrt32-12.0*s;
1877 48           S10:
1878             /*
1879             STEP 2: T=STANDARD NORMAL DEVIATE,
1880             X=(S,1/2)-NORMAL DEVIATE.
1881             IMMEDIATE ACCEPTANCE (I)
1882             */
1883 48           t = snorm();
1884 48           x = s+0.5*t;
1885 48           sgamma = x*x;
1886 48 100         if(t >= 0.0) return sgamma;
1887             /*
1888             STEP 3: U= 0,1 -UNIFORM SAMPLE. SQUEEZE ACCEPTANCE (S)
1889             */
1890 28           u = ranf();
1891 28 100         if(d*u <= t*t*t) return sgamma;
1892             /*
1893             STEP 4: RECALCULATIONS OF Q0,B,SI,C IF NECESSARY
1894             */
1895 6 100         if(a == aaa) goto S40;
1896 4           aaa = a;
1897 4           r = 1.0/a;
1898 4           q0 = ((((((((q9*r+q8)*r+q7)*r+q6)*r+q5)*r+q4)*r+q3)*r+q2)*r+q1)*r;
1899             /*
1900             APPROXIMATION DEPENDING ON SIZE OF PARAMETER A
1901             THE CONSTANTS IN THE EXPRESSIONS FOR B, SI AND
1902             C WERE ESTABLISHED BY NUMERICAL EXPERIMENTS
1903             */
1904 4 50         if(a <= 3.686) goto S30;
1905 0 0         if(a <= 13.022) goto S20;
1906             /*
1907             CASE 3: A .GT. 13.022
1908             */
1909 0           b = 1.77;
1910 0           si = 0.75;
1911 0           c = 0.1515/s;
1912 0           goto S40;
1913 0           S20:
1914             /*
1915             CASE 2: 3.686 .LT. A .LE. 13.022
1916             */
1917 0           b = 1.654+7.6E-3*s2;
1918 0           si = 1.68/s+0.275;
1919 0           c = 6.2E-2/s+2.4E-2;
1920 0           goto S40;
1921 4           S30:
1922             /*
1923             CASE 1: A .LE. 3.686
1924             */
1925 4           b = 0.463+s+0.178*s2;
1926 4           si = 1.235;
1927 4           c = 0.195/s-7.9E-2+1.6E-1*s;
1928 6           S40:
1929             /*
1930             STEP 5: NO QUOTIENT TEST IF X NOT POSITIVE
1931             */
1932 6 100         if(x <= 0.0) goto S70;
1933             /*
1934             STEP 6: CALCULATION OF V AND QUOTIENT Q
1935             */
1936 4           v = t/(s+s);
1937 4 50         if(fabs(v) <= 0.25) goto S50;
1938 4           q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v);
1939 4           goto S60;
1940 0           S50:
1941 0           q = q0+0.5*t*t*((((((((a9*v+a8)*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v;
1942 4           S60:
1943             /*
1944             STEP 7: QUOTIENT ACCEPTANCE (Q)
1945             */
1946 4 100         if(log(1.0-u) <= q) return sgamma;
1947 16           S70:
1948             /*
1949             STEP 8: E=STANDARD EXPONENTIAL DEVIATE
1950             U= 0,1 -UNIFORM DEVIATE
1951             T=(B,SI)-DOUBLE EXPONENTIAL (LAPLACE) SAMPLE
1952             */
1953 18           e = sexpo();
1954 18           u = ranf();
1955 18           u += (u-1.0);
1956 18           t = b+fsign(si*e,u);
1957             /*
1958             STEP 9: REJECTION IF T .LT. TAU(1) = -.71874483771719
1959             */
1960 18 50         if(t < -0.71874483771719) goto S70;
1961             /*
1962             STEP 10: CALCULATION OF V AND QUOTIENT Q
1963             */
1964 18           v = t/(s+s);
1965 18 100         if(fabs(v) <= 0.25) goto S80;
1966 16           q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v);
1967 16           goto S90;
1968 2           S80:
1969 2           q = q0+0.5*t*t*((((((((a9*v+a8)*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v;
1970 18           S90:
1971             /*
1972             STEP 11: HAT ACCEPTANCE (H) (IF Q NOT POSITIVE GO TO STEP 8)
1973             */
1974 18 50         if(q <= 0.0) goto S70;
1975 18 100         if(q <= 0.5) goto S100;
1976             /*
1977             * JJV modified the code through line 115 to handle large Q case
1978             */
1979 8 50         if(q < 15.0) goto S95;
1980             /*
1981             * JJV Here Q is large enough that Q = log(exp(Q) - 1.0) (for real Q)
1982             * JJV so reformulate test at 110 in terms of one EXP, if not too big
1983             * JJV 87.49823 is close to the largest real which can be
1984             * JJV exponentiated (87.49823 = log(1.0E38))
1985             */
1986 0 0         if((q+e-0.5*t*t) > 87.4982335337737) goto S115;
1987 0 0         if(c*fabs(u) > exp(q+e-0.5*t*t)) goto S70;
1988 0           goto S115;
1989 8           S95:
1990 8           w = exp(q)-1.0;
1991 8           goto S110;
1992 10           S100:
1993 10           w = ((((((e7*q+e6)*q+e5)*q+e4)*q+e3)*q+e2)*q+e1)*q;
1994 18           S110:
1995             /*
1996             IF T IS REJECTED, SAMPLE AGAIN AT STEP 8
1997             */
1998 18 100         if(c*fabs(u) > w*exp(e-0.5*t*t)) goto S70;
1999 4           S115:
2000 4           x = s+0.5*t;
2001 4           sgamma = x*x;
2002 4           return sgamma;
2003 0           S120:
2004             /*
2005             ALTERNATE METHOD FOR PARAMETERS A BELOW 1 (.3678794=EXP(-1.))
2006              
2007             JJV changed B to B0 (which was added to declarations for this)
2008             JJV in 120 to END to fix rare and subtle bug.
2009             JJV Line: 'aa = 0.0' was removed (unnecessary, wasteful).
2010             JJV Reasons: the state of AA only serves to tell the A >= 1.0
2011             JJV case if certain A-dependent constants need to be recalculated.
2012             JJV The A < 1.0 case (here) no longer changes any of these, and
2013             JJV the recalculation of B (which used to change with an
2014             JJV A < 1.0 call) is governed by the state of AAA anyway.
2015             aa = 0.0;
2016             */
2017 0           b0 = 1.0+ 0.3678794411714423*a;
2018 0           S130:
2019 0           p = b0*ranf();
2020 0 0         if(p >= 1.0) goto S140;
2021 0           sgamma = exp(log(p)/ a);
2022 0 0         if(sexpo() < sgamma) goto S130;
2023 0           return sgamma;
2024 0           S140:
2025 0           sgamma = -log((b0-p)/ a);
2026 0 0         if(sexpo() < (1.0-a)*log(sgamma)) goto S130;
2027 0           return sgamma;
2028             }
2029              
2030 80           double snorm(void)
2031             /*
2032             **********************************************************************
2033            
2034            
2035             (STANDARD-) N O R M A L DISTRIBUTION
2036            
2037            
2038             **********************************************************************
2039             **********************************************************************
2040            
2041             FOR DETAILS SEE:
2042            
2043             AHRENS, J.H. AND DIETER, U.
2044             EXTENSIONS OF FORSYTHE'S METHOD FOR RANDOM
2045             SAMPLING FROM THE NORMAL DISTRIBUTION.
2046             MATH. COMPUT., 27,124 (OCT. 1973), 927 - 937.
2047            
2048             ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM 'FL'
2049             (M=5) IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION)
2050            
2051             Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
2052             SUNIF. The argument IR thus goes away.
2053            
2054             **********************************************************************
2055             THE DEFINITIONS OF THE CONSTANTS A(K), D(K), T(K) AND
2056             H(K) ARE ACCORDING TO THE ABOVEMENTIONED ARTICLE
2057             */
2058             {
2059             static double a[32] = {
2060             0.0, 0.03917608550309, 0.07841241273311, 0.11776987457909,
2061             0.15731068461017, 0.19709908429430, 0.23720210932878, 0.27769043982157,
2062             0.31863936396437, 0.36012989178957, 0.40225006532172, 0.44509652498551,
2063             0.48877641111466, 0.53340970624127, 0.57913216225555, 0.62609901234641,
2064             0.67448975019607, 0.72451438349236, 0.77642176114792, 0.83051087820539,
2065             0.88714655901887, 0.94678175630104, 1.00999016924958, 1.07751556704027,
2066             1.15034938037600, 1.22985875921658, 1.31801089730353, 1.41779713799625,
2067             1.53412054435253, 1.67593972277344, 1.86273186742164, 2.15387469406144
2068             };
2069             static double d[31] = {
2070             0.0, 0.0, 0.0, 0.0,
2071             0.0, 0.26368432217502, 0.24250845238097, 0.22556744380930,
2072             0.21163416577204, 0.19992426749317, 0.18991075842246, 0.18122518100691,
2073             0.17360140038056, 0.16684190866667, 0.16079672918053, 0.15534971747692,
2074             0.15040938382813, 0.14590257684509, 0.14177003276856, 0.13796317369537,
2075             0.13444176150074, 0.13117215026483, 0.12812596512583, 0.12527909006226,
2076             0.12261088288608, 0.12010355965651, 0.11774170701949, 0.11551189226063,
2077             0.11340234879117, 0.11140272044119, 0.10950385201710
2078             };
2079             static double t[31] = {
2080             7.6738283767E-4, 2.30687039764E-3, 3.86061844387E-3, 5.43845406707E-3,
2081             7.05069876857E-3, 8.70839582019E-3, 1.042356984914E-2, 1.220953194966E-2,
2082             1.408124734637E-2, 1.605578804548E-2, 1.815290075142E-2, 2.039573175398E-2,
2083             2.281176732513E-2, 2.543407332319E-2, 2.830295595118E-2, 3.146822492920E-2,
2084             3.499233438388E-2, 3.895482964836E-2, 4.345878381672E-2, 4.864034918076E-2,
2085             5.468333844273E-2, 6.184222395816E-2, 7.047982761667E-2, 8.113194985866E-2,
2086             9.462443534514E-2, 0.11230007889456, 0.13649799954975, 0.17168856004707,
2087             0.22762405488269, 0.33049802776911, 0.58470309390507
2088             };
2089             static double h[31] = {
2090             3.920617164634E-2, 3.932704963665E-2, 3.950999486086E-2, 3.975702679515E-2,
2091             4.007092772490E-2, 4.045532602655E-2, 4.091480886081E-2, 4.145507115859E-2,
2092             4.208311051344E-2, 4.280748137995E-2, 4.363862733472E-2, 4.458931789605E-2,
2093             4.567522779560E-2, 4.691571371696E-2, 4.833486978119E-2, 4.996298427702E-2,
2094             5.183858644724E-2, 5.401138183398E-2, 5.654656186515E-2, 5.953130423884E-2,
2095             6.308488965373E-2, 6.737503494905E-2, 7.264543556657E-2, 7.926471414968E-2,
2096             8.781922325338E-2, 9.930398323927E-2, 0.11555994154118, 0.14043438342816,
2097             0.18361418337460, 0.27900163464163, 0.70104742502766
2098             };
2099             static long i;
2100             static double snorm,u,s,ustar,aa,w,y,tt;
2101 80           u = ranf();
2102 80           s = 0.0;
2103 80 100         if(u > 0.5) s = 1.0;
2104 80           u += (u-s);
2105 80           u = 32.0*u;
2106 80           i = (long) (u);
2107 80 50         if(i == 32) i = 31;
2108 80 100         if(i == 0) goto S100;
2109             /*
2110             START CENTER
2111             */
2112 78           ustar = u-(double)i;
2113 78           aa = *(a+i-1);
2114 82           S40:
2115 82 100         if(ustar <= *(t+i-1)) goto S60;
2116 76           w = (ustar-*(t+i-1))**(h+i-1);
2117 80           S50:
2118             /*
2119             EXIT (BOTH CASES)
2120             */
2121 80           y = aa+w;
2122 80           snorm = y;
2123 80 100         if(s == 1.0) snorm = -y;
2124 80           return snorm;
2125 6           S60:
2126             /*
2127             CENTER CONTINUED
2128             */
2129 6           u = ranf();
2130 6           w = u*(*(a+i)-aa);
2131 6           tt = (0.5*w+aa)*w;
2132 6           goto S80;
2133 0           S70:
2134 0           tt = u;
2135 0           ustar = ranf();
2136 6           S80:
2137 6 100         if(ustar > tt) goto S50;
2138 4           u = ranf();
2139 4 50         if(ustar >= u) goto S70;
2140 4           ustar = ranf();
2141 4           goto S40;
2142 2           S100:
2143             /*
2144             START TAIL
2145             */
2146 2           i = 6;
2147 2           aa = *(a+31);
2148 2           goto S120;
2149 10           S110:
2150 10           aa += *(d+i-1);
2151 10           i += 1;
2152 12           S120:
2153 12           u += u;
2154 12 100         if(u < 1.0) goto S110;
2155 2           u -= 1.0;
2156 2           S140:
2157 2           w = u**(d+i-1);
2158 2           tt = (0.5*w+aa)*w;
2159 2           goto S160;
2160 0           S150:
2161 0           tt = u;
2162 2           S160:
2163 2           ustar = ranf();
2164 2 50         if(ustar > tt) goto S50;
2165 0           u = ranf();
2166 0 0         if(ustar >= u) goto S150;
2167 0           u = ranf();
2168 0           goto S140;
2169             }
2170              
2171 18           double fsign( double num, double sign )
2172             /* Transfers sign of argument sign to argument num */
2173             {
2174 18 100         if ( ( sign>0.0f && num<0.0f ) || ( sign<0.0f && num>0.0f ) )
    50          
    100          
    50          
2175 8           return -num;
2176 10           else return num;
2177             }
2178              
2179             /************************************************************************
2180             FTNSTOP:
2181             Prints msg to standard error and then exits
2182             ************************************************************************/
2183 0           void ftnstop(char* msg)
2184             /* msg - error message */
2185             {
2186 0 0         if (msg != NULL) fprintf(stderr,"%s\n",msg);
2187 0           exit(0);
2188             }