ignbin.f

Go to the documentation of this file.
00001       INTEGER FUNCTION ignbin(n,pp)
00002 C**********************************************************************
00003 C
00004 C     INTEGER FUNCTION IGNBIN( N, PP )
00005 C
00006 C                    GENerate BINomial random deviate
00007 C
00008 C
00009 C                              Function
00010 C
00011 C
00012 C     Generates a single random deviate from a binomial
00013 C     distribution whose number of trials is N and whose
00014 C     probability of an event in each trial is P.
00015 C
00016 C
00017 C                              Arguments
00018 C
00019 C
00020 C     N  --> The number of trials in the binomial distribution
00021 C            from which a random deviate is to be generated.
00022 C                              INTEGER N
00023 C     JJV                      (N >= 0)
00024 C
00025 C     PP --> The probability of an event in each trial of the
00026 C            binomial distribution from which a random deviate
00027 C            is to be generated.
00028 C                              REAL PP
00029 C     JJV                      (0.0 <= pp <= 1.0)
00030 C
00031 C     IGNBIN <-- A random deviate yielding the number of events
00032 C                from N independent trials, each of which has
00033 C                a probability of event P.
00034 C                              INTEGER IGNBIN
00035 C
00036 C
00037 C                              Note
00038 C
00039 C
00040 C     Uses RANF so the value of the seeds, ISEED1 and ISEED2 must be set
00041 C     by a call similar to the following
00042 C          DUM = RANSET( ISEED1, ISEED2 )
00043 C
00044 C
00045 C                              Method
00046 C
00047 C
00048 C     This is algorithm BTPE from:
00049 C
00050 C         Kachitvichyanukul, V. and Schmeiser, B. W.
00051 C
00052 C         Binomial Random Variate Generation.
00053 C         Communications of the ACM, 31, 2
00054 C         (February, 1988) 216.
00055 C
00056 C**********************************************************************
00057 C     SUBROUTINE BTPEC(N,PP,ISEED,JX)
00058 C
00059 C     BINOMIAL RANDOM VARIATE GENERATOR
00060 C     MEAN .LT. 30 -- INVERSE CDF
00061 C       MEAN .GE. 30 -- ALGORITHM BTPE:  ACCEPTANCE-REJECTION VIA
00062 C       FOUR REGION COMPOSITION.  THE FOUR REGIONS ARE A TRIANGLE
00063 C       (SYMMETRIC IN THE CENTER), A PAIR OF PARALLELOGRAMS (ABOVE
00064 C       THE TRIANGLE), AND EXPONENTIAL LEFT AND RIGHT TAILS.
00065 C
00066 C     BTPE REFERS TO BINOMIAL-TRIANGLE-PARALLELOGRAM-EXPONENTIAL.
00067 C     BTPEC REFERS TO BTPE AND "COMBINED."  THUS BTPE IS THE
00068 C       RESEARCH AND BTPEC IS THE IMPLEMENTATION OF A COMPLETE
00069 C       USABLE ALGORITHM.
00070 C     REFERENCE:  VORATAS KACHITVICHYANUKUL AND BRUCE SCHMEISER,
00071 C       "BINOMIAL RANDOM VARIATE GENERATION,"
00072 C       COMMUNICATIONS OF THE ACM, FORTHCOMING
00073 C     WRITTEN:  SEPTEMBER 1980.
00074 C       LAST REVISED:  MAY 1985, JULY 1987
00075 C     REQUIRED SUBPROGRAM:  RAND() -- A UNIFORM (0,1) RANDOM NUMBER
00076 C                           GENERATOR
00077 C     ARGUMENTS
00078 C
00079 C       N : NUMBER OF BERNOULLI TRIALS            (INPUT)
00080 C       PP : PROBABILITY OF SUCCESS IN EACH TRIAL (INPUT)
00081 C       ISEED:  RANDOM NUMBER SEED                (INPUT AND OUTPUT)
00082 C       JX:  RANDOMLY GENERATED OBSERVATION       (OUTPUT)
00083 C
00084 C     VARIABLES
00085 C       PSAVE: VALUE OF PP FROM THE LAST CALL TO BTPEC
00086 C       NSAVE: VALUE OF N FROM THE LAST CALL TO BTPEC
00087 C       XNP:  VALUE OF THE MEAN FROM THE LAST CALL TO BTPEC
00088 C
00089 C       P: PROBABILITY USED IN THE GENERATION PHASE OF BTPEC
00090 C       FFM: TEMPORARY VARIABLE EQUAL TO XNP + P
00091 C       M:  INTEGER VALUE OF THE CURRENT MODE
00092 C       FM:  FLOATING POINT VALUE OF THE CURRENT MODE
00093 C       XNPQ: TEMPORARY VARIABLE USED IN SETUP AND SQUEEZING STEPS
00094 C       P1:  AREA OF THE TRIANGLE
00095 C       C:  HEIGHT OF THE PARALLELOGRAMS
00096 C       XM:  CENTER OF THE TRIANGLE
00097 C       XL:  LEFT END OF THE TRIANGLE
00098 C       XR:  RIGHT END OF THE TRIANGLE
00099 C       AL:  TEMPORARY VARIABLE
00100 C       XLL:  RATE FOR THE LEFT EXPONENTIAL TAIL
00101 C       XLR:  RATE FOR THE RIGHT EXPONENTIAL TAIL
00102 C       P2:  AREA OF THE PARALLELOGRAMS
00103 C       P3:  AREA OF THE LEFT EXPONENTIAL TAIL
00104 C       P4:  AREA OF THE RIGHT EXPONENTIAL TAIL
00105 C       U:  A U(0,P4) RANDOM VARIATE USED FIRST TO SELECT ONE OF THE
00106 C           FOUR REGIONS AND THEN CONDITIONALLY TO GENERATE A VALUE
00107 C           FROM THE REGION
00108 C       V:  A U(0,1) RANDOM NUMBER USED TO GENERATE THE RANDOM VALUE
00109 C           (REGION 1) OR TRANSFORMED INTO THE VARIATE TO ACCEPT OR
00110 C           REJECT THE CANDIDATE VALUE
00111 C       IX:  INTEGER CANDIDATE VALUE
00112 C       X:  PRELIMINARY CONTINUOUS CANDIDATE VALUE IN REGION 2 LOGIC
00113 C           AND A FLOATING POINT IX IN THE ACCEPT/REJECT LOGIC
00114 C       K:  ABSOLUTE VALUE OF (IX-M)
00115 C       F:  THE HEIGHT OF THE SCALED DENSITY FUNCTION USED IN THE
00116 C           ACCEPT/REJECT DECISION WHEN BOTH M AND IX ARE SMALL
00117 C           ALSO USED IN THE INVERSE TRANSFORMATION
00118 C       R: THE RATIO P/Q
00119 C       G: CONSTANT USED IN CALCULATION OF PROBABILITY
00120 C       MP:  MODE PLUS ONE, THE LOWER INDEX FOR EXPLICIT CALCULATION
00121 C            OF F WHEN IX IS GREATER THAN M
00122 C       IX1:  CANDIDATE VALUE PLUS ONE, THE LOWER INDEX FOR EXPLICIT
00123 C             CALCULATION OF F WHEN IX IS LESS THAN M
00124 C       I:  INDEX FOR EXPLICIT CALCULATION OF F FOR BTPE
00125 C       AMAXP: MAXIMUM ERROR OF THE LOGARITHM OF NORMAL BOUND
00126 C       YNORM: LOGARITHM OF NORMAL BOUND
00127 C       ALV:  NATURAL LOGARITHM OF THE ACCEPT/REJECT VARIATE V
00128 C
00129 C       X1,F1,Z,W,Z2,X2,F2, AND W2 ARE TEMPORARY VARIABLES TO BE
00130 C       USED IN THE FINAL ACCEPT/REJECT TEST
00131 C
00132 C       QN: PROBABILITY OF NO SUCCESS IN N TRIALS
00133 C
00134 C     REMARK
00135 C       IX AND JX COULD LOGICALLY BE THE SAME VARIABLE, WHICH WOULD
00136 C       SAVE A MEMORY POSITION AND A LINE OF CODE.  HOWEVER, SOME
00137 C       COMPILERS (E.G.,CDC MNF) OPTIMIZE BETTER WHEN THE ARGUMENTS
00138 C       ARE NOT INVOLVED.
00139 C
00140 C     ISEED NEEDS TO BE DOUBLE PRECISION IF THE IMSL ROUTINE
00141 C     GGUBFS IS USED TO GENERATE UNIFORM RANDOM NUMBER, OTHERWISE
00142 C     TYPE OF ISEED SHOULD BE DICTATED BY THE UNIFORM GENERATOR
00143 C
00144 C**********************************************************************
00145 
00146 C
00147 C
00148 C
00149 C*****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY
00150 C
00151 C     ..
00152 C     .. Scalar Arguments ..
00153       REAL pp
00154       INTEGER n
00155 C     ..
00156 C     .. Local Scalars ..
00157       REAL al,alv,amaxp,c,f,f1,f2,ffm,fm,g,p,p1,p2,p3,p4,psave,q,qn,r,u,
00158      +     v,w,w2,x,x1,x2,xl,xll,xlr,xm,xnp,xnpq,xr,ynorm,z,z2
00159       INTEGER i,ix,ix1,k,m,mp,nsave
00160 C     ..
00161 C     .. External Functions ..
00162       REAL ranf
00163       EXTERNAL ranf
00164 C     ..
00165 C     .. Intrinsic Functions ..
00166       INTRINSIC abs,alog,amin1,iabs,int,sqrt
00167 C     JJV ..
00168 C     JJV .. Save statement ..
00169       SAVE p,q,m,fm,xnp,xnpq,p1,xm,xl,xr,c,xll,xlr,p2,p3,p4,qn,r,g,
00170      +     psave,nsave
00171 C     JJV I am including the variables in data statements
00172 C     ..
00173 C     .. Data statements ..
00174 C     JJV made these ridiculous starting values - the hope is that
00175 C     JJV no one will call this the first time with them as args
00176       DATA psave,nsave/-1.0E37,-214748365/
00177 C     ..
00178 C     .. Executable Statements ..
00179       IF (pp.NE.psave) GO TO 10
00180       IF (n.NE.nsave) GO TO 20
00181       IF (xnp-30.0.LT.0.0) GO TO 150
00182       GO TO 30
00183 C
00184 C*****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE
00185 C
00186 
00187 C     JJV added the argument checker - involved only renaming 10
00188 C     JJV and 20 to the checkers and adding checkers
00189 C     JJV Only remaining problem - if called initially with the
00190 C     JJV initial values of psave and nsave, it will hang
00191  10   IF (pp.LT.0.0) CALL XSTOPX ('PP < 0.0 in IGNBIN - ABORT!')
00192       IF (pp.GT.1.0) CALL XSTOPX ('PP > 1.0 in IGNBIN - ABORT!')
00193       psave = pp
00194       p = amin1(psave,1.-psave)
00195       q = 1. - p
00196  20   IF (n.LT.0) CALL XSTOPX ('N < 0 in IGNBIN - ABORT!')
00197       xnp = n*p
00198       nsave = n
00199       IF (xnp.LT.30.) GO TO 140
00200       ffm = xnp + p
00201       m = ffm
00202       fm = m
00203       xnpq = xnp*q
00204       p1 = int(2.195*sqrt(xnpq)-4.6*q) + 0.5
00205       xm = fm + 0.5
00206       xl = xm - p1
00207       xr = xm + p1
00208       c = 0.134 + 20.5/ (15.3+fm)
00209       al = (ffm-xl)/ (ffm-xl*p)
00210       xll = al* (1.+.5*al)
00211       al = (xr-ffm)/ (xr*q)
00212       xlr = al* (1.+.5*al)
00213       p2 = p1* (1.+c+c)
00214       p3 = p2 + c/xll
00215       p4 = p3 + c/xlr
00216 C      WRITE(6,100) N,P,P1,P2,P3,P4,XL,XR,XM,FM
00217 C  100 FORMAT(I15,4F18.7/5F18.7)
00218 C
00219 C*****GENERATE VARIATE
00220 C
00221    30 u = ranf()*p4
00222       v = ranf()
00223 C
00224 C     TRIANGULAR REGION
00225 C
00226       IF (u.GT.p1) GO TO 40
00227       ix = xm - p1*v + u
00228       GO TO 170
00229 C
00230 C     PARALLELOGRAM REGION
00231 C
00232    40 IF (u.GT.p2) GO TO 50
00233       x = xl + (u-p1)/c
00234       v = v*c + 1. - abs(xm-x)/p1
00235       IF (v.GT.1. .OR. v.LE.0.) GO TO 30
00236       ix = x
00237       GO TO 70
00238 C
00239 C     LEFT TAIL
00240 C
00241    50 IF (u.GT.p3) GO TO 60
00242       ix = xl + alog(v)/xll
00243       IF (ix.LT.0) GO TO 30
00244       v = v* (u-p2)*xll
00245       GO TO 70
00246 C
00247 C     RIGHT TAIL
00248 C
00249    60 ix = xr - alog(v)/xlr
00250       IF (ix.GT.n) GO TO 30
00251       v = v* (u-p3)*xlr
00252 C
00253 C*****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST
00254 C
00255    70 k = iabs(ix-m)
00256       IF (k.GT.20 .AND. k.LT.xnpq/2-1) GO TO 130
00257 C
00258 C     EXPLICIT EVALUATION
00259 C
00260       f = 1.0
00261       r = p/q
00262       g = (n+1)*r
00263       IF (m-ix.LT.0) GO TO 80
00264       IF (m-ix.EQ.0) GO TO 120
00265       GO TO 100
00266    80 mp = m + 1
00267       DO 90 i = mp,ix
00268           f = f* (g/i-r)
00269    90 CONTINUE
00270       GO TO 120
00271 
00272   100 ix1 = ix + 1
00273       DO 110 i = ix1,m
00274           f = f/ (g/i-r)
00275   110 CONTINUE
00276   120 IF (v-f.LE.0) GO TO 170
00277       GO TO 30
00278 C
00279 C     SQUEEZING USING UPPER AND LOWER BOUNDS ON ALOG(F(X))
00280 C
00281   130 amaxp = (k/xnpq)* ((k* (k/3.+.625)+.1666666666666)/xnpq+.5)
00282       ynorm = -k*k/ (2.*xnpq)
00283       alv = alog(v)
00284       IF (alv.LT.ynorm-amaxp) GO TO 170
00285       IF (alv.GT.ynorm+amaxp) GO TO 30
00286 C
00287 C     STIRLING'S FORMULA TO MACHINE ACCURACY FOR
00288 C     THE FINAL ACCEPTANCE/REJECTION TEST
00289 C
00290       x1 = ix + 1
00291       f1 = fm + 1.
00292       z = n + 1 - fm
00293       w = n - ix + 1.
00294       z2 = z*z
00295       x2 = x1*x1
00296       f2 = f1*f1
00297       w2 = w*w
00298       IF (alv- (xm*alog(f1/x1)+ (n-m+.5)*alog(z/w)+ (ix-
00299      +    m)*alog(w*p/ (x1*q))+ (13860.- (462.- (132.- (99.-
00300      +    140./f2)/f2)/f2)/f2)/f1/166320.+ (13860.- (462.- (132.- (99.-
00301      +    140./z2)/z2)/z2)/z2)/z/166320.+ (13860.- (462.- (132.- (99.-
00302      +    140./x2)/x2)/x2)/x2)/x1/166320.+ (13860.- (462.- (132.- (99.-
00303      +    140./w2)/w2)/w2)/w2)/w/166320.) .LE. 0.) GO TO 170
00304       GO TO 30
00305 C
00306 C     INVERSE CDF LOGIC FOR MEAN LESS THAN 30
00307 C
00308   140 qn = q**n
00309       r = p/q
00310       g = r* (n+1)
00311   150 ix = 0
00312       f = qn
00313       u = ranf()
00314   160 IF (u.LT.f) GO TO 170
00315       IF (ix.GT.110) GO TO 150
00316       u = u - f
00317       ix = ix + 1
00318       f = f* (g/ix-r)
00319       GO TO 160
00320 
00321   170 IF (psave.GT.0.5) ix = n - ix
00322       ignbin = ix
00323       RETURN
00324 
00325       END
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines