00001 REAL FUNCTION sgamma(a) 00002 C**********************************************************************C 00003 C C 00004 C C 00005 C (STANDARD-) G A M M A DISTRIBUTION C 00006 C C 00007 C C 00008 C**********************************************************************C 00009 C**********************************************************************C 00010 C C 00011 C PARAMETER A >= 1.0 ! C 00012 C C 00013 C**********************************************************************C 00014 C C 00015 C FOR DETAILS SEE: C 00016 C C 00017 C AHRENS, J.H. AND DIETER, U. C 00018 C GENERATING GAMMA VARIATES BY A C 00019 C MODIFIED REJECTION TECHNIQUE. C 00020 C COMM. ACM, 25,1 (JAN. 1982), 47 - 54. C 00021 C C 00022 C STEP NUMBERS CORRESPOND TO ALGORITHM 'GD' IN THE ABOVE PAPER C 00023 C (STRAIGHTFORWARD IMPLEMENTATION) C 00024 C C 00025 C Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of C 00026 C SUNIF. The argument IR thus goes away. C 00027 C C 00028 C**********************************************************************C 00029 C C 00030 C PARAMETER 0.0 < A < 1.0 ! C 00031 C C 00032 C**********************************************************************C 00033 C C 00034 C FOR DETAILS SEE: C 00035 C C 00036 C AHRENS, J.H. AND DIETER, U. C 00037 C COMPUTER METHODS FOR SAMPLING FROM GAMMA, C 00038 C BETA, POISSON AND BINOMIAL DISTRIBUTIONS. C 00039 C COMPUTING, 12 (1974), 223 - 246. C 00040 C C 00041 C (ADAPTED IMPLEMENTATION OF ALGORITHM 'GS' IN THE ABOVE PAPER) C 00042 C C 00043 C**********************************************************************C 00044 C 00045 C 00046 C INPUT: A =PARAMETER (MEAN) OF THE STANDARD GAMMA DISTRIBUTION 00047 C OUTPUT: SGAMMA = SAMPLE FROM THE GAMMA-(A)-DISTRIBUTION 00048 C 00049 C COEFFICIENTS Q(K) - FOR Q0 = SUM(Q(K)*A**(-K)) 00050 C COEFFICIENTS A(K) - FOR Q = Q0+(T*T/2)*SUM(A(K)*V**K) 00051 C COEFFICIENTS E(K) - FOR EXP(Q)-1 = SUM(E(K)*Q**K) 00052 C 00053 C .. Scalar Arguments .. 00054 REAL a 00055 C .. 00056 C .. Local Scalars .. (JJV added B0 to fix rare and subtle bug) 00057 REAL a1,a2,a3,a4,a5,a6,a7,aa,aaa,b,b0,c,d,e,e1,e2,e3,e4,e5,p,q,q0, 00058 + q1,q2,q3,q4,q5,q6,q7,r,s,s2,si,sqrt32,t,u,v,w,x 00059 C .. 00060 C .. External Functions .. 00061 REAL ranf,sexpo,snorm 00062 EXTERNAL ranf,sexpo,snorm 00063 C .. 00064 C .. Intrinsic Functions .. 00065 INTRINSIC abs,alog,exp,sign,sqrt 00066 C .. 00067 C .. Save statement .. 00068 C JJV added Save statement for vars in Data satatements 00069 SAVE aa,aaa,s2,s,d,q0,b,si,c,q1,q2,q3,q4,q5,q6,q7,a1,a2,a3,a4,a5, 00070 + a6,a7,e1,e2,e3,e4,e5,sqrt32 00071 C .. 00072 C .. Data statements .. 00073 C 00074 C PREVIOUS A PRE-SET TO ZERO - AA IS A', AAA IS A" 00075 C SQRT32 IS THE SQUAREROOT OF 32 = 5.656854249492380 00076 C 00077 DATA q1,q2,q3,q4,q5,q6,q7/.04166669,.02083148,.00801191,.00144121, 00078 + -.00007388,.00024511,.00024240/ 00079 DATA a1,a2,a3,a4,a5,a6,a7/.3333333,-.2500030,.2000062,-.1662921, 00080 + .1423657,-.1367177,.1233795/ 00081 DATA e1,e2,e3,e4,e5/1.,.4999897,.1668290,.0407753,.0102930/ 00082 DATA aa/0.0/,aaa/0.0/,sqrt32/5.656854/ 00083 C .. 00084 C .. Executable Statements .. 00085 C 00086 IF (a.EQ.aa) GO TO 10 00087 IF (a.LT.1.0) GO TO 130 00088 C 00089 C STEP 1: RECALCULATIONS OF S2,S,D IF A HAS CHANGED 00090 C 00091 aa = a 00092 s2 = a - 0.5 00093 s = sqrt(s2) 00094 d = sqrt32 - 12.0*s 00095 C 00096 C STEP 2: T=STANDARD NORMAL DEVIATE, 00097 C X=(S,1/2)-NORMAL DEVIATE. 00098 C IMMEDIATE ACCEPTANCE (I) 00099 C 00100 10 t = snorm() 00101 x = s + 0.5*t 00102 sgamma = x*x 00103 IF (t.GE.0.0) RETURN 00104 C 00105 C STEP 3: U= 0,1 -UNIFORM SAMPLE. SQUEEZE ACCEPTANCE (S) 00106 C 00107 u = ranf() 00108 IF (d*u.LE.t*t*t) RETURN 00109 C 00110 C STEP 4: RECALCULATIONS OF Q0,B,SI,C IF NECESSARY 00111 C 00112 IF (a.EQ.aaa) GO TO 40 00113 aaa = a 00114 r = 1.0/a 00115 q0 = ((((((q7*r+q6)*r+q5)*r+q4)*r+q3)*r+q2)*r+q1)*r 00116 C 00117 C APPROXIMATION DEPENDING ON SIZE OF PARAMETER A 00118 C THE CONSTANTS IN THE EXPRESSIONS FOR B, SI AND 00119 C C WERE ESTABLISHED BY NUMERICAL EXPERIMENTS 00120 C 00121 IF (a.LE.3.686) GO TO 30 00122 IF (a.LE.13.022) GO TO 20 00123 C 00124 C CASE 3: A .GT. 13.022 00125 C 00126 b = 1.77 00127 si = .75 00128 c = .1515/s 00129 GO TO 40 00130 C 00131 C CASE 2: 3.686 .LT. A .LE. 13.022 00132 C 00133 20 b = 1.654 + .0076*s2 00134 si = 1.68/s + .275 00135 c = .062/s + .024 00136 GO TO 40 00137 C 00138 C CASE 1: A .LE. 3.686 00139 C 00140 30 b = .463 + s + .178*s2 00141 si = 1.235 00142 c = .195/s - .079 + .16*s 00143 C 00144 C STEP 5: NO QUOTIENT TEST IF X NOT POSITIVE 00145 C 00146 40 IF (x.LE.0.0) GO TO 70 00147 C 00148 C STEP 6: CALCULATION OF V AND QUOTIENT Q 00149 C 00150 v = t/ (s+s) 00151 IF (abs(v).LE.0.25) GO TO 50 00152 q = q0 - s*t + 0.25*t*t + (s2+s2)*alog(1.0+v) 00153 GO TO 60 00154 00155 50 q = q0 + 0.5*t*t* ((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v 00156 C 00157 C STEP 7: QUOTIENT ACCEPTANCE (Q) 00158 C 00159 60 IF (alog(1.0-u).LE.q) RETURN 00160 C 00161 C STEP 8: E=STANDARD EXPONENTIAL DEVIATE 00162 C U= 0,1 -UNIFORM DEVIATE 00163 C T=(B,SI)-DOUBLE EXPONENTIAL (LAPLACE) SAMPLE 00164 C 00165 70 e = sexpo() 00166 u = ranf() 00167 u = u + u - 1.0 00168 t = b + sign(si*e,u) 00169 C 00170 C STEP 9: REJECTION IF T .LT. TAU(1) = -.71874483771719 00171 C 00172 80 IF (t.LT. (-.7187449)) GO TO 70 00173 C 00174 C STEP 10: CALCULATION OF V AND QUOTIENT Q 00175 C 00176 v = t/ (s+s) 00177 IF (abs(v).LE.0.25) GO TO 90 00178 q = q0 - s*t + 0.25*t*t + (s2+s2)*alog(1.0+v) 00179 GO TO 100 00180 00181 90 q = q0 + 0.5*t*t* ((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v 00182 C 00183 C STEP 11: HAT ACCEPTANCE (H) (IF Q NOT POSITIVE GO TO STEP 8) 00184 C 00185 100 IF (q.LE.0.0) GO TO 70 00186 IF (q.LE.0.5) GO TO 110 00187 C 00188 C JJV modified the code through line 125 to handle large Q case 00189 C 00190 IF (q.LT.15.0) GO TO 105 00191 C 00192 C JJV Here Q is large enough that Q = log(exp(Q) - 1.0) (for real Q) 00193 C JJV so reformulate test at 120 in terms of one EXP, if not too big 00194 C JJV 87.49823 is close to the largest real which can be 00195 C JJV exponentiated (87.49823 = log(1.0E38)) 00196 C 00197 IF ((q+e-0.5*t*t).GT.87.49823) GO TO 125 00198 IF (c*abs(u).GT.exp(q+e-0.5*t*t)) GO TO 70 00199 GO TO 125 00200 00201 105 w = exp(q) - 1.0 00202 GO TO 120 00203 00204 110 w = ((((e5*q+e4)*q+e3)*q+e2)*q+e1)*q 00205 C 00206 C IF T IS REJECTED, SAMPLE AGAIN AT STEP 8 00207 C 00208 120 IF (c*abs(u).GT.w*exp(e-0.5*t*t)) GO TO 70 00209 125 x = s + 0.5*t 00210 sgamma = x*x 00211 RETURN 00212 C 00213 C ALTERNATE METHOD FOR PARAMETERS A BELOW 1 (.3678794=EXP(-1.)) 00214 C 00215 C JJV changed B to B0 (which was added to declarations for this) 00216 C JJV in 130 to END to fix rare and subtle bug. 00217 C JJV Line: '130 aa = 0.0' was removed (unnecessary, wasteful). 00218 C JJV Reasons: the state of AA only serves to tell the A .GE. 1.0 00219 C JJV case if certain A-dependant constants need to be recalculated. 00220 C JJV The A .LT. 1.0 case (here) no longer changes any of these, and 00221 C JJV the recalculation of B (which used to change with an 00222 C JJV A .LT. 1.0 call) is governed by the state of AAA anyway. 00223 C 00224 130 b0 = 1.0 + .3678794*a 00225 140 p = b0*ranf() 00226 IF (p.GE.1.0) GO TO 150 00227 sgamma = exp(alog(p)/a) 00228 IF (sexpo().LT.sgamma) GO TO 140 00229 RETURN 00230 00231 150 sgamma = -alog((b0-p)/a) 00232 IF (sexpo().LT. (1.0-a)*alog(sgamma)) GO TO 140 00233 RETURN 00234 00235 END