Annotation of capa/capa51/pProj/ranlib.c, revision 1.1
1.1 ! albertel 1:
! 2: #include "ranlib.h"
! 3: #include <stdio.h>
! 4: #include <math.h>
! 5: #include <stdlib.h>
! 6: #define abs(x) ((x) >= 0 ? (x) : -(x))
! 7: #define min(a,b) ((a) <= (b) ? (a) : (b))
! 8: #define max(a,b) ((a) >= (b) ? (a) : (b))
! 9:
! 10: /*
! 11: **********************************************************************
! 12: float genbet(float aa,float bb)
! 13: GeNerate BETa random deviate
! 14: Function
! 15: Returns a single random deviate from the beta distribution with
! 16: parameters A and B. The density of the beta is
! 17: x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1
! 18: Arguments
! 19: aa --> First parameter of the beta distribution
! 20:
! 21: bb --> Second parameter of the beta distribution
! 22:
! 23: Method
! 24: R. C. H. Cheng
! 25: Generating Beta Variatew with Nonintegral Shape Parameters
! 26: Communications of the ACM, 21:317-322 (1978)
! 27: (Algorithms BB and BC)
! 28: **********************************************************************
! 29: */
! 30: float genbet(float aa,float bb)
! 31: {
! 32: #define expmax 89.0
! 33: #define infnty 1.0E38
! 34: static float olda = -1.0;
! 35: static float oldb = -1.0;
! 36: static float genbet,a,alpha,b,beta,delta,gamma,k1,k2,r,s,t,u1,u2,v,w,y,z;
! 37: static long qsame;
! 38:
! 39: qsame = olda == aa && oldb == bb;
! 40: if(qsame) goto S20;
! 41: if(!(aa <= 0.0 || bb <= 0.0)) goto S10;
! 42: puts(" AA or BB <= 0 in GENBET - Abort!");
! 43: printf(" AA: %16.6E BB %16.6E\n",aa,bb);
! 44: exit(1);
! 45: S10:
! 46: olda = aa;
! 47: oldb = bb;
! 48: S20:
! 49: if(!(min(aa,bb) > 1.0)) goto S100;
! 50: /*
! 51: Alborithm BB
! 52: Initialize
! 53: */
! 54: if(qsame) goto S30;
! 55: a = min(aa,bb);
! 56: b = max(aa,bb);
! 57: alpha = a+b;
! 58: beta = sqrt((alpha-2.0)/(2.0*a*b-alpha));
! 59: gamma = a+1.0/beta;
! 60: S30:
! 61: S40:
! 62: u1 = ranf();
! 63: /*
! 64: Step 1
! 65: */
! 66: u2 = ranf();
! 67: v = beta*log(u1/(1.0-u1));
! 68: if(!(v > expmax)) goto S50;
! 69: w = infnty;
! 70: goto S60;
! 71: S50:
! 72: w = a*exp(v);
! 73: S60:
! 74: z = pow(u1,2.0)*u2;
! 75: r = gamma*v-1.3862944;
! 76: s = a+r-w;
! 77: /*
! 78: Step 2
! 79: */
! 80: if(s+2.609438 >= 5.0*z) goto S70;
! 81: /*
! 82: Step 3
! 83: */
! 84: t = log(z);
! 85: if(s > t) goto S70;
! 86: /*
! 87: Step 4
! 88: */
! 89: if(r+alpha*log(alpha/(b+w)) < t) goto S40;
! 90: S70:
! 91: /*
! 92: Step 5
! 93: */
! 94: if(!(aa == a)) goto S80;
! 95: genbet = w/(b+w);
! 96: goto S90;
! 97: S80:
! 98: genbet = b/(b+w);
! 99: S90:
! 100: goto S230;
! 101: S100:
! 102: /*
! 103: Algorithm BC
! 104: Initialize
! 105: */
! 106: if(qsame) goto S110;
! 107: a = max(aa,bb);
! 108: b = min(aa,bb);
! 109: alpha = a+b;
! 110: beta = 1.0/b;
! 111: delta = 1.0+a-b;
! 112: k1 = delta*(1.38889E-2+4.16667E-2*b)/(a*beta-0.777778);
! 113: k2 = 0.25+(0.5+0.25/delta)*b;
! 114: S110:
! 115: S120:
! 116: u1 = ranf();
! 117: /*
! 118: Step 1
! 119: */
! 120: u2 = ranf();
! 121: if(u1 >= 0.5) goto S130;
! 122: /*
! 123: Step 2
! 124: */
! 125: y = u1*u2;
! 126: z = u1*y;
! 127: if(0.25*u2+z-y >= k1) goto S120;
! 128: goto S170;
! 129: S130:
! 130: /*
! 131: Step 3
! 132: */
! 133: z = pow(u1,2.0)*u2;
! 134: if(!(z <= 0.25)) goto S160;
! 135: v = beta*log(u1/(1.0-u1));
! 136: if(!(v > expmax)) goto S140;
! 137: w = infnty;
! 138: goto S150;
! 139: S140:
! 140: w = a*exp(v);
! 141: S150:
! 142: goto S200;
! 143: S160:
! 144: if(z >= k2) goto S120;
! 145: S170:
! 146: /*
! 147: Step 4
! 148: Step 5
! 149: */
! 150: v = beta*log(u1/(1.0-u1));
! 151: if(!(v > expmax)) goto S180;
! 152: w = infnty;
! 153: goto S190;
! 154: S180:
! 155: w = a*exp(v);
! 156: S190:
! 157: if(alpha*(log(alpha/(b+w))+v)-1.3862944 < log(z)) goto S120;
! 158: S200:
! 159: /*
! 160: Step 6
! 161: */
! 162: if(!(a == aa)) goto S210;
! 163: genbet = w/(b+w);
! 164: goto S220;
! 165: S210:
! 166: genbet = b/(b+w);
! 167: S230:
! 168: S220:
! 169: return genbet;
! 170: #undef expmax
! 171: #undef infnty
! 172: }
! 173: float genchi(float df)
! 174: /*
! 175: **********************************************************************
! 176: float genchi(float df)
! 177: Generate random value of CHIsquare variable
! 178: Function
! 179: Generates random deviate from the distribution of a chisquare
! 180: with DF degrees of freedom random variable.
! 181: Arguments
! 182: df --> Degrees of freedom of the chisquare
! 183: (Must be positive)
! 184:
! 185: Method
! 186: Uses relation between chisquare and gamma.
! 187: **********************************************************************
! 188: */
! 189: {
! 190: static float genchi;
! 191:
! 192: if(!(df <= 0.0)) goto S10;
! 193: puts("DF <= 0 in GENCHI - ABORT");
! 194: printf("Value of DF: %16.6E\n",df);
! 195: exit(1);
! 196: S10:
! 197: genchi = 2.0*gengam(1.0,df/2.0);
! 198: return genchi;
! 199: }
! 200: float genexp(float av)
! 201: /*
! 202: **********************************************************************
! 203: float genexp(float av)
! 204: GENerate EXPonential random deviate
! 205: Function
! 206: Generates a single random deviate from an exponential
! 207: distribution with mean AV.
! 208: Arguments
! 209: av --> The mean of the exponential distribution from which
! 210: a random deviate is to be generated.
! 211: Method
! 212: Renames SEXPO from TOMS as slightly modified by BWB to use RANF
! 213: instead of SUNIF.
! 214: For details see:
! 215: Ahrens, J.H. and Dieter, U.
! 216: Computer Methods for Sampling From the
! 217: Exponential and Normal Distributions.
! 218: Comm. ACM, 15,10 (Oct. 1972), 873 - 882.
! 219: **********************************************************************
! 220: */
! 221: {
! 222: static float genexp;
! 223:
! 224: genexp = sexpo()*av;
! 225: return genexp;
! 226: }
! 227: float genf(float dfn,float dfd)
! 228: /*
! 229: **********************************************************************
! 230: float genf(float dfn,float dfd)
! 231: GENerate random deviate from the F distribution
! 232: Function
! 233: Generates a random deviate from the F (variance ratio)
! 234: distribution with DFN degrees of freedom in the numerator
! 235: and DFD degrees of freedom in the denominator.
! 236: Arguments
! 237: dfn --> Numerator degrees of freedom
! 238: (Must be positive)
! 239: dfd --> Denominator degrees of freedom
! 240: (Must be positive)
! 241: Method
! 242: Directly generates ratio of chisquare variates
! 243: **********************************************************************
! 244: */
! 245: {
! 246: static float genf,xden,xnum;
! 247:
! 248: if(!(dfn <= 0.0 || dfd <= 0.0)) goto S10;
! 249: puts("Degrees of freedom nonpositive in GENF - abort!");
! 250: printf("DFN value: %16.6EDFD value: %16.6E\n",dfn,dfd);
! 251: exit(1);
! 252: S10:
! 253: xnum = genchi(dfn)/dfn;
! 254: /*
! 255: GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD )
! 256: */
! 257: xden = genchi(dfd)/dfd;
! 258: if(!(xden <= 9.999999999998E-39*xnum)) goto S20;
! 259: puts(" GENF - generated numbers would cause overflow");
! 260: printf(" Numerator %16.6E Denominator %16.6E\n",xnum,xden);
! 261: puts(" GENF returning 1.0E38");
! 262: genf = 1.0E38;
! 263: goto S30;
! 264: S20:
! 265: genf = xnum/xden;
! 266: S30:
! 267: return genf;
! 268: }
! 269: float gengam(float a,float r)
! 270: /*
! 271: **********************************************************************
! 272: float gengam(float a,float r)
! 273: GENerates random deviates from GAMma distribution
! 274: Function
! 275: Generates random deviates from the gamma distribution whose
! 276: density is
! 277: (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)
! 278: Arguments
! 279: a --> Location parameter of Gamma distribution
! 280: r --> Shape parameter of Gamma distribution
! 281: Method
! 282: Renames SGAMMA from TOMS as slightly modified by BWB to use RANF
! 283: instead of SUNIF.
! 284: For details see:
! 285: (Case R >= 1.0)
! 286: Ahrens, J.H. and Dieter, U.
! 287: Generating Gamma Variates by a
! 288: Modified Rejection Technique.
! 289: Comm. ACM, 25,1 (Jan. 1982), 47 - 54.
! 290: Algorithm GD
! 291: (Case 0.0 <= R <= 1.0)
! 292: Ahrens, J.H. and Dieter, U.
! 293: Computer Methods for Sampling from Gamma,
! 294: Beta, Poisson and Binomial Distributions.
! 295: Computing, 12 (1974), 223-246/
! 296: Adapted algorithm GS.
! 297: **********************************************************************
! 298: */
! 299: {
! 300: static float gengam;
! 301:
! 302: gengam = sgamma(r);
! 303: gengam /= a;
! 304: return gengam;
! 305: }
! 306: void genmn(float *parm,float *x,float *work)
! 307: /*
! 308: **********************************************************************
! 309: void genmn(float *parm,float *x,float *work)
! 310: GENerate Multivariate Normal random deviate
! 311: Arguments
! 312: parm --> Parameters needed to generate multivariate normal
! 313: deviates (MEANV and Cholesky decomposition of
! 314: COVM). Set by a previous call to SETGMN.
! 315: 1 : 1 - size of deviate, P
! 316: 2 : P + 1 - mean vector
! 317: P+2 : P*(P+3)/2 + 1 - upper half of cholesky
! 318: decomposition of cov matrix
! 319: x <-- Vector deviate generated.
! 320: work <--> Scratch array
! 321: Method
! 322: 1) Generate P independent standard normal deviates - Ei ~ N(0,1)
! 323: 2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM
! 324: 3) trans(A)E + MEANV ~ N(MEANV,COVM)
! 325: **********************************************************************
! 326: */
! 327: {
! 328: static long i,icount,j,p,D1,D2,D3,D4;
! 329: static float ae;
! 330:
! 331: p = (long) (*parm);
! 332: /*
! 333: Generate P independent normal deviates - WORK ~ N(0,1)
! 334: */
! 335: for(i=1; i<=p; i++) *(work+i-1) = snorm();
! 336: for(i=1,D3=1,D4=(p-i+D3)/D3; D4>0; D4--,i+=D3) {
! 337: /*
! 338: PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky
! 339: decomposition of the desired covariance matrix.
! 340: trans(A)(1,1) = PARM(P+2)
! 341: trans(A)(2,1) = PARM(P+3)
! 342: trans(A)(2,2) = PARM(P+2+P)
! 343: trans(A)(3,1) = PARM(P+4)
! 344: trans(A)(3,2) = PARM(P+3+P)
! 345: trans(A)(3,3) = PARM(P+2-1+2P) ...
! 346: trans(A)*WORK + MEANV ~ N(MEANV,COVM)
! 347: */
! 348: icount = 0;
! 349: ae = 0.0;
! 350: for(j=1,D1=1,D2=(i-j+D1)/D1; D2>0; D2--,j+=D1) {
! 351: icount += (j-1);
! 352: ae += (*(parm+i+(j-1)*p-icount+p)**(work+j-1));
! 353: }
! 354: *(x+i-1) = ae+*(parm+i);
! 355: }
! 356: }
! 357: float gennch(float df,float xnonc)
! 358: /*
! 359: **********************************************************************
! 360: float gennch(float df,float xnonc)
! 361: Generate random value of Noncentral CHIsquare variable
! 362: Function
! 363: Generates random deviate from the distribution of a noncentral
! 364: chisquare with DF degrees of freedom and noncentrality parameter
! 365: xnonc.
! 366: Arguments
! 367: df --> Degrees of freedom of the chisquare
! 368: (Must be > 1.0)
! 369: xnonc --> Noncentrality parameter of the chisquare
! 370: (Must be >= 0.0)
! 371: Method
! 372: Uses fact that noncentral chisquare is the sum of a chisquare
! 373: deviate with DF-1 degrees of freedom plus the square of a normal
! 374: deviate with mean XNONC and standard deviation 1.
! 375: **********************************************************************
! 376: */
! 377: {
! 378: static float gennch;
! 379:
! 380: if(!(df <= 1.0 || xnonc < 0.0)) goto S10;
! 381: puts("DF <= 1 or XNONC < 0 in GENNCH - ABORT");
! 382: printf("Value of DF: %16.6E Value of XNONC%16.6E\n",df,xnonc);
! 383: exit(1);
! 384: S10:
! 385: gennch = genchi(df-1.0)+pow(gennor(sqrt(xnonc),1.0),2.0);
! 386: return gennch;
! 387: }
! 388: float gennf(float dfn,float dfd,float xnonc)
! 389: /*
! 390: **********************************************************************
! 391: float gennf(float dfn,float dfd,float xnonc)
! 392: GENerate random deviate from the Noncentral F distribution
! 393: Function
! 394: Generates a random deviate from the noncentral F (variance ratio)
! 395: distribution with DFN degrees of freedom in the numerator, and DFD
! 396: degrees of freedom in the denominator, and noncentrality parameter
! 397: XNONC.
! 398: Arguments
! 399: dfn --> Numerator degrees of freedom
! 400: (Must be >= 1.0)
! 401: dfd --> Denominator degrees of freedom
! 402: (Must be positive)
! 403: xnonc --> Noncentrality parameter
! 404: (Must be nonnegative)
! 405: Method
! 406: Directly generates ratio of noncentral numerator chisquare variate
! 407: to central denominator chisquare variate.
! 408: **********************************************************************
! 409: */
! 410: {
! 411: static float gennf,xden,xnum;
! 412: static long qcond;
! 413:
! 414: qcond = dfn <= 1.0 || dfd <= 0.0 || xnonc < 0.0;
! 415: if(!qcond) goto S10;
! 416: puts("In GENNF - Either (1) Numerator DF <= 1.0 or");
! 417: puts("(2) Denominator DF < 0.0 or ");
! 418: puts("(3) Noncentrality parameter < 0.0");
! 419: printf("DFN value: %16.6EDFD value: %16.6EXNONC value: \n%16.6E\n",dfn,dfd,
! 420: xnonc);
! 421: exit(1);
! 422: S10:
! 423: xnum = gennch(dfn,xnonc)/dfn;
! 424: /*
! 425: GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD )
! 426: */
! 427: xden = genchi(dfd)/dfd;
! 428: if(!(xden <= 9.999999999998E-39*xnum)) goto S20;
! 429: puts(" GENNF - generated numbers would cause overflow");
! 430: printf(" Numerator %16.6E Denominator %16.6E\n",xnum,xden);
! 431: puts(" GENNF returning 1.0E38");
! 432: gennf = 1.0E38;
! 433: goto S30;
! 434: S20:
! 435: gennf = xnum/xden;
! 436: S30:
! 437: return gennf;
! 438: }
! 439: float gennor(float av,float sd)
! 440: /*
! 441: **********************************************************************
! 442: float gennor(float av,float sd)
! 443: GENerate random deviate from a NORmal distribution
! 444: Function
! 445: Generates a single random deviate from a normal distribution
! 446: with mean, AV, and standard deviation, SD.
! 447: Arguments
! 448: av --> Mean of the normal distribution.
! 449: sd --> Standard deviation of the normal distribution.
! 450: Method
! 451: Renames SNORM from TOMS as slightly modified by BWB to use RANF
! 452: instead of SUNIF.
! 453: For details see:
! 454: Ahrens, J.H. and Dieter, U.
! 455: Extensions of Forsythe's Method for Random
! 456: Sampling from the Normal Distribution.
! 457: Math. Comput., 27,124 (Oct. 1973), 927 - 937.
! 458: **********************************************************************
! 459: */
! 460: {
! 461: static float gennor;
! 462:
! 463: gennor = sd*snorm()+av;
! 464: return gennor;
! 465: }
! 466: void genprm(long *iarray,int larray)
! 467: /*
! 468: **********************************************************************
! 469: void genprm(long *iarray,int larray)
! 470: GENerate random PeRMutation of iarray
! 471: Arguments
! 472: iarray <--> On output IARRAY is a random permutation of its
! 473: value on input
! 474: larray <--> Length of IARRAY
! 475: **********************************************************************
! 476: */
! 477: {
! 478: static long i,itmp,iwhich,D1,D2;
! 479:
! 480: for(i=1,D1=1,D2=(larray-i+D1)/D1; D2>0; D2--,i+=D1) {
! 481: iwhich = ignuin(i,larray);
! 482: itmp = *(iarray+iwhich-1);
! 483: *(iarray+iwhich-1) = *(iarray+i-1);
! 484: *(iarray+i-1) = itmp;
! 485: }
! 486: }
! 487: float genunf(float low,float high)
! 488: /*
! 489: **********************************************************************
! 490: float genunf(float low,float high)
! 491: GeNerate Uniform Real between LOW and HIGH
! 492: Function
! 493: Generates a real uniformly distributed between LOW and HIGH.
! 494: Arguments
! 495: low --> Low bound (exclusive) on real value to be generated
! 496: high --> High bound (exclusive) on real value to be generated
! 497: **********************************************************************
! 498: */
! 499: {
! 500: static float genunf;
! 501:
! 502: if(!(low > high)) goto S10;
! 503: printf("LOW > HIGH in GENUNF: LOW %16.6E HIGH: %16.6E\n",low,high);
! 504: puts("Abort");
! 505: exit(1);
! 506: S10:
! 507: genunf = low+(high-low)*ranf();
! 508: return genunf;
! 509: }
! 510: void gscgn(long getset,long *g)
! 511: /*
! 512: **********************************************************************
! 513: void gscgn(long getset,long *g)
! 514: Get/Set GeNerator
! 515: Gets or returns in G the number of the current generator
! 516: Arguments
! 517: getset --> 0 Get
! 518: 1 Set
! 519: g <-- Number of the current random number generator (1..32)
! 520: **********************************************************************
! 521: */
! 522: {
! 523: #define numg 32L
! 524: static long curntg = 1;
! 525: if(getset == 0) *g = curntg;
! 526: else {
! 527: if(*g < 0 || *g > numg) {
! 528: puts(" Generator number out of range in GSCGN");
! 529: exit(0);
! 530: }
! 531: curntg = *g;
! 532: }
! 533: #undef numg
! 534: }
! 535: void gsrgs(long getset,long *qvalue)
! 536: /*
! 537: **********************************************************************
! 538: void gsrgs(long getset,long *qvalue)
! 539: Get/Set Random Generators Set
! 540: Gets or sets whether random generators set (initialized).
! 541: Initially (data statement) state is not set
! 542: If getset is 1 state is set to qvalue
! 543: If getset is 0 state returned in qvalue
! 544: **********************************************************************
! 545: */
! 546: {
! 547: static long qinit = 0;
! 548:
! 549: if(getset == 0) *qvalue = qinit;
! 550: else qinit = *qvalue;
! 551: }
! 552: void gssst(long getset,long *qset)
! 553: /*
! 554: **********************************************************************
! 555: void gssst(long getset,long *qset)
! 556: Get or Set whether Seed is Set
! 557: Initialize to Seed not Set
! 558: If getset is 1 sets state to Seed Set
! 559: If getset is 0 returns T in qset if Seed Set
! 560: Else returns F in qset
! 561: **********************************************************************
! 562: */
! 563: {
! 564: static long qstate = 0;
! 565: if(getset != 0) qstate = 1;
! 566: else *qset = qstate;
! 567: }
! 568: long ignbin(long n,float pp)
! 569: /*
! 570: **********************************************************************
! 571: long ignbin(long n,float pp)
! 572: GENerate BINomial random deviate
! 573: Function
! 574: Generates a single random deviate from a binomial
! 575: distribution whose number of trials is N and whose
! 576: probability of an event in each trial is P.
! 577: Arguments
! 578: n --> The number of trials in the binomial distribution
! 579: from which a random deviate is to be generated.
! 580: p --> The probability of an event in each trial of the
! 581: binomial distribution from which a random deviate
! 582: is to be generated.
! 583: ignbin <-- A random deviate yielding the number of events
! 584: from N independent trials, each of which has
! 585: a probability of event P.
! 586: Method
! 587: This is algorithm BTPE from:
! 588: Kachitvichyanukul, V. and Schmeiser, B. W.
! 589: Binomial Random Variate Generation.
! 590: Communications of the ACM, 31, 2
! 591: (February, 1988) 216.
! 592: **********************************************************************
! 593: SUBROUTINE BTPEC(N,PP,ISEED,JX)
! 594: BINOMIAL RANDOM VARIATE GENERATOR
! 595: MEAN .LT. 30 -- INVERSE CDF
! 596: MEAN .GE. 30 -- ALGORITHM BTPE: ACCEPTANCE-REJECTION VIA
! 597: FOUR REGION COMPOSITION. THE FOUR REGIONS ARE A TRIANGLE
! 598: (SYMMETRIC IN THE CENTER), A PAIR OF PARALLELOGRAMS (ABOVE
! 599: THE TRIANGLE), AND EXPONENTIAL LEFT AND RIGHT TAILS.
! 600: BTPE REFERS TO BINOMIAL-TRIANGLE-PARALLELOGRAM-EXPONENTIAL.
! 601: BTPEC REFERS TO BTPE AND "COMBINED." THUS BTPE IS THE
! 602: RESEARCH AND BTPEC IS THE IMPLEMENTATION OF A COMPLETE
! 603: USABLE ALGORITHM.
! 604: REFERENCE: VORATAS KACHITVICHYANUKUL AND BRUCE SCHMEISER,
! 605: "BINOMIAL RANDOM VARIATE GENERATION,"
! 606: COMMUNICATIONS OF THE ACM, FORTHCOMING
! 607: WRITTEN: SEPTEMBER 1980.
! 608: LAST REVISED: MAY 1985, JULY 1987
! 609: REQUIRED SUBPROGRAM: RAND() -- A UNIFORM (0,1) RANDOM NUMBER
! 610: GENERATOR
! 611: ARGUMENTS
! 612: N : NUMBER OF BERNOULLI TRIALS (INPUT)
! 613: PP : PROBABILITY OF SUCCESS IN EACH TRIAL (INPUT)
! 614: ISEED: RANDOM NUMBER SEED (INPUT AND OUTPUT)
! 615: JX: RANDOMLY GENERATED OBSERVATION (OUTPUT)
! 616: VARIABLES
! 617: PSAVE: VALUE OF PP FROM THE LAST CALL TO BTPEC
! 618: NSAVE: VALUE OF N FROM THE LAST CALL TO BTPEC
! 619: XNP: VALUE OF THE MEAN FROM THE LAST CALL TO BTPEC
! 620: P: PROBABILITY USED IN THE GENERATION PHASE OF BTPEC
! 621: FFM: TEMPORARY VARIABLE EQUAL TO XNP + P
! 622: M: INTEGER VALUE OF THE CURRENT MODE
! 623: FM: FLOATING POINT VALUE OF THE CURRENT MODE
! 624: XNPQ: TEMPORARY VARIABLE USED IN SETUP AND SQUEEZING STEPS
! 625: P1: AREA OF THE TRIANGLE
! 626: C: HEIGHT OF THE PARALLELOGRAMS
! 627: XM: CENTER OF THE TRIANGLE
! 628: XL: LEFT END OF THE TRIANGLE
! 629: XR: RIGHT END OF THE TRIANGLE
! 630: AL: TEMPORARY VARIABLE
! 631: XLL: RATE FOR THE LEFT EXPONENTIAL TAIL
! 632: XLR: RATE FOR THE RIGHT EXPONENTIAL TAIL
! 633: P2: AREA OF THE PARALLELOGRAMS
! 634: P3: AREA OF THE LEFT EXPONENTIAL TAIL
! 635: P4: AREA OF THE RIGHT EXPONENTIAL TAIL
! 636: U: A U(0,P4) RANDOM VARIATE USED FIRST TO SELECT ONE OF THE
! 637: FOUR REGIONS AND THEN CONDITIONALLY TO GENERATE A VALUE
! 638: FROM THE REGION
! 639: V: A U(0,1) RANDOM NUMBER USED TO GENERATE THE RANDOM VALUE
! 640: (REGION 1) OR TRANSFORMED INTO THE VARIATE TO ACCEPT OR
! 641: REJECT THE CANDIDATE VALUE
! 642: IX: INTEGER CANDIDATE VALUE
! 643: X: PRELIMINARY CONTINUOUS CANDIDATE VALUE IN REGION 2 LOGIC
! 644: AND A FLOATING POINT IX IN THE ACCEPT/REJECT LOGIC
! 645: K: ABSOLUTE VALUE OF (IX-M)
! 646: F: THE HEIGHT OF THE SCALED DENSITY FUNCTION USED IN THE
! 647: ACCEPT/REJECT DECISION WHEN BOTH M AND IX ARE SMALL
! 648: ALSO USED IN THE INVERSE TRANSFORMATION
! 649: R: THE RATIO P/Q
! 650: G: CONSTANT USED IN CALCULATION OF PROBABILITY
! 651: MP: MODE PLUS ONE, THE LOWER INDEX FOR EXPLICIT CALCULATION
! 652: OF F WHEN IX IS GREATER THAN M
! 653: IX1: CANDIDATE VALUE PLUS ONE, THE LOWER INDEX FOR EXPLICIT
! 654: CALCULATION OF F WHEN IX IS LESS THAN M
! 655: I: INDEX FOR EXPLICIT CALCULATION OF F FOR BTPE
! 656: AMAXP: MAXIMUM ERROR OF THE LOGARITHM OF NORMAL BOUND
! 657: YNORM: LOGARITHM OF NORMAL BOUND
! 658: ALV: NATURAL LOGARITHM OF THE ACCEPT/REJECT VARIATE V
! 659: X1,F1,Z,W,Z2,X2,F2, AND W2 ARE TEMPORARY VARIABLES TO BE
! 660: USED IN THE FINAL ACCEPT/REJECT TEST
! 661: QN: PROBABILITY OF NO SUCCESS IN N TRIALS
! 662: REMARK
! 663: IX AND JX COULD LOGICALLY BE THE SAME VARIABLE, WHICH WOULD
! 664: SAVE A MEMORY POSITION AND A LINE OF CODE. HOWEVER, SOME
! 665: COMPILERS (E.G.,CDC MNF) OPTIMIZE BETTER WHEN THE ARGUMENTS
! 666: ARE NOT INVOLVED.
! 667: ISEED NEEDS TO BE DOUBLE PRECISION IF THE IMSL ROUTINE
! 668: GGUBFS IS USED TO GENERATE UNIFORM RANDOM NUMBER, OTHERWISE
! 669: TYPE OF ISEED SHOULD BE DICTATED BY THE UNIFORM GENERATOR
! 670: **********************************************************************
! 671: *****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY
! 672: */
! 673: {
! 674: static float psave = -1.0;
! 675: static long nsave = -1;
! 676: static long ignbin,i,ix,ix1,k,m,mp,T1;
! 677: static float al,alv,amaxp,c,f,f1,f2,ffm,fm,g,p,p1,p2,p3,p4,q,qn,r,u,v,w,w2,x,x1,
! 678: x2,xl,xll,xlr,xm,xnp,xnpq,xr,ynorm,z,z2;
! 679:
! 680: if(pp != psave) goto S10;
! 681: if(n != nsave) goto S20;
! 682: if(xnp < 30.0) goto S150;
! 683: goto S30;
! 684: S10:
! 685: /*
! 686: *****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE
! 687: */
! 688: psave = pp;
! 689: p = min(psave,1.0-psave);
! 690: q = 1.0-p;
! 691: S20:
! 692: xnp = n*p;
! 693: nsave = n;
! 694: if(xnp < 30.0) goto S140;
! 695: ffm = xnp+p;
! 696: m = ffm;
! 697: fm = m;
! 698: xnpq = xnp*q;
! 699: p1 = (long) (2.195*sqrt(xnpq)-4.6*q)+0.5;
! 700: xm = fm+0.5;
! 701: xl = xm-p1;
! 702: xr = xm+p1;
! 703: c = 0.134+20.5/(15.3+fm);
! 704: al = (ffm-xl)/(ffm-xl*p);
! 705: xll = al*(1.0+0.5*al);
! 706: al = (xr-ffm)/(xr*q);
! 707: xlr = al*(1.0+0.5*al);
! 708: p2 = p1*(1.0+c+c);
! 709: p3 = p2+c/xll;
! 710: p4 = p3+c/xlr;
! 711: S30:
! 712: /*
! 713: *****GENERATE VARIATE
! 714: */
! 715: u = ranf()*p4;
! 716: v = ranf();
! 717: /*
! 718: TRIANGULAR REGION
! 719: */
! 720: if(u > p1) goto S40;
! 721: ix = xm-p1*v+u;
! 722: goto S170;
! 723: S40:
! 724: /*
! 725: PARALLELOGRAM REGION
! 726: */
! 727: if(u > p2) goto S50;
! 728: x = xl+(u-p1)/c;
! 729: v = v*c+1.0-abs(xm-x)/p1;
! 730: if(v > 1.0 || v <= 0.0) goto S30;
! 731: ix = x;
! 732: goto S70;
! 733: S50:
! 734: /*
! 735: LEFT TAIL
! 736: */
! 737: if(u > p3) goto S60;
! 738: ix = xl+log(v)/xll;
! 739: if(ix < 0) goto S30;
! 740: v *= ((u-p2)*xll);
! 741: goto S70;
! 742: S60:
! 743: /*
! 744: RIGHT TAIL
! 745: */
! 746: ix = xr-log(v)/xlr;
! 747: if(ix > n) goto S30;
! 748: v *= ((u-p3)*xlr);
! 749: S70:
! 750: /*
! 751: *****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST
! 752: */
! 753: k = abs(ix-m);
! 754: if(k > 20 && k < xnpq/2-1) goto S130;
! 755: /*
! 756: EXPLICIT EVALUATION
! 757: */
! 758: f = 1.0;
! 759: r = p/q;
! 760: g = (n+1)*r;
! 761: T1 = m-ix;
! 762: if(T1 < 0) goto S80;
! 763: else if(T1 == 0) goto S120;
! 764: else goto S100;
! 765: S80:
! 766: mp = m+1;
! 767: for(i=mp; i<=ix; i++) f *= (g/i-r);
! 768: goto S120;
! 769: S100:
! 770: ix1 = ix+1;
! 771: for(i=ix1; i<=m; i++) f /= (g/i-r);
! 772: S120:
! 773: if(v <= f) goto S170;
! 774: goto S30;
! 775: S130:
! 776: /*
! 777: SQUEEZING USING UPPER AND LOWER BOUNDS ON ALOG(F(X))
! 778: */
! 779: amaxp = k/xnpq*((k*(k/3.0+0.625)+0.1666666666666)/xnpq+0.5);
! 780: ynorm = -(k*k/(2.0*xnpq));
! 781: alv = log(v);
! 782: if(alv < ynorm-amaxp) goto S170;
! 783: if(alv > ynorm+amaxp) goto S30;
! 784: /*
! 785: STIRLING'S FORMULA TO MACHINE ACCURACY FOR
! 786: THE FINAL ACCEPTANCE/REJECTION TEST
! 787: */
! 788: x1 = ix+1.0;
! 789: f1 = fm+1.0;
! 790: z = n+1.0-fm;
! 791: w = n-ix+1.0;
! 792: z2 = z*z;
! 793: x2 = x1*x1;
! 794: f2 = f1*f1;
! 795: w2 = w*w;
! 796: if(alv <= xm*log(f1/x1)+(n-m+0.5)*log(z/w)+(ix-m)*log(w*p/(x1*q))+(13860.0-
! 797: (462.0-(132.0-(99.0-140.0/f2)/f2)/f2)/f2)/f1/166320.0+(13860.0-(462.0-
! 798: (132.0-(99.0-140.0/z2)/z2)/z2)/z2)/z/166320.0+(13860.0-(462.0-(132.0-
! 799: (99.0-140.0/x2)/x2)/x2)/x2)/x1/166320.0+(13860.0-(462.0-(132.0-(99.0
! 800: -140.0/w2)/w2)/w2)/w2)/w/166320.0) goto S170;
! 801: goto S30;
! 802: S140:
! 803: /*
! 804: INVERSE CDF LOGIC FOR MEAN LESS THAN 30
! 805: */
! 806: qn = pow(q,(double)n);
! 807: r = p/q;
! 808: g = r*(n+1);
! 809: S150:
! 810: ix = 0;
! 811: f = qn;
! 812: u = ranf();
! 813: S160:
! 814: if(u < f) goto S170;
! 815: if(ix > 110) goto S150;
! 816: u -= f;
! 817: ix += 1;
! 818: f *= (g/ix-r);
! 819: goto S160;
! 820: S170:
! 821: if(psave > 0.5) ix = n-ix;
! 822: ignbin = ix;
! 823: return ignbin;
! 824: }
! 825: long ignpoi(float mu)
! 826: /*
! 827: **********************************************************************
! 828: long ignpoi(float mu)
! 829: GENerate POIsson random deviate
! 830: Function
! 831: Generates a single random deviate from a Poisson
! 832: distribution with mean AV.
! 833: Arguments
! 834: av --> The mean of the Poisson distribution from which
! 835: a random deviate is to be generated.
! 836: genexp <-- The random deviate.
! 837: Method
! 838: Renames KPOIS from TOMS as slightly modified by BWB to use RANF
! 839: instead of SUNIF.
! 840: For details see:
! 841: Ahrens, J.H. and Dieter, U.
! 842: Computer Generation of Poisson Deviates
! 843: From Modified Normal Distributions.
! 844: ACM Trans. Math. Software, 8, 2
! 845: (June 1982),163-179
! 846: **********************************************************************
! 847: **********************************************************************
! 848:
! 849:
! 850: P O I S S O N DISTRIBUTION
! 851:
! 852:
! 853: **********************************************************************
! 854: **********************************************************************
! 855:
! 856: FOR DETAILS SEE:
! 857:
! 858: AHRENS, J.H. AND DIETER, U.
! 859: COMPUTER GENERATION OF POISSON DEVIATES
! 860: FROM MODIFIED NORMAL DISTRIBUTIONS.
! 861: ACM TRANS. MATH. SOFTWARE, 8,2 (JUNE 1982), 163 - 179.
! 862:
! 863: (SLIGHTLY MODIFIED VERSION OF THE PROGRAM IN THE ABOVE ARTICLE)
! 864:
! 865: **********************************************************************
! 866: INTEGER FUNCTION IGNPOI(IR,MU)
! 867: INPUT: IR=CURRENT STATE OF BASIC RANDOM NUMBER GENERATOR
! 868: MU=MEAN MU OF THE POISSON DISTRIBUTION
! 869: OUTPUT: IGNPOI=SAMPLE FROM THE POISSON-(MU)-DISTRIBUTION
! 870: MUPREV=PREVIOUS MU, MUOLD=MU AT LAST EXECUTION OF STEP P OR B.
! 871: TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT
! 872: COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL
! 873: SEPARATION OF CASES A AND B
! 874: */
! 875: {
! 876: extern float fsign( float num, float sign );
! 877: static float a0 = -0.5;
! 878: static float a1 = 0.3333333;
! 879: static float a2 = -0.2500068;
! 880: static float a3 = 0.2000118;
! 881: static float a4 = -0.1661269;
! 882: static float a5 = 0.1421878;
! 883: static float a6 = -0.1384794;
! 884: static float a7 = 0.125006;
! 885: static float muold = 0.0;
! 886: static float muprev = 0.0;
! 887: static float fact[10] = {
! 888: 1.0,1.0,2.0,6.0,24.0,120.0,720.0,5040.0,40320.0,362880.0
! 889: };
! 890: static long ignpoi,j,k,kflag,l,m;
! 891: static float b1,b2,c,c0,c1,c2,c3,d,del,difmuk,e,fk,fx,fy,g,omega,p,p0,px,py,q,s,
! 892: t,u,v,x,xx,pp[35];
! 893:
! 894: if(mu == muprev) goto S10;
! 895: if(mu < 10.0) goto S120;
! 896: /*
! 897: C A S E A. (RECALCULATION OF S,D,L IF MU HAS CHANGED)
! 898: */
! 899: muprev = mu;
! 900: s = sqrt(mu);
! 901: d = 6.0*mu*mu;
! 902: /*
! 903: THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL
! 904: PROBABILITIES FK WHENEVER K >= M(MU). L=IFIX(MU-1.1484)
! 905: IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 .
! 906: */
! 907: l = (long) (mu-1.1484);
! 908: S10:
! 909: /*
! 910: STEP N. NORMAL SAMPLE - SNORM(IR) FOR STANDARD NORMAL DEVIATE
! 911: */
! 912: g = mu+s*snorm();
! 913: if(g < 0.0) goto S20;
! 914: ignpoi = (long) (g);
! 915: /*
! 916: STEP I. IMMEDIATE ACCEPTANCE IF IGNPOI IS LARGE ENOUGH
! 917: */
! 918: if(ignpoi >= l) return ignpoi;
! 919: /*
! 920: STEP S. SQUEEZE ACCEPTANCE - SUNIF(IR) FOR (0,1)-SAMPLE U
! 921: */
! 922: fk = (float)ignpoi;
! 923: difmuk = mu-fk;
! 924: u = ranf();
! 925: if(d*u >= difmuk*difmuk*difmuk) return ignpoi;
! 926: S20:
! 927: /*
! 928: STEP P. PREPARATIONS FOR STEPS Q AND H.
! 929: (RECALCULATIONS OF PARAMETERS IF NECESSARY)
! 930: .3989423=(2*PI)**(-.5) .416667E-1=1./24. .1428571=1./7.
! 931: THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE
! 932: APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK.
! 933: C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION.
! 934: */
! 935: if(mu == muold) goto S30;
! 936: muold = mu;
! 937: omega = 0.3989423/s;
! 938: b1 = 4.166667E-2/mu;
! 939: b2 = 0.3*b1*b1;
! 940: c3 = 0.1428571*b1*b2;
! 941: c2 = b2-15.0*c3;
! 942: c1 = b1-6.0*b2+45.0*c3;
! 943: c0 = 1.0-b1+3.0*b2-15.0*c3;
! 944: c = 0.1069/mu;
! 945: S30:
! 946: if(g < 0.0) goto S50;
! 947: /*
! 948: 'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN)
! 949: */
! 950: kflag = 0;
! 951: goto S70;
! 952: S40:
! 953: /*
! 954: STEP Q. QUOTIENT ACCEPTANCE (RARE CASE)
! 955: */
! 956: if(fy-u*fy <= py*exp(px-fx)) return ignpoi;
! 957: S50:
! 958: /*
! 959: STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL
! 960: DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'
! 961: (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)
! 962: */
! 963: e = sexpo();
! 964: u = ranf();
! 965: u += (u-1.0);
! 966: t = 1.8+fsign(e,u);
! 967: if(t <= -0.6744) goto S50;
! 968: ignpoi = (long) (mu+s*t);
! 969: fk = (float)ignpoi;
! 970: difmuk = mu-fk;
! 971: /*
! 972: 'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)
! 973: */
! 974: kflag = 1;
! 975: goto S70;
! 976: S60:
! 977: /*
! 978: STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)
! 979: */
! 980: if(c*fabs(u) > py*exp(px+e)-fy*exp(fx+e)) goto S50;
! 981: return ignpoi;
! 982: S70:
! 983: /*
! 984: STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY.
! 985: CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT
! 986: */
! 987: if(ignpoi >= 10) goto S80;
! 988: px = -mu;
! 989: py = pow(mu,(double)ignpoi)/ *(fact+ignpoi);
! 990: goto S110;
! 991: S80:
! 992: /*
! 993: CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION
! 994: A0-A7 FOR ACCURACY WHEN ADVISABLE
! 995: .8333333E-1=1./12. .3989423=(2*PI)**(-.5)
! 996: */
! 997: del = 8.333333E-2/fk;
! 998: del -= (4.8*del*del*del);
! 999: v = difmuk/fk;
! 1000: if(fabs(v) <= 0.25) goto S90;
! 1001: px = fk*log(1.0+v)-difmuk-del;
! 1002: goto S100;
! 1003: S90:
! 1004: px = fk*v*v*(((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0)-del;
! 1005: S100:
! 1006: py = 0.3989423/sqrt(fk);
! 1007: S110:
! 1008: x = (0.5-difmuk)/s;
! 1009: xx = x*x;
! 1010: fx = -0.5*xx;
! 1011: fy = omega*(((c3*xx+c2)*xx+c1)*xx+c0);
! 1012: if(kflag <= 0) goto S40;
! 1013: goto S60;
! 1014: S120:
! 1015: /*
! 1016: C A S E B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY)
! 1017: */
! 1018: muprev = 0.0;
! 1019: if(mu == muold) goto S130;
! 1020: muold = mu;
! 1021: m = max(1L,(long) (mu));
! 1022: l = 0;
! 1023: p = exp(-mu);
! 1024: q = p0 = p;
! 1025: S130:
! 1026: /*
! 1027: STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
! 1028: */
! 1029: u = ranf();
! 1030: ignpoi = 0;
! 1031: if(u <= p0) return ignpoi;
! 1032: /*
! 1033: STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE
! 1034: PP-TABLE OF CUMULATIVE POISSON PROBABILITIES
! 1035: (0.458=PP(9) FOR MU=10)
! 1036: */
! 1037: if(l == 0) goto S150;
! 1038: j = 1;
! 1039: if(u > 0.458) j = min(l,m);
! 1040: for(k=j; k<=l; k++) {
! 1041: if(u <= *(pp+k-1)) goto S180;
! 1042: }
! 1043: if(l == 35) goto S130;
! 1044: S150:
! 1045: /*
! 1046: STEP C. CREATION OF NEW POISSON PROBABILITIES P
! 1047: AND THEIR CUMULATIVES Q=PP(K)
! 1048: */
! 1049: l += 1;
! 1050: for(k=l; k<=35; k++) {
! 1051: p = p*mu/(float)k;
! 1052: q += p;
! 1053: *(pp+k-1) = q;
! 1054: if(u <= q) goto S170;
! 1055: }
! 1056: l = 35;
! 1057: goto S130;
! 1058: S170:
! 1059: l = k;
! 1060: S180:
! 1061: ignpoi = k;
! 1062: return ignpoi;
! 1063: }
! 1064: long ignuin(long low,long high)
! 1065: /*
! 1066: **********************************************************************
! 1067: long ignuin(long low,long high)
! 1068: GeNerate Uniform INteger
! 1069: Function
! 1070: Generates an integer uniformly distributed between LOW and HIGH.
! 1071: Arguments
! 1072: low --> Low bound (inclusive) on integer value to be generated
! 1073: high --> High bound (inclusive) on integer value to be generated
! 1074: Note
! 1075: If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and
! 1076: stops the program.
! 1077: **********************************************************************
! 1078: IGNLGI generates integers between 1 and 2147483562
! 1079: MAXNUM is 1 less than maximum generable value
! 1080: */
! 1081: {
! 1082: #define maxnum 2147483561L
! 1083: static long ignuin,ign,maxnow,range,ranp1;
! 1084:
! 1085: if(!(low > high)) goto S10;
! 1086: puts(" low > high in ignuin - ABORT");
! 1087: exit(1);
! 1088:
! 1089: S10:
! 1090: range = high-low;
! 1091: if(!(range > maxnum)) goto S20;
! 1092: puts(" high - low too large in ignuin - ABORT");
! 1093: exit(1);
! 1094:
! 1095: S20:
! 1096: if(!(low == high)) goto S30;
! 1097: ignuin = low;
! 1098: return ignuin;
! 1099:
! 1100: S30:
! 1101: /*
! 1102: Number to be generated should be in range 0..RANGE
! 1103: Set MAXNOW so that the number of integers in 0..MAXNOW is an
! 1104: integral multiple of the number in 0..RANGE
! 1105: */
! 1106: ranp1 = range+1;
! 1107: maxnow = maxnum/ranp1*ranp1;
! 1108: S40:
! 1109: ign = ignlgi()-1;
! 1110: if(!(ign <= maxnow)) goto S50;
! 1111: ignuin = low+ign%ranp1;
! 1112: return ignuin;
! 1113: S50:
! 1114: goto S40;
! 1115: #undef maxnum
! 1116: #undef err1
! 1117: #undef err2
! 1118: }
! 1119: long lennob( char *str )
! 1120: /*
! 1121: Returns the length of str ignoring trailing blanks but not
! 1122: other white space.
! 1123: */
! 1124: {
! 1125: long i, i_nb;
! 1126:
! 1127: for (i=0, i_nb= -1L; *(str+i); i++)
! 1128: if ( *(str+i) != ' ' ) i_nb = i;
! 1129: return (i_nb+1);
! 1130: }
! 1131: long mltmod(long a,long s,long m)
! 1132: /*
! 1133: **********************************************************************
! 1134: long mltmod(long a,long s,long m)
! 1135: Returns (A*S) MOD M
! 1136: This is a transcription from Pascal to Fortran of routine
! 1137: MULtMod_Decompos from the paper
! 1138: L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
! 1139: with Splitting Facilities." ACM Transactions on Mathematical
! 1140: Software, 17:98-111 (1991)
! 1141: Arguments
! 1142: a, s, m -->
! 1143: **********************************************************************
! 1144: */
! 1145: {
! 1146: #define h 32768L
! 1147: static long mltmod,a0,a1,k,p,q,qh,rh;
! 1148: /*
! 1149: H = 2**((b-2)/2) where b = 32 because we are using a 32 bit
! 1150: machine. On a different machine recompute H
! 1151: */
! 1152: if(!(a <= 0 || a >= m || s <= 0 || s >= m)) goto S10;
! 1153: puts(" a, m, s out of order in mltmod - ABORT!");
! 1154: printf(" a = %12ld s = %12ld m = %12ld\n",a,s,m);
! 1155: puts(" mltmod requires: 0 < a < m; 0 < s < m");
! 1156: exit(1);
! 1157: S10:
! 1158: if(!(a < h)) goto S20;
! 1159: a0 = a;
! 1160: p = 0;
! 1161: goto S120;
! 1162: S20:
! 1163: a1 = a/h;
! 1164: a0 = a-h*a1;
! 1165: qh = m/h;
! 1166: rh = m-h*qh;
! 1167: if(!(a1 >= h)) goto S50;
! 1168: a1 -= h;
! 1169: k = s/qh;
! 1170: p = h*(s-k*qh)-k*rh;
! 1171: S30:
! 1172: if(!(p < 0)) goto S40;
! 1173: p += m;
! 1174: goto S30;
! 1175: S40:
! 1176: goto S60;
! 1177: S50:
! 1178: p = 0;
! 1179: S60:
! 1180: /*
! 1181: P = (A2*S*H)MOD M
! 1182: */
! 1183: if(!(a1 != 0)) goto S90;
! 1184: q = m/a1;
! 1185: k = s/q;
! 1186: p -= (k*(m-a1*q));
! 1187: if(p > 0) p -= m;
! 1188: p += (a1*(s-k*q));
! 1189: S70:
! 1190: if(!(p < 0)) goto S80;
! 1191: p += m;
! 1192: goto S70;
! 1193: S90:
! 1194: S80:
! 1195: k = p/qh;
! 1196: /*
! 1197: P = ((A2*H + A1)*S)MOD M
! 1198: */
! 1199: p = h*(p-k*qh)-k*rh;
! 1200: S100:
! 1201: if(!(p < 0)) goto S110;
! 1202: p += m;
! 1203: goto S100;
! 1204: S120:
! 1205: S110:
! 1206: if(!(a0 != 0)) goto S150;
! 1207: /*
! 1208: P = ((A2*H + A1)*H*S)MOD M
! 1209: */
! 1210: q = m/a0;
! 1211: k = s/q;
! 1212: p -= (k*(m-a0*q));
! 1213: if(p > 0) p -= m;
! 1214: p += (a0*(s-k*q));
! 1215: S130:
! 1216: if(!(p < 0)) goto S140;
! 1217: p += m;
! 1218: goto S130;
! 1219: S150:
! 1220: S140:
! 1221: mltmod = p;
! 1222: return mltmod;
! 1223: #undef h
! 1224: }
! 1225: void phrtsd(char* phrase,long *seed1,long *seed2)
! 1226: /*
! 1227: **********************************************************************
! 1228: void phrtsd(char* phrase,long *seed1,long *seed2)
! 1229: PHRase To SeeDs
! 1230:
! 1231: Function
! 1232:
! 1233: Uses a phrase (character string) to generate two seeds for the RGN
! 1234: random number generator.
! 1235: Arguments
! 1236: phrase --> Phrase to be used for random number generation
! 1237:
! 1238: seed1 <-- First seed for generator
! 1239:
! 1240: seed2 <-- Second seed for generator
! 1241:
! 1242: Note
! 1243:
! 1244: Trailing blanks are eliminated before the seeds are generated.
! 1245: Generated seed values will fall in the range 1..2^30
! 1246: (1..1,073,741,824)
! 1247: **********************************************************************
! 1248: */
! 1249: {
! 1250:
! 1251: static char table[] =
! 1252: "abcdefghijklmnopqrstuvwxyz\
! 1253: ABCDEFGHIJKLMNOPQRSTUVWXYZ\
! 1254: 0123456789\
! 1255: !@#$%^&*()_+[];:'\\\"<>?,./";
! 1256:
! 1257: long ix;
! 1258:
! 1259: static long twop30 = 1073741824L;
! 1260: static long shift[5] = {
! 1261: 1L,64L,4096L,262144L,16777216L
! 1262: };
! 1263: static long i,ichr,j,lphr,values[5];
! 1264: extern long lennob(char *str);
! 1265:
! 1266: *seed1 = 1234567890L;
! 1267: *seed2 = 123456789L;
! 1268: lphr = lennob(phrase);
! 1269: if(lphr < 1) return;
! 1270: for(i=0; i<=(lphr-1); i++) {
! 1271: for (ix=0; table[ix]; ix++) if (*(phrase+i) == table[ix]) break;
! 1272: if (!table[ix]) ix = 0;
! 1273: ichr = ix % 64;
! 1274: if(ichr == 0) ichr = 63;
! 1275: for(j=1; j<=5; j++) {
! 1276: *(values+j-1) = ichr-j;
! 1277: if(*(values+j-1) < 1) *(values+j-1) += 63;
! 1278: }
! 1279: for(j=1; j<=5; j++) {
! 1280: *seed1 = ( *seed1+*(shift+j-1)**(values+j-1) ) % twop30;
! 1281: *seed2 = ( *seed2+*(shift+j-1)**(values+6-j-1) ) % twop30;
! 1282: }
! 1283: }
! 1284: #undef twop30
! 1285: }
! 1286: float ranf(void)
! 1287: /*
! 1288: **********************************************************************
! 1289: float ranf(void)
! 1290: RANDom number generator as a Function
! 1291: Returns a random floating point number from a uniform distribution
! 1292: over 0 - 1 (endpoints of this interval are not returned) using the
! 1293: current generator
! 1294: This is a transcription from Pascal to Fortran of routine
! 1295: Uniform_01 from the paper
! 1296: L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
! 1297: with Splitting Facilities." ACM Transactions on Mathematical
! 1298: Software, 17:98-111 (1991)
! 1299: **********************************************************************
! 1300: */
! 1301: {
! 1302: static float ranf;
! 1303: /*
! 1304: 4.656613057E-10 is 1/M1 M1 is set in a data statement in IGNLGI
! 1305: and is currently 2147483563. If M1 changes, change this also.
! 1306: */
! 1307: ranf = ignlgi()*4.656613057E-10;
! 1308: return ranf;
! 1309: }
! 1310: void setgmn(float *meanv,float *covm,long p,float *parm)
! 1311: /*
! 1312: **********************************************************************
! 1313: void setgmn(float *meanv,float *covm,long p,float *parm)
! 1314: SET Generate Multivariate Normal random deviate
! 1315: Function
! 1316: Places P, MEANV, and the Cholesky factoriztion of COVM
! 1317: in GENMN.
! 1318: Arguments
! 1319: meanv --> Mean vector of multivariate normal distribution.
! 1320: covm <--> (Input) Covariance matrix of the multivariate
! 1321: normal distribution
! 1322: (Output) Destroyed on output
! 1323: p --> Dimension of the normal, or length of MEANV.
! 1324: parm <-- Array of parameters needed to generate multivariate norma
! 1325: deviates (P, MEANV and Cholesky decomposition of
! 1326: COVM).
! 1327: 1 : 1 - P
! 1328: 2 : P + 1 - MEANV
! 1329: P+2 : P*(P+3)/2 + 1 - Cholesky decomposition of COVM
! 1330: Needed dimension is (p*(p+3)/2 + 1)
! 1331: **********************************************************************
! 1332: */
! 1333: {
! 1334: extern void spofa(float *a,long lda,long n,long *info);
! 1335: static long T1;
! 1336: static long i,icount,info,j,D2,D3,D4,D5;
! 1337: T1 = p*(p+3)/2+1;
! 1338: /*
! 1339: TEST THE INPUT
! 1340: */
! 1341: if(!(p <= 0)) goto S10;
! 1342: puts("P nonpositive in SETGMN");
! 1343: printf("Value of P: %12ld\n",p);
! 1344: exit(1);
! 1345: S10:
! 1346: *parm = p;
! 1347: /*
! 1348: PUT P AND MEANV INTO PARM
! 1349: */
! 1350: for(i=2,D2=1,D3=(p+1-i+D2)/D2; D3>0; D3--,i+=D2) *(parm+i-1) = *(meanv+i-2);
! 1351: /*
! 1352: Cholesky decomposition to find A s.t. trans(A)*(A) = COVM
! 1353: */
! 1354: spofa(covm,p,p,&info);
! 1355: if(!(info != 0)) goto S30;
! 1356: puts(" COVM not positive definite in SETGMN");
! 1357: exit(1);
! 1358: S30:
! 1359: icount = p+1;
! 1360: /*
! 1361: PUT UPPER HALF OF A, WHICH IS NOW THE CHOLESKY FACTOR, INTO PARM
! 1362: COVM(1,1) = PARM(P+2)
! 1363: COVM(1,2) = PARM(P+3)
! 1364: :
! 1365: COVM(1,P) = PARM(2P+1)
! 1366: COVM(2,2) = PARM(2P+2) ...
! 1367: */
! 1368: for(i=1,D4=1,D5=(p-i+D4)/D4; D5>0; D5--,i+=D4) {
! 1369: for(j=i-1; j<p; j++) {
! 1370: icount += 1;
! 1371: *(parm+icount-1) = *(covm+i-1+j*p);
! 1372: }
! 1373: }
! 1374: }
! 1375: float sexpo(void)
! 1376: /*
! 1377: **********************************************************************
! 1378:
! 1379:
! 1380: (STANDARD-) E X P O N E N T I A L DISTRIBUTION
! 1381:
! 1382:
! 1383: **********************************************************************
! 1384: **********************************************************************
! 1385:
! 1386: FOR DETAILS SEE:
! 1387:
! 1388: AHRENS, J.H. AND DIETER, U.
! 1389: COMPUTER METHODS FOR SAMPLING FROM THE
! 1390: EXPONENTIAL AND NORMAL DISTRIBUTIONS.
! 1391: COMM. ACM, 15,10 (OCT. 1972), 873 - 882.
! 1392:
! 1393: ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM
! 1394: 'SA' IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION)
! 1395:
! 1396: Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
! 1397: SUNIF. The argument IR thus goes away.
! 1398:
! 1399: **********************************************************************
! 1400: Q(N) = SUM(ALOG(2.0)**K/K!) K=1,..,N , THE HIGHEST N
! 1401: (HERE 8) IS DETERMINED BY Q(N)=1.0 WITHIN STANDARD PRECISION
! 1402: */
! 1403: {
! 1404: static float q[8] = {
! 1405: 0.6931472,0.9333737,0.9888778,0.9984959,0.9998293,0.9999833,0.9999986,1.0
! 1406: };
! 1407: static long i;
! 1408: static float sexpo,a,u,ustar,umin;
! 1409: static float *q1 = q;
! 1410: a = 0.0;
! 1411: u = ranf();
! 1412: goto S30;
! 1413: S20:
! 1414: a += *q1;
! 1415: S30:
! 1416: u += u;
! 1417: if(u <= 1.0) goto S20;
! 1418: u -= 1.0;
! 1419: if(u > *q1) goto S60;
! 1420: sexpo = a+u;
! 1421: return sexpo;
! 1422: S60:
! 1423: i = 1;
! 1424: ustar = ranf();
! 1425: umin = ustar;
! 1426: S70:
! 1427: ustar = ranf();
! 1428: if(ustar < umin) umin = ustar;
! 1429: i += 1;
! 1430: if(u > *(q+i-1)) goto S70;
! 1431: sexpo = a+umin**q1;
! 1432: return sexpo;
! 1433: }
! 1434: float sgamma(float a)
! 1435: /*
! 1436: **********************************************************************
! 1437:
! 1438:
! 1439: (STANDARD-) G A M M A DISTRIBUTION
! 1440:
! 1441:
! 1442: **********************************************************************
! 1443: **********************************************************************
! 1444:
! 1445: PARAMETER A >= 1.0 !
! 1446:
! 1447: **********************************************************************
! 1448:
! 1449: FOR DETAILS SEE:
! 1450:
! 1451: AHRENS, J.H. AND DIETER, U.
! 1452: GENERATING GAMMA VARIATES BY A
! 1453: MODIFIED REJECTION TECHNIQUE.
! 1454: COMM. ACM, 25,1 (JAN. 1982), 47 - 54.
! 1455:
! 1456: STEP NUMBERS CORRESPOND TO ALGORITHM 'GD' IN THE ABOVE PAPER
! 1457: (STRAIGHTFORWARD IMPLEMENTATION)
! 1458:
! 1459: Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
! 1460: SUNIF. The argument IR thus goes away.
! 1461:
! 1462: **********************************************************************
! 1463:
! 1464: PARAMETER 0.0 < A < 1.0 !
! 1465:
! 1466: **********************************************************************
! 1467:
! 1468: FOR DETAILS SEE:
! 1469:
! 1470: AHRENS, J.H. AND DIETER, U.
! 1471: COMPUTER METHODS FOR SAMPLING FROM GAMMA,
! 1472: BETA, POISSON AND BINOMIAL DISTRIBUTIONS.
! 1473: COMPUTING, 12 (1974), 223 - 246.
! 1474:
! 1475: (ADAPTED IMPLEMENTATION OF ALGORITHM 'GS' IN THE ABOVE PAPER)
! 1476:
! 1477: **********************************************************************
! 1478: INPUT: A =PARAMETER (MEAN) OF THE STANDARD GAMMA DISTRIBUTION
! 1479: OUTPUT: SGAMMA = SAMPLE FROM THE GAMMA-(A)-DISTRIBUTION
! 1480: COEFFICIENTS Q(K) - FOR Q0 = SUM(Q(K)*A**(-K))
! 1481: COEFFICIENTS A(K) - FOR Q = Q0+(T*T/2)*SUM(A(K)*V**K)
! 1482: COEFFICIENTS E(K) - FOR EXP(Q)-1 = SUM(E(K)*Q**K)
! 1483: PREVIOUS A PRE-SET TO ZERO - AA IS A', AAA IS A"
! 1484: SQRT32 IS THE SQUAREROOT OF 32 = 5.656854249492380
! 1485: */
! 1486: {
! 1487: extern float fsign( float num, float sign );
! 1488: static float q1 = 4.166669E-2;
! 1489: static float q2 = 2.083148E-2;
! 1490: static float q3 = 8.01191E-3;
! 1491: static float q4 = 1.44121E-3;
! 1492: static float q5 = -7.388E-5;
! 1493: static float q6 = 2.4511E-4;
! 1494: static float q7 = 2.424E-4;
! 1495: static float a1 = 0.3333333;
! 1496: static float a2 = -0.250003;
! 1497: static float a3 = 0.2000062;
! 1498: static float a4 = -0.1662921;
! 1499: static float a5 = 0.1423657;
! 1500: static float a6 = -0.1367177;
! 1501: static float a7 = 0.1233795;
! 1502: static float e1 = 1.0;
! 1503: static float e2 = 0.4999897;
! 1504: static float e3 = 0.166829;
! 1505: static float e4 = 4.07753E-2;
! 1506: static float e5 = 1.0293E-2;
! 1507: static float aa = 0.0;
! 1508: static float aaa = 0.0;
! 1509: static float sqrt32 = 5.656854;
! 1510: static float sgamma,s2,s,d,t,x,u,r,q0,b,si,c,v,q,e,w,p;
! 1511: if(a == aa) goto S10;
! 1512: if(a < 1.0) goto S120;
! 1513: /*
! 1514: STEP 1: RECALCULATIONS OF S2,S,D IF A HAS CHANGED
! 1515: */
! 1516: aa = a;
! 1517: s2 = a-0.5;
! 1518: s = sqrt(s2);
! 1519: d = sqrt32-12.0*s;
! 1520: S10:
! 1521: /*
! 1522: STEP 2: T=STANDARD NORMAL DEVIATE,
! 1523: X=(S,1/2)-NORMAL DEVIATE.
! 1524: IMMEDIATE ACCEPTANCE (I)
! 1525: */
! 1526: t = snorm();
! 1527: x = s+0.5*t;
! 1528: sgamma = x*x;
! 1529: if(t >= 0.0) return sgamma;
! 1530: /*
! 1531: STEP 3: U= 0,1 -UNIFORM SAMPLE. SQUEEZE ACCEPTANCE (S)
! 1532: */
! 1533: u = ranf();
! 1534: if(d*u <= t*t*t) return sgamma;
! 1535: /*
! 1536: STEP 4: RECALCULATIONS OF Q0,B,SI,C IF NECESSARY
! 1537: */
! 1538: if(a == aaa) goto S40;
! 1539: aaa = a;
! 1540: r = 1.0/ a;
! 1541: q0 = ((((((q7*r+q6)*r+q5)*r+q4)*r+q3)*r+q2)*r+q1)*r;
! 1542: /*
! 1543: APPROXIMATION DEPENDING ON SIZE OF PARAMETER A
! 1544: THE CONSTANTS IN THE EXPRESSIONS FOR B, SI AND
! 1545: C WERE ESTABLISHED BY NUMERICAL EXPERIMENTS
! 1546: */
! 1547: if(a <= 3.686) goto S30;
! 1548: if(a <= 13.022) goto S20;
! 1549: /*
! 1550: CASE 3: A .GT. 13.022
! 1551: */
! 1552: b = 1.77;
! 1553: si = 0.75;
! 1554: c = 0.1515/s;
! 1555: goto S40;
! 1556: S20:
! 1557: /*
! 1558: CASE 2: 3.686 .LT. A .LE. 13.022
! 1559: */
! 1560: b = 1.654+7.6E-3*s2;
! 1561: si = 1.68/s+0.275;
! 1562: c = 6.2E-2/s+2.4E-2;
! 1563: goto S40;
! 1564: S30:
! 1565: /*
! 1566: CASE 1: A .LE. 3.686
! 1567: */
! 1568: b = 0.463+s-0.178*s2;
! 1569: si = 1.235;
! 1570: c = 0.195/s-7.9E-2+1.6E-2*s;
! 1571: S40:
! 1572: /*
! 1573: STEP 5: NO QUOTIENT TEST IF X NOT POSITIVE
! 1574: */
! 1575: if(x <= 0.0) goto S70;
! 1576: /*
! 1577: STEP 6: CALCULATION OF V AND QUOTIENT Q
! 1578: */
! 1579: v = t/(s+s);
! 1580: if(fabs(v) <= 0.25) goto S50;
! 1581: q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v);
! 1582: goto S60;
! 1583: S50:
! 1584: q = q0+0.5*t*t*((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v;
! 1585: S60:
! 1586: /*
! 1587: STEP 7: QUOTIENT ACCEPTANCE (Q)
! 1588: */
! 1589: if(log(1.0-u) <= q) return sgamma;
! 1590: S70:
! 1591: /*
! 1592: STEP 8: E=STANDARD EXPONENTIAL DEVIATE
! 1593: U= 0,1 -UNIFORM DEVIATE
! 1594: T=(B,SI)-DOUBLE EXPONENTIAL (LAPLACE) SAMPLE
! 1595: */
! 1596: e = sexpo();
! 1597: u = ranf();
! 1598: u += (u-1.0);
! 1599: t = b+fsign(si*e,u);
! 1600: /*
! 1601: STEP 9: REJECTION IF T .LT. TAU(1) = -.71874483771719
! 1602: */
! 1603: if(t < -0.7187449) goto S70;
! 1604: /*
! 1605: STEP 10: CALCULATION OF V AND QUOTIENT Q
! 1606: */
! 1607: v = t/(s+s);
! 1608: if(fabs(v) <= 0.25) goto S80;
! 1609: q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v);
! 1610: goto S90;
! 1611: S80:
! 1612: q = q0+0.5*t*t*((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v;
! 1613: S90:
! 1614: /*
! 1615: STEP 11: HAT ACCEPTANCE (H) (IF Q NOT POSITIVE GO TO STEP 8)
! 1616: */
! 1617: if(q <= 0.0) goto S70;
! 1618: if(q <= 0.5) goto S100;
! 1619: w = exp(q)-1.0;
! 1620: goto S110;
! 1621: S100:
! 1622: w = ((((e5*q+e4)*q+e3)*q+e2)*q+e1)*q;
! 1623: S110:
! 1624: /*
! 1625: IF T IS REJECTED, SAMPLE AGAIN AT STEP 8
! 1626: */
! 1627: if(c*fabs(u) > w*exp(e-0.5*t*t)) goto S70;
! 1628: x = s+0.5*t;
! 1629: sgamma = x*x;
! 1630: return sgamma;
! 1631: S120:
! 1632: /*
! 1633: ALTERNATE METHOD FOR PARAMETERS A BELOW 1 (.3678794=EXP(-1.))
! 1634: */
! 1635: aa = 0.0;
! 1636: b = 1.0+0.3678794*a;
! 1637: S130:
! 1638: p = b*ranf();
! 1639: if(p >= 1.0) goto S140;
! 1640: sgamma = exp(log(p)/ a);
! 1641: if(sexpo() < sgamma) goto S130;
! 1642: return sgamma;
! 1643: S140:
! 1644: sgamma = -log((b-p)/ a);
! 1645: if(sexpo() < (1.0-a)*log(sgamma)) goto S130;
! 1646: return sgamma;
! 1647: }
! 1648: float snorm(void)
! 1649: /*
! 1650: **********************************************************************
! 1651:
! 1652:
! 1653: (STANDARD-) N O R M A L DISTRIBUTION
! 1654:
! 1655:
! 1656: **********************************************************************
! 1657: **********************************************************************
! 1658:
! 1659: FOR DETAILS SEE:
! 1660:
! 1661: AHRENS, J.H. AND DIETER, U.
! 1662: EXTENSIONS OF FORSYTHE'S METHOD FOR RANDOM
! 1663: SAMPLING FROM THE NORMAL DISTRIBUTION.
! 1664: MATH. COMPUT., 27,124 (OCT. 1973), 927 - 937.
! 1665:
! 1666: ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM 'FL'
! 1667: (M=5) IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION)
! 1668:
! 1669: Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of
! 1670: SUNIF. The argument IR thus goes away.
! 1671:
! 1672: **********************************************************************
! 1673: THE DEFINITIONS OF THE CONSTANTS A(K), D(K), T(K) AND
! 1674: H(K) ARE ACCORDING TO THE ABOVEMENTIONED ARTICLE
! 1675: */
! 1676: {
! 1677: static float a[32] = {
! 1678: 0.0,3.917609E-2,7.841241E-2,0.11777,0.1573107,0.1970991,0.2372021,0.2776904,
! 1679: 0.3186394,0.36013,0.4022501,0.4450965,0.4887764,0.5334097,0.5791322,
! 1680: 0.626099,0.6744898,0.7245144,0.7764218,0.8305109,0.8871466,0.9467818,
! 1681: 1.00999,1.077516,1.150349,1.229859,1.318011,1.417797,1.534121,1.67594,
! 1682: 1.862732,2.153875
! 1683: };
! 1684: static float d[31] = {
! 1685: 0.0,0.0,0.0,0.0,0.0,0.2636843,0.2425085,0.2255674,0.2116342,0.1999243,
! 1686: 0.1899108,0.1812252,0.1736014,0.1668419,0.1607967,0.1553497,0.1504094,
! 1687: 0.1459026,0.14177,0.1379632,0.1344418,0.1311722,0.128126,0.1252791,
! 1688: 0.1226109,0.1201036,0.1177417,0.1155119,0.1134023,0.1114027,0.1095039
! 1689: };
! 1690: static float t[31] = {
! 1691: 7.673828E-4,2.30687E-3,3.860618E-3,5.438454E-3,7.0507E-3,8.708396E-3,
! 1692: 1.042357E-2,1.220953E-2,1.408125E-2,1.605579E-2,1.81529E-2,2.039573E-2,
! 1693: 2.281177E-2,2.543407E-2,2.830296E-2,3.146822E-2,3.499233E-2,3.895483E-2,
! 1694: 4.345878E-2,4.864035E-2,5.468334E-2,6.184222E-2,7.047983E-2,8.113195E-2,
! 1695: 9.462444E-2,0.1123001,0.136498,0.1716886,0.2276241,0.330498,0.5847031
! 1696: };
! 1697: static float h[31] = {
! 1698: 3.920617E-2,3.932705E-2,3.951E-2,3.975703E-2,4.007093E-2,4.045533E-2,
! 1699: 4.091481E-2,4.145507E-2,4.208311E-2,4.280748E-2,4.363863E-2,4.458932E-2,
! 1700: 4.567523E-2,4.691571E-2,4.833487E-2,4.996298E-2,5.183859E-2,5.401138E-2,
! 1701: 5.654656E-2,5.95313E-2,6.308489E-2,6.737503E-2,7.264544E-2,7.926471E-2,
! 1702: 8.781922E-2,9.930398E-2,0.11556,0.1404344,0.1836142,0.2790016,0.7010474
! 1703: };
! 1704: static long i;
! 1705: static float snorm,u,s,ustar,aa,w,y,tt;
! 1706: u = ranf();
! 1707: s = 0.0;
! 1708: if(u > 0.5) s = 1.0;
! 1709: u += (u-s);
! 1710: u = 32.0*u;
! 1711: i = (long) (u);
! 1712: if(i == 32) i = 31;
! 1713: if(i == 0) goto S100;
! 1714: /*
! 1715: START CENTER
! 1716: */
! 1717: ustar = u-(float)i;
! 1718: aa = *(a+i-1);
! 1719: S40:
! 1720: if(ustar <= *(t+i-1)) goto S60;
! 1721: w = (ustar-*(t+i-1))**(h+i-1);
! 1722: S50:
! 1723: /*
! 1724: EXIT (BOTH CASES)
! 1725: */
! 1726: y = aa+w;
! 1727: snorm = y;
! 1728: if(s == 1.0) snorm = -y;
! 1729: return snorm;
! 1730: S60:
! 1731: /*
! 1732: CENTER CONTINUED
! 1733: */
! 1734: u = ranf();
! 1735: w = u*(*(a+i)-aa);
! 1736: tt = (0.5*w+aa)*w;
! 1737: goto S80;
! 1738: S70:
! 1739: tt = u;
! 1740: ustar = ranf();
! 1741: S80:
! 1742: if(ustar > tt) goto S50;
! 1743: u = ranf();
! 1744: if(ustar >= u) goto S70;
! 1745: ustar = ranf();
! 1746: goto S40;
! 1747: S100:
! 1748: /*
! 1749: START TAIL
! 1750: */
! 1751: i = 6;
! 1752: aa = *(a+31);
! 1753: goto S120;
! 1754: S110:
! 1755: aa += *(d+i-1);
! 1756: i += 1;
! 1757: S120:
! 1758: u += u;
! 1759: if(u < 1.0) goto S110;
! 1760: u -= 1.0;
! 1761: S140:
! 1762: w = u**(d+i-1);
! 1763: tt = (0.5*w+aa)*w;
! 1764: goto S160;
! 1765: S150:
! 1766: tt = u;
! 1767: S160:
! 1768: ustar = ranf();
! 1769: if(ustar > tt) goto S50;
! 1770: u = ranf();
! 1771: if(ustar >= u) goto S150;
! 1772: u = ranf();
! 1773: goto S140;
! 1774: }
! 1775: float fsign( float num, float sign )
! 1776: /* Transfers sign of argument sign to argument num */
! 1777: {
! 1778: if ( ( sign>0.0f && num<0.0f ) || ( sign<0.0f && num>0.0f ) )
! 1779: return -num;
! 1780: else return num;
! 1781: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>