GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ignpoi.f
Go to the documentation of this file.
1 INTEGER*4 FUNCTION ignpoi(mu)
2C**********************************************************************
3C
4C INTEGER*4 FUNCTION IGNPOI( MU )
5C
6C GENerate POIsson random deviate
7C
8C
9C Function
10C
11C
12C Generates a single random deviate from a Poisson
13C distribution with mean MU.
14C
15C
16C Arguments
17C
18C
19C MU --> The mean of the Poisson distribution from which
20C a random deviate is to be generated.
21C REAL MU
22C JJV (MU >= 0.0)
23C
24C IGNPOI <-- The random deviate.
25C INTEGER IGNPOI (non-negative)
26C
27C
28C Method
29C
30C
31C Renames KPOIS from TOMS as slightly modified by BWB to use RANF
32C instead of SUNIF.
33C
34C For details see:
35C
36C Ahrens, J.H. and Dieter, U.
37C Computer Generation of Poisson Deviates
38C From Modified Normal Distributions.
39C ACM Trans. Math. Software, 8, 2
40C (June 1982),163-179
41C
42C**********************************************************************
43C**********************************************************************C
44C**********************************************************************C
45C C
46C C
47C P O I S S O N DISTRIBUTION C
48C C
49C C
50C**********************************************************************C
51C**********************************************************************C
52C C
53C FOR DETAILS SEE: C
54C C
55C AHRENS, J.H. AND DIETER, U. C
56C COMPUTER GENERATION OF POISSON DEVIATES C
57C FROM MODIFIED NORMAL DISTRIBUTIONS. C
58C ACM TRANS. MATH. SOFTWARE, 8,2 (JUNE 1982), 163 - 179. C
59C C
60C (SLIGHTLY MODIFIED VERSION OF THE PROGRAM IN THE ABOVE ARTICLE) C
61C C
62C**********************************************************************C
63C
64C INTEGER*4 FUNCTION IGNPOI(IR,MU)
65C
66C INPUT: IR=CURRENT STATE OF BASIC RANDOM NUMBER GENERATOR
67C MU=MEAN MU OF THE POISSON DISTRIBUTION
68C OUTPUT: IGNPOI=SAMPLE FROM THE POISSON-(MU)-DISTRIBUTION
69C
70C
71C
72C MUPREV=PREVIOUS MU, MUOLD=MU AT LAST EXECUTION OF STEP P OR CASE B
73C TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT
74C COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL
75C
76C
77C
78C SEPARATION OF CASES A AND B
79C
80C .. Scalar Arguments ..
81 REAL mu
82C ..
83C .. Local Scalars ..
84 REAL a0,a1,a2,a3,a4,a5,a6,a7,b1,b2,c,c0,c1,c2,c3,d,del,difmuk,e,
85 + fk,fx,fy,g,muold,muprev,omega,p,p0,px,py,q,s,t,u,v,x,xx
86C JJV I added a variable 'll' here - it is the 'l' for CASE A
87 INTEGER*4 j,k,kflag,l,ll,m
88C ..
89C .. Local Arrays ..
90 REAL fact(10),pp(35)
91C ..
92C .. External Functions ..
93 REAL ranf,sexpo,snorm
94 EXTERNAL ranf,sexpo,snorm
95C ..
96C .. Intrinsic Functions ..
97 INTRINSIC abs,alog,exp,float,ifix,max0,min0,sign,sqrt
98C ..
99C JJV added this for case: mu unchanged
100C .. Save statement ..
101 SAVE s, d, l, ll, omega, c3, c2, c1, c0, c, m, p, q, p0,
102 + a0, a1, a2, a3, a4, a5, a6, a7, fact, pp, muprev, muold
103C ..
104C JJV end addition - I am including vars in Data statements
105C .. Data statements ..
106C JJV changed initial values of MUPREV and MUOLD to -1.0E37
107C JJV if no one calls IGNPOI with MU = -1.0E37 the first time,
108C JJV the code shouldn't break
109 DATA muprev,muold/-1.0e37,-1.0e37/
110 DATA a0,a1,a2,a3,a4,a5,a6,a7/-.5,.3333333,-.2500068,.2000118,
111 + -.1661269,.1421878,-.1384794,.1250060/
112 DATA fact/1.,1.,2.,6.,24.,120.,720.,5040.,40320.,362880./
113 DATA pp/35*0.0/
114C ..
115C .. Executable Statements ..
116
117 IF (mu.EQ.muprev) GO TO 10
118 IF (mu.LT.10.0) GO TO 120
119C
120C C A S E A. (RECALCULATION OF S,D,LL IF MU HAS CHANGED)
121C
122C JJV This is the case where I changed 'l' to 'll'
123C JJV Here 'll' is set once and used in a comparison once
124
125 muprev = mu
126 s = sqrt(mu)
127 d = 6.0*mu*mu
128C
129C THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL
130C PROBABILITIES FK WHENEVER K >= M(MU). LL=IFIX(MU-1.1484)
131C IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 .
132C
133 ll = ifix(mu-1.1484)
134C
135C STEP N. NORMAL SAMPLE - SNORM(IR) FOR STANDARD NORMAL DEVIATE
136C
137 10 g = mu + s*snorm()
138 IF (g.LT.0.0) GO TO 20
139 ignpoi = ifix(g)
140C
141C STEP I. IMMEDIATE ACCEPTANCE IF IGNPOI IS LARGE ENOUGH
142C
143 IF (ignpoi.GE.ll) RETURN
144C
145C STEP S. SQUEEZE ACCEPTANCE - SUNIF(IR) FOR (0,1)-SAMPLE U
146C
147 fk = float(ignpoi)
148 difmuk = mu - fk
149 u = ranf()
150 IF (d*u.GE.difmuk*difmuk*difmuk) RETURN
151C
152C STEP P. PREPARATIONS FOR STEPS Q AND H.
153C (RECALCULATIONS OF PARAMETERS IF NECESSARY)
154C .3989423=(2*PI)**(-.5) .416667E-1=1./24. .1428571=1./7.
155C THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE
156C APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK.
157C C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION.
158C
159 20 IF (mu.EQ.muold) GO TO 30
160 muold = mu
161 omega = .3989423/s
162 b1 = .4166667e-1/mu
163 b2 = .3*b1*b1
164 c3 = .1428571*b1*b2
165 c2 = b2 - 15.*c3
166 c1 = b1 - 6.*b2 + 45.*c3
167 c0 = 1. - b1 + 3.*b2 - 15.*c3
168 c = .1069/mu
169 30 IF (g.LT.0.0) GO TO 50
170C
171C 'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN)
172C
173 kflag = 0
174 GO TO 70
175C
176C STEP Q. QUOTIENT ACCEPTANCE (RARE CASE)
177C
178 40 IF (fy-u*fy.LE.py*exp(px-fx)) RETURN
179C
180C STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL
181C DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'
182C (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)
183C
184 50 e = sexpo()
185 u = ranf()
186 u = u + u - 1.0
187 t = 1.8 + sign(e,u)
188 IF (t.LE. (-.6744)) GO TO 50
189 ignpoi = ifix(mu+s*t)
190 fk = float(ignpoi)
191 difmuk = mu - fk
192C
193C 'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)
194C
195 kflag = 1
196 GO TO 70
197C
198C STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)
199C
200 60 IF (c*abs(u).GT.py*exp(px+e)-fy*exp(fx+e)) GO TO 50
201 RETURN
202C
203C STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY.
204C CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT
205C
206 70 IF (ignpoi.GE.10) GO TO 80
207 px = -mu
208 py = mu**ignpoi/fact(ignpoi+1)
209 GO TO 110
210C
211C CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION
212C A0-A7 FOR ACCURACY WHEN ADVISABLE
213C .8333333E-1=1./12. .3989423=(2*PI)**(-.5)
214C
215 80 del = .8333333e-1/fk
216 del = del - 4.8*del*del*del
217 v = difmuk/fk
218 IF (abs(v).LE.0.25) GO TO 90
219 px = fk*alog(1.0+v) - difmuk - del
220 GO TO 100
221
222 90 px = fk*v*v* (((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0) -
223 + del
224 100 py = .3989423/sqrt(fk)
225 110 x = (0.5-difmuk)/s
226 xx = x*x
227 fx = -0.5*xx
228 fy = omega* (((c3*xx+c2)*xx+c1)*xx+c0)
229 IF (kflag.LE.0) GO TO 40
230 GO TO 60
231C
232C C A S E B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY)
233C
234C JJV changed MUPREV assignment from 0.0 to initial value
235 120 muprev = -1.0e37
236 IF (mu.EQ.muold) GO TO 130
237C JJV added argument checker here
238 IF (mu.GE.0.0) GO TO 125
239 WRITE (*,*) 'MU < 0 in IGNPOI - ABORT'
240 WRITE (*,*) 'Value of MU: ',mu
241 CALL xstopx ('MU < 0 in IGNPOI - ABORT')
242C JJV added line label here
243 125 muold = mu
244 m = max0(1,ifix(mu))
245 l = 0
246 p = exp(-mu)
247 q = p
248 p0 = p
249C
250C STEP U. UNIFORM SAMPLE FOR INVERSION METHOD
251C
252 130 u = ranf()
253 ignpoi = 0
254 IF (u.LE.p0) RETURN
255C
256C STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE
257C PP-TABLE OF CUMULATIVE POISSON PROBABILITIES
258C (0.458=PP(9) FOR MU=10)
259C
260 IF (l.EQ.0) GO TO 150
261 j = 1
262 IF (u.GT.0.458) j = min0(l,m)
263 DO 140 k = j,l
264 IF (u.LE.pp(k)) GO TO 180
265 140 CONTINUE
266 IF (l.EQ.35) GO TO 130
267C
268C STEP C. CREATION OF NEW POISSON PROBABILITIES P
269C AND THEIR CUMULATIVES Q=PP(K)
270C
271 150 l = l + 1
272 DO 160 k = l,35
273 p = p*mu/float(k)
274 q = q + p
275 pp(k) = q
276 IF (u.LE.q) GO TO 170
277 160 CONTINUE
278 l = 35
279 GO TO 130
280
281 170 l = k
282 180 ignpoi = k
283 RETURN
284
285 END
integer *4 function ignpoi(mu)
Definition ignpoi.f:2
real function ranf()
Definition ranf.f:2
real function sexpo()
Definition sexpo.f:2
real function snorm()
Definition snorm.f:2