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>