Annotation of capa/capa51/pProj/ranlib.c, revision 1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>