| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include "randlib.h" |
|
2
|
|
|
|
|
|
|
#include |
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
#include |
|
5
|
|
|
|
|
|
|
#define ABS(x) ((x) >= 0 ? (x) : -(x)) |
|
6
|
|
|
|
|
|
|
#define min(a,b) ((a) <= (b) ? (a) : (b)) |
|
7
|
|
|
|
|
|
|
#define max(a,b) ((a) >= (b) ? (a) : (b)) |
|
8
|
|
|
|
|
|
|
void ftnstop(char*); |
|
9
|
|
|
|
|
|
|
|
|
10
|
6
|
|
|
|
|
|
double genbet(double aa,double bb) |
|
11
|
|
|
|
|
|
|
/* |
|
12
|
|
|
|
|
|
|
********************************************************************** |
|
13
|
|
|
|
|
|
|
double genbet(double aa,double bb) |
|
14
|
|
|
|
|
|
|
GeNerate BETa random deviate |
|
15
|
|
|
|
|
|
|
Function |
|
16
|
|
|
|
|
|
|
Returns a single random deviate from the beta distribution with |
|
17
|
|
|
|
|
|
|
parameters A and B. The density of the beta is |
|
18
|
|
|
|
|
|
|
x^(a-1) * (1-x)^(b-1) / B(a,b) for 0 < x < 1 |
|
19
|
|
|
|
|
|
|
Arguments |
|
20
|
|
|
|
|
|
|
aa --> First parameter of the beta distribution |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
bb --> Second parameter of the beta distribution |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Method |
|
25
|
|
|
|
|
|
|
R. C. H. Cheng |
|
26
|
|
|
|
|
|
|
Generating Beta Variates with Nonintegral Shape Parameters |
|
27
|
|
|
|
|
|
|
Communications of the ACM, 21:317-322 (1978) |
|
28
|
|
|
|
|
|
|
(Algorithms BB and BC) |
|
29
|
|
|
|
|
|
|
********************************************************************** |
|
30
|
|
|
|
|
|
|
*/ |
|
31
|
|
|
|
|
|
|
{ |
|
32
|
|
|
|
|
|
|
/* JJV changed expmax (log(1.0E38)==87.49823), and added minlog */ |
|
33
|
|
|
|
|
|
|
#define expmax 87.4982335337737 |
|
34
|
|
|
|
|
|
|
#define infnty 1.0E38 |
|
35
|
|
|
|
|
|
|
#define minlog 1.0E-37 |
|
36
|
|
|
|
|
|
|
static double olda = -1.0E37; |
|
37
|
|
|
|
|
|
|
static double oldb = -1.0E37; |
|
38
|
|
|
|
|
|
|
static double genbet,a,alpha,b,beta,delta,gamma,k1,k2,r,s,t,u1,u2,v,w,y,z; |
|
39
|
|
|
|
|
|
|
static long qsame; |
|
40
|
|
|
|
|
|
|
|
|
41
|
6
|
100
|
|
|
|
|
qsame = olda == aa && oldb == bb; |
|
|
|
50
|
|
|
|
|
|
|
42
|
6
|
100
|
|
|
|
|
if(qsame) goto S20; |
|
43
|
1
|
50
|
|
|
|
|
if(!(aa < minlog || bb < minlog)) goto S10; |
|
|
|
50
|
|
|
|
|
|
|
44
|
0
|
|
|
|
|
|
fputs(" AA or BB < 1.0E-37 in GENBET - Abort!\n",stderr); |
|
45
|
0
|
|
|
|
|
|
fprintf(stderr," AA: %16.6E BB %16.6E\n",aa,bb); |
|
46
|
0
|
|
|
|
|
|
exit(1); |
|
47
|
1
|
|
|
|
|
|
S10: |
|
48
|
1
|
|
|
|
|
|
olda = aa; |
|
49
|
1
|
|
|
|
|
|
oldb = bb; |
|
50
|
6
|
|
|
|
|
|
S20: |
|
51
|
6
|
50
|
|
|
|
|
if(!(min(aa,bb) > 1.0)) goto S100; |
|
|
|
50
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
/* |
|
53
|
|
|
|
|
|
|
Algorithm BB |
|
54
|
|
|
|
|
|
|
Initialize |
|
55
|
|
|
|
|
|
|
*/ |
|
56
|
6
|
100
|
|
|
|
|
if(qsame) goto S30; |
|
57
|
1
|
50
|
|
|
|
|
a = min(aa,bb); |
|
58
|
1
|
50
|
|
|
|
|
b = max(aa,bb); |
|
59
|
1
|
|
|
|
|
|
alpha = a+b; |
|
60
|
1
|
|
|
|
|
|
beta = sqrt((alpha-2.0)/(2.0*a*b-alpha)); |
|
61
|
1
|
|
|
|
|
|
gamma = a+1.0/beta; |
|
62
|
0
|
|
|
|
|
|
S30: |
|
63
|
6
|
|
|
|
|
|
u1 = ranf(); |
|
64
|
|
|
|
|
|
|
/* |
|
65
|
|
|
|
|
|
|
Step 1 |
|
66
|
|
|
|
|
|
|
*/ |
|
67
|
6
|
|
|
|
|
|
u2 = ranf(); |
|
68
|
6
|
|
|
|
|
|
v = beta*log(u1/(1.0-u1)); |
|
69
|
|
|
|
|
|
|
/* JJV altered this */ |
|
70
|
6
|
50
|
|
|
|
|
if(v > expmax) goto S55; |
|
71
|
|
|
|
|
|
|
/* |
|
72
|
|
|
|
|
|
|
* JJV added checker to see if a*exp(v) will overflow |
|
73
|
|
|
|
|
|
|
* JJV S50 _was_ w = a*exp(v); also note here a > 1.0 |
|
74
|
|
|
|
|
|
|
*/ |
|
75
|
6
|
|
|
|
|
|
w = exp(v); |
|
76
|
6
|
50
|
|
|
|
|
if(w > infnty/a) goto S55; |
|
77
|
6
|
|
|
|
|
|
w *= a; |
|
78
|
6
|
|
|
|
|
|
goto S60; |
|
79
|
0
|
|
|
|
|
|
S55: |
|
80
|
0
|
|
|
|
|
|
w = infnty; |
|
81
|
6
|
|
|
|
|
|
S60: |
|
82
|
6
|
|
|
|
|
|
z = pow(u1,2.0)*u2; |
|
83
|
6
|
|
|
|
|
|
r = gamma*v-1.38629436111989; |
|
84
|
6
|
|
|
|
|
|
s = a+r-w; |
|
85
|
|
|
|
|
|
|
/* |
|
86
|
|
|
|
|
|
|
Step 2 |
|
87
|
|
|
|
|
|
|
*/ |
|
88
|
6
|
100
|
|
|
|
|
if(s+2.60943791243410 >= 5.0*z) goto S70; |
|
89
|
|
|
|
|
|
|
/* |
|
90
|
|
|
|
|
|
|
Step 3 |
|
91
|
|
|
|
|
|
|
*/ |
|
92
|
2
|
|
|
|
|
|
t = log(z); |
|
93
|
2
|
50
|
|
|
|
|
if(s > t) goto S70; |
|
94
|
|
|
|
|
|
|
/* |
|
95
|
|
|
|
|
|
|
* Step 4 |
|
96
|
|
|
|
|
|
|
* |
|
97
|
|
|
|
|
|
|
* JJV added checker to see if log(alpha/(b+w)) will |
|
98
|
|
|
|
|
|
|
* JJV overflow. If so, we count the log as -INF, and |
|
99
|
|
|
|
|
|
|
* JJV consequently evaluate conditional as true, i.e. |
|
100
|
|
|
|
|
|
|
* JJV the algorithm rejects the trial and starts over |
|
101
|
|
|
|
|
|
|
* JJV May not need this here since alpha > 2.0 |
|
102
|
|
|
|
|
|
|
*/ |
|
103
|
0
|
0
|
|
|
|
|
if(alpha/(b+w) < minlog) goto S30; |
|
104
|
0
|
0
|
|
|
|
|
if(r+alpha*log(alpha/(b+w)) < t) goto S30; |
|
105
|
0
|
|
|
|
|
|
S70: |
|
106
|
|
|
|
|
|
|
/* |
|
107
|
|
|
|
|
|
|
Step 5 |
|
108
|
|
|
|
|
|
|
*/ |
|
109
|
6
|
50
|
|
|
|
|
if(aa == a) { |
|
110
|
6
|
|
|
|
|
|
genbet = w/(b+w); |
|
111
|
|
|
|
|
|
|
} else { |
|
112
|
0
|
|
|
|
|
|
genbet = b/(b+w); |
|
113
|
|
|
|
|
|
|
} |
|
114
|
6
|
|
|
|
|
|
goto S230; |
|
115
|
0
|
|
|
|
|
|
S100: |
|
116
|
|
|
|
|
|
|
/* |
|
117
|
|
|
|
|
|
|
Algorithm BC |
|
118
|
|
|
|
|
|
|
Initialize |
|
119
|
|
|
|
|
|
|
*/ |
|
120
|
0
|
0
|
|
|
|
|
if(qsame) goto S110; |
|
121
|
0
|
0
|
|
|
|
|
a = max(aa,bb); |
|
122
|
0
|
0
|
|
|
|
|
b = min(aa,bb); |
|
123
|
0
|
|
|
|
|
|
alpha = a+b; |
|
124
|
0
|
|
|
|
|
|
beta = 1.0/b; |
|
125
|
0
|
|
|
|
|
|
delta = 1.0+a-b; |
|
126
|
0
|
|
|
|
|
|
k1 = delta*(1.38888888888889E-2+4.16666666666667E-2*b) / |
|
127
|
0
|
|
|
|
|
|
(a*beta-0.777777777777778); |
|
128
|
0
|
|
|
|
|
|
k2 = 0.25+(0.5+0.25/delta)*b; |
|
129
|
0
|
|
|
|
|
|
S110: |
|
130
|
0
|
|
|
|
|
|
S120: |
|
131
|
0
|
|
|
|
|
|
u1 = ranf(); |
|
132
|
|
|
|
|
|
|
/* |
|
133
|
|
|
|
|
|
|
Step 1 |
|
134
|
|
|
|
|
|
|
*/ |
|
135
|
0
|
|
|
|
|
|
u2 = ranf(); |
|
136
|
0
|
0
|
|
|
|
|
if(u1 >= 0.5) goto S130; |
|
137
|
|
|
|
|
|
|
/* |
|
138
|
|
|
|
|
|
|
Step 2 |
|
139
|
|
|
|
|
|
|
*/ |
|
140
|
0
|
|
|
|
|
|
y = u1*u2; |
|
141
|
0
|
|
|
|
|
|
z = u1*y; |
|
142
|
0
|
0
|
|
|
|
|
if(0.25*u2+z-y >= k1) goto S120; |
|
143
|
0
|
|
|
|
|
|
goto S170; |
|
144
|
0
|
|
|
|
|
|
S130: |
|
145
|
|
|
|
|
|
|
/* |
|
146
|
|
|
|
|
|
|
Step 3 |
|
147
|
|
|
|
|
|
|
*/ |
|
148
|
0
|
|
|
|
|
|
z = pow(u1,2.0)*u2; |
|
149
|
0
|
0
|
|
|
|
|
if(!(z <= 0.25)) goto S160; |
|
150
|
0
|
|
|
|
|
|
v = beta*log(u1/(1.0-u1)); |
|
151
|
|
|
|
|
|
|
/* |
|
152
|
|
|
|
|
|
|
* JJV instead of checking v > expmax at top, I will check |
|
153
|
|
|
|
|
|
|
* JJV if a < 1, then check the appropriate values |
|
154
|
|
|
|
|
|
|
*/ |
|
155
|
0
|
0
|
|
|
|
|
if(a > 1.0) goto S135; |
|
156
|
|
|
|
|
|
|
/* JJV a < 1 so it can help out if exp(v) would overflow */ |
|
157
|
0
|
0
|
|
|
|
|
if(v > expmax) goto S132; |
|
158
|
0
|
|
|
|
|
|
w = a*exp(v); |
|
159
|
0
|
|
|
|
|
|
goto S200; |
|
160
|
0
|
|
|
|
|
|
S132: |
|
161
|
0
|
|
|
|
|
|
w = v + log(a); |
|
162
|
0
|
0
|
|
|
|
|
if(w > expmax) goto S140; |
|
163
|
0
|
|
|
|
|
|
w = exp(w); |
|
164
|
0
|
|
|
|
|
|
goto S200; |
|
165
|
0
|
|
|
|
|
|
S135: |
|
166
|
|
|
|
|
|
|
/* JJV in this case a > 1 */ |
|
167
|
0
|
0
|
|
|
|
|
if(v > expmax) goto S140; |
|
168
|
0
|
|
|
|
|
|
w = exp(v); |
|
169
|
0
|
0
|
|
|
|
|
if(w > infnty/a) goto S140; |
|
170
|
0
|
|
|
|
|
|
w *= a; |
|
171
|
0
|
|
|
|
|
|
goto S200; |
|
172
|
0
|
|
|
|
|
|
S140: |
|
173
|
0
|
|
|
|
|
|
w = infnty; |
|
174
|
0
|
|
|
|
|
|
goto S200; |
|
175
|
|
|
|
|
|
|
/* |
|
176
|
|
|
|
|
|
|
* JJV old code |
|
177
|
|
|
|
|
|
|
* if(!(v > expmax)) goto S140; |
|
178
|
|
|
|
|
|
|
* w = infnty; |
|
179
|
|
|
|
|
|
|
* goto S150; |
|
180
|
|
|
|
|
|
|
*S140: |
|
181
|
|
|
|
|
|
|
* w = a*exp(v); |
|
182
|
|
|
|
|
|
|
*S150: |
|
183
|
|
|
|
|
|
|
* goto S200; |
|
184
|
|
|
|
|
|
|
*/ |
|
185
|
0
|
|
|
|
|
|
S160: |
|
186
|
0
|
0
|
|
|
|
|
if(z >= k2) goto S120; |
|
187
|
0
|
|
|
|
|
|
S170: |
|
188
|
|
|
|
|
|
|
/* |
|
189
|
|
|
|
|
|
|
Step 4 |
|
190
|
|
|
|
|
|
|
Step 5 |
|
191
|
|
|
|
|
|
|
*/ |
|
192
|
0
|
|
|
|
|
|
v = beta*log(u1/(1.0-u1)); |
|
193
|
|
|
|
|
|
|
/* JJV same kind of checking as above */ |
|
194
|
0
|
0
|
|
|
|
|
if(a > 1.0) goto S175; |
|
195
|
|
|
|
|
|
|
/* JJV a < 1 so it can help out if exp(v) would overflow */ |
|
196
|
0
|
0
|
|
|
|
|
if(v > expmax) goto S172; |
|
197
|
0
|
|
|
|
|
|
w = a*exp(v); |
|
198
|
0
|
|
|
|
|
|
goto S190; |
|
199
|
0
|
|
|
|
|
|
S172: |
|
200
|
0
|
|
|
|
|
|
w = v + log(a); |
|
201
|
0
|
0
|
|
|
|
|
if(w > expmax) goto S180; |
|
202
|
0
|
|
|
|
|
|
w = exp(w); |
|
203
|
0
|
|
|
|
|
|
goto S190; |
|
204
|
0
|
|
|
|
|
|
S175: |
|
205
|
|
|
|
|
|
|
/* JJV in this case a > 1.0 */ |
|
206
|
0
|
0
|
|
|
|
|
if(v > expmax) goto S180; |
|
207
|
0
|
|
|
|
|
|
w = exp(v); |
|
208
|
0
|
0
|
|
|
|
|
if(w > infnty/a) goto S180; |
|
209
|
0
|
|
|
|
|
|
w *= a; |
|
210
|
0
|
|
|
|
|
|
goto S190; |
|
211
|
0
|
|
|
|
|
|
S180: |
|
212
|
0
|
|
|
|
|
|
w = infnty; |
|
213
|
|
|
|
|
|
|
/* |
|
214
|
|
|
|
|
|
|
* JJV old code |
|
215
|
|
|
|
|
|
|
* if(!(v > expmax)) goto S180; |
|
216
|
|
|
|
|
|
|
* w = infnty; |
|
217
|
|
|
|
|
|
|
* goto S190; |
|
218
|
|
|
|
|
|
|
*S180: |
|
219
|
|
|
|
|
|
|
* w = a*exp(v); |
|
220
|
|
|
|
|
|
|
*/ |
|
221
|
0
|
|
|
|
|
|
S190: |
|
222
|
|
|
|
|
|
|
/* |
|
223
|
|
|
|
|
|
|
* JJV here we also check to see if log overlows; if so, we treat it |
|
224
|
|
|
|
|
|
|
* JJV as -INF, which means condition is true, i.e. restart |
|
225
|
|
|
|
|
|
|
*/ |
|
226
|
0
|
0
|
|
|
|
|
if(alpha/(b+w) < minlog) goto S120; |
|
227
|
0
|
0
|
|
|
|
|
if(alpha*(log(alpha/(b+w))+v)-1.38629436111989 < log(z)) goto S120; |
|
228
|
0
|
|
|
|
|
|
S200: |
|
229
|
|
|
|
|
|
|
/* |
|
230
|
|
|
|
|
|
|
Step 6 |
|
231
|
|
|
|
|
|
|
*/ |
|
232
|
0
|
0
|
|
|
|
|
if(a == aa) { |
|
233
|
0
|
|
|
|
|
|
genbet = w/(b+w); |
|
234
|
|
|
|
|
|
|
} else { |
|
235
|
0
|
|
|
|
|
|
genbet = b/(b+w); |
|
236
|
|
|
|
|
|
|
} |
|
237
|
6
|
|
|
|
|
|
S230: |
|
238
|
6
|
|
|
|
|
|
return genbet; |
|
239
|
|
|
|
|
|
|
#undef expmax |
|
240
|
|
|
|
|
|
|
#undef infnty |
|
241
|
|
|
|
|
|
|
#undef minlog |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
|
|
244
|
6
|
|
|
|
|
|
double genchi(double df) |
|
245
|
|
|
|
|
|
|
/* |
|
246
|
|
|
|
|
|
|
********************************************************************** |
|
247
|
|
|
|
|
|
|
double genchi(double df) |
|
248
|
|
|
|
|
|
|
Generate random value of CHIsquare variable |
|
249
|
|
|
|
|
|
|
Function |
|
250
|
|
|
|
|
|
|
Generates random deviate from the distribution of a chisquare |
|
251
|
|
|
|
|
|
|
with DF degrees of freedom random variable. |
|
252
|
|
|
|
|
|
|
Arguments |
|
253
|
|
|
|
|
|
|
df --> Degrees of freedom of the chisquare |
|
254
|
|
|
|
|
|
|
(Must be positive) |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
Method |
|
257
|
|
|
|
|
|
|
Uses relation between chisquare and gamma. |
|
258
|
|
|
|
|
|
|
********************************************************************** |
|
259
|
|
|
|
|
|
|
*/ |
|
260
|
|
|
|
|
|
|
{ |
|
261
|
|
|
|
|
|
|
static double genchi; |
|
262
|
|
|
|
|
|
|
|
|
263
|
6
|
50
|
|
|
|
|
if(!(df <= 0.0)) goto S10; |
|
264
|
0
|
|
|
|
|
|
fputs(" DF <= 0 in GENCHI - ABORT\n",stderr); |
|
265
|
0
|
|
|
|
|
|
fprintf(stderr," Value of DF: %16.6E\n",df); |
|
266
|
0
|
|
|
|
|
|
exit(1); |
|
267
|
6
|
|
|
|
|
|
S10: |
|
268
|
|
|
|
|
|
|
/* |
|
269
|
|
|
|
|
|
|
* JJV changed the code to call SGAMMA directly |
|
270
|
|
|
|
|
|
|
* genchi = 2.0*gengam(1.0,df/2.0); <- OLD |
|
271
|
|
|
|
|
|
|
*/ |
|
272
|
6
|
|
|
|
|
|
genchi = 2.0*sgamma(df/2.0); |
|
273
|
6
|
|
|
|
|
|
return genchi; |
|
274
|
|
|
|
|
|
|
} |
|
275
|
|
|
|
|
|
|
|
|
276
|
6
|
|
|
|
|
|
double genexp(double av) |
|
277
|
|
|
|
|
|
|
/* |
|
278
|
|
|
|
|
|
|
********************************************************************** |
|
279
|
|
|
|
|
|
|
double genexp(double av) |
|
280
|
|
|
|
|
|
|
GENerate EXPonential random deviate |
|
281
|
|
|
|
|
|
|
Function |
|
282
|
|
|
|
|
|
|
Generates a single random deviate from an exponential |
|
283
|
|
|
|
|
|
|
distribution with mean AV. |
|
284
|
|
|
|
|
|
|
Arguments |
|
285
|
|
|
|
|
|
|
av --> The mean of the exponential distribution from which |
|
286
|
|
|
|
|
|
|
a random deviate is to be generated. |
|
287
|
|
|
|
|
|
|
JJV (av >= 0) |
|
288
|
|
|
|
|
|
|
Method |
|
289
|
|
|
|
|
|
|
Renames SEXPO from TOMS as slightly modified by BWB to use RANF |
|
290
|
|
|
|
|
|
|
instead of SUNIF. |
|
291
|
|
|
|
|
|
|
For details see: |
|
292
|
|
|
|
|
|
|
Ahrens, J.H. and Dieter, U. |
|
293
|
|
|
|
|
|
|
Computer Methods for Sampling From the |
|
294
|
|
|
|
|
|
|
Exponential and Normal Distributions. |
|
295
|
|
|
|
|
|
|
Comm. ACM, 15,10 (Oct. 1972), 873 - 882. |
|
296
|
|
|
|
|
|
|
********************************************************************** |
|
297
|
|
|
|
|
|
|
*/ |
|
298
|
|
|
|
|
|
|
{ |
|
299
|
|
|
|
|
|
|
static double genexp; |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
/* JJV added check that av >= 0 */ |
|
302
|
6
|
50
|
|
|
|
|
if(av >= 0.0) goto S10; |
|
303
|
0
|
|
|
|
|
|
fputs(" AV < 0 in GENEXP - ABORT\n",stderr); |
|
304
|
0
|
|
|
|
|
|
fprintf(stderr," Value of AV: %16.6E\n",av); |
|
305
|
0
|
|
|
|
|
|
exit(1); |
|
306
|
6
|
|
|
|
|
|
S10: |
|
307
|
6
|
|
|
|
|
|
genexp = sexpo()*av; |
|
308
|
6
|
|
|
|
|
|
return genexp; |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
|
|
311
|
6
|
|
|
|
|
|
double genf(double dfn,double dfd) |
|
312
|
|
|
|
|
|
|
/* |
|
313
|
|
|
|
|
|
|
********************************************************************** |
|
314
|
|
|
|
|
|
|
double genf(double dfn,double dfd) |
|
315
|
|
|
|
|
|
|
GENerate random deviate from the F distribution |
|
316
|
|
|
|
|
|
|
Function |
|
317
|
|
|
|
|
|
|
Generates a random deviate from the F (variance ratio) |
|
318
|
|
|
|
|
|
|
distribution with DFN degrees of freedom in the numerator |
|
319
|
|
|
|
|
|
|
and DFD degrees of freedom in the denominator. |
|
320
|
|
|
|
|
|
|
Arguments |
|
321
|
|
|
|
|
|
|
dfn --> Numerator degrees of freedom |
|
322
|
|
|
|
|
|
|
(Must be positive) |
|
323
|
|
|
|
|
|
|
dfd --> Denominator degrees of freedom |
|
324
|
|
|
|
|
|
|
(Must be positive) |
|
325
|
|
|
|
|
|
|
Method |
|
326
|
|
|
|
|
|
|
Directly generates ratio of chisquare variates |
|
327
|
|
|
|
|
|
|
********************************************************************** |
|
328
|
|
|
|
|
|
|
*/ |
|
329
|
|
|
|
|
|
|
{ |
|
330
|
|
|
|
|
|
|
static double genf,xden,xnum; |
|
331
|
|
|
|
|
|
|
|
|
332
|
6
|
50
|
|
|
|
|
if(!(dfn <= 0.0 || dfd <= 0.0)) goto S10; |
|
|
|
50
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
|
fputs(" Degrees of freedom nonpositive in GENF - abort!\n",stderr); |
|
334
|
0
|
|
|
|
|
|
fprintf(stderr," DFN value: %16.6E DFD value: %16.6E\n",dfn,dfd); |
|
335
|
0
|
|
|
|
|
|
exit(1); |
|
336
|
6
|
|
|
|
|
|
S10: |
|
337
|
|
|
|
|
|
|
/* |
|
338
|
|
|
|
|
|
|
* JJV changed this to call SGAMMA directly |
|
339
|
|
|
|
|
|
|
* |
|
340
|
|
|
|
|
|
|
* GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD ) |
|
341
|
|
|
|
|
|
|
* xnum = genchi(dfn)/dfn; <- OLD |
|
342
|
|
|
|
|
|
|
* xden = genchi(dfd)/dfd; <- OLD |
|
343
|
|
|
|
|
|
|
*/ |
|
344
|
6
|
|
|
|
|
|
xnum = 2.0*sgamma(dfn/2.0)/dfn; |
|
345
|
6
|
|
|
|
|
|
xden = 2.0*sgamma(dfd/2.0)/dfd; |
|
346
|
|
|
|
|
|
|
/* |
|
347
|
|
|
|
|
|
|
* JJV changed constant to prevent underflow at compile time. |
|
348
|
|
|
|
|
|
|
* if(!(xden <= 9.999999999998E-39*xnum)) goto S20; |
|
349
|
|
|
|
|
|
|
*/ |
|
350
|
6
|
50
|
|
|
|
|
if(!(xden <= 1.0E-37*xnum)) goto S20; |
|
351
|
0
|
|
|
|
|
|
fputs(" GENF - generated numbers would cause overflow\n",stderr); |
|
352
|
0
|
|
|
|
|
|
fprintf(stderr," Numerator %16.6E Denominator %16.6E\n",xnum,xden); |
|
353
|
|
|
|
|
|
|
/* |
|
354
|
|
|
|
|
|
|
* JJV changed next 2 lines to reflect constant change above in the |
|
355
|
|
|
|
|
|
|
* JJV truncated value returned. |
|
356
|
|
|
|
|
|
|
* fputs(" GENF returning 1.0E38\n",stderr); |
|
357
|
|
|
|
|
|
|
* genf = 1.0E38; |
|
358
|
|
|
|
|
|
|
*/ |
|
359
|
0
|
|
|
|
|
|
fputs(" GENF returning 1.0E37\n",stderr); |
|
360
|
0
|
|
|
|
|
|
genf = 1.0E37; |
|
361
|
0
|
|
|
|
|
|
goto S30; |
|
362
|
6
|
|
|
|
|
|
S20: |
|
363
|
6
|
|
|
|
|
|
genf = xnum/xden; |
|
364
|
6
|
|
|
|
|
|
S30: |
|
365
|
6
|
|
|
|
|
|
return genf; |
|
366
|
|
|
|
|
|
|
} |
|
367
|
|
|
|
|
|
|
|
|
368
|
6
|
|
|
|
|
|
double gengam(double a,double r) |
|
369
|
|
|
|
|
|
|
/* |
|
370
|
|
|
|
|
|
|
********************************************************************** |
|
371
|
|
|
|
|
|
|
double gengam(double a,double r) |
|
372
|
|
|
|
|
|
|
GENerates random deviates from GAMma distribution |
|
373
|
|
|
|
|
|
|
Function |
|
374
|
|
|
|
|
|
|
Generates random deviates from the gamma distribution whose |
|
375
|
|
|
|
|
|
|
density is |
|
376
|
|
|
|
|
|
|
(A**R)/Gamma(R) * X**(R-1) * Exp(-A*X) |
|
377
|
|
|
|
|
|
|
Arguments |
|
378
|
|
|
|
|
|
|
a --> Location parameter of Gamma distribution |
|
379
|
|
|
|
|
|
|
JJV (a > 0) |
|
380
|
|
|
|
|
|
|
r --> Shape parameter of Gamma distribution |
|
381
|
|
|
|
|
|
|
JJV (r > 0) |
|
382
|
|
|
|
|
|
|
Method |
|
383
|
|
|
|
|
|
|
Renames SGAMMA from TOMS as slightly modified by BWB to use RANF |
|
384
|
|
|
|
|
|
|
instead of SUNIF. |
|
385
|
|
|
|
|
|
|
For details see: |
|
386
|
|
|
|
|
|
|
(Case R >= 1.0) |
|
387
|
|
|
|
|
|
|
Ahrens, J.H. and Dieter, U. |
|
388
|
|
|
|
|
|
|
Generating Gamma Variates by a |
|
389
|
|
|
|
|
|
|
Modified Rejection Technique. |
|
390
|
|
|
|
|
|
|
Comm. ACM, 25,1 (Jan. 1982), 47 - 54. |
|
391
|
|
|
|
|
|
|
Algorithm GD |
|
392
|
|
|
|
|
|
|
JJV altered following to reflect argument ranges |
|
393
|
|
|
|
|
|
|
(Case 0.0 < R < 1.0) |
|
394
|
|
|
|
|
|
|
Ahrens, J.H. and Dieter, U. |
|
395
|
|
|
|
|
|
|
Computer Methods for Sampling from Gamma, |
|
396
|
|
|
|
|
|
|
Beta, Poisson and Binomial Distributions. |
|
397
|
|
|
|
|
|
|
Computing, 12 (1974), 223-246/ |
|
398
|
|
|
|
|
|
|
Adapted algorithm GS. |
|
399
|
|
|
|
|
|
|
********************************************************************** |
|
400
|
|
|
|
|
|
|
*/ |
|
401
|
|
|
|
|
|
|
{ |
|
402
|
|
|
|
|
|
|
static double gengam; |
|
403
|
|
|
|
|
|
|
/* JJV added argument checker */ |
|
404
|
6
|
50
|
|
|
|
|
if(a > 0.0 && r > 0.0) goto S10; |
|
|
|
50
|
|
|
|
|
|
|
405
|
0
|
|
|
|
|
|
fputs(" A or R nonpositive in GENGAM - abort!\n",stderr); |
|
406
|
0
|
|
|
|
|
|
fprintf(stderr," A value: %16.6E R value: %16.6E\n",a,r); |
|
407
|
0
|
|
|
|
|
|
exit(1); |
|
408
|
6
|
|
|
|
|
|
S10: |
|
409
|
6
|
|
|
|
|
|
gengam = sgamma(r); |
|
410
|
6
|
|
|
|
|
|
gengam /= a; |
|
411
|
6
|
|
|
|
|
|
return gengam; |
|
412
|
|
|
|
|
|
|
} |
|
413
|
|
|
|
|
|
|
|
|
414
|
4
|
|
|
|
|
|
void genmn(double *parm,double *x,double *work) |
|
415
|
|
|
|
|
|
|
/* |
|
416
|
|
|
|
|
|
|
********************************************************************** |
|
417
|
|
|
|
|
|
|
void genmn(double *parm,double *x,double *work) |
|
418
|
|
|
|
|
|
|
GENerate Multivariate Normal random deviate |
|
419
|
|
|
|
|
|
|
Arguments |
|
420
|
|
|
|
|
|
|
parm --> Parameters needed to generate multivariate normal |
|
421
|
|
|
|
|
|
|
deviates (MEANV and Cholesky decomposition of |
|
422
|
|
|
|
|
|
|
COVM). Set by a previous call to SETGMN. |
|
423
|
|
|
|
|
|
|
1 : 1 - size of deviate, P |
|
424
|
|
|
|
|
|
|
2 : P + 1 - mean vector |
|
425
|
|
|
|
|
|
|
P+2 : P*(P+3)/2 + 1 - upper half of cholesky |
|
426
|
|
|
|
|
|
|
decomposition of cov matrix |
|
427
|
|
|
|
|
|
|
x <-- Vector deviate generated. |
|
428
|
|
|
|
|
|
|
work <--> Scratch array |
|
429
|
|
|
|
|
|
|
Method |
|
430
|
|
|
|
|
|
|
1) Generate P independent standard normal deviates - Ei ~ N(0,1) |
|
431
|
|
|
|
|
|
|
2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM |
|
432
|
|
|
|
|
|
|
3) trans(A)E + MEANV ~ N(MEANV,COVM) |
|
433
|
|
|
|
|
|
|
********************************************************************** |
|
434
|
|
|
|
|
|
|
*/ |
|
435
|
|
|
|
|
|
|
{ |
|
436
|
|
|
|
|
|
|
static long i,icount,j,p,D1,D2,D3,D4; |
|
437
|
|
|
|
|
|
|
static double ae; |
|
438
|
|
|
|
|
|
|
|
|
439
|
4
|
|
|
|
|
|
p = (long) (*parm); |
|
440
|
|
|
|
|
|
|
/* |
|
441
|
|
|
|
|
|
|
Generate P independent normal deviates - WORK ~ N(0,1) |
|
442
|
|
|
|
|
|
|
*/ |
|
443
|
12
|
100
|
|
|
|
|
for(i=1; i<=p; i++) *(work+i-1) = snorm(); |
|
444
|
12
|
100
|
|
|
|
|
for(i=1,D3=1,D4=(p-i+D3)/D3; D4>0; D4--,i+=D3) { |
|
445
|
|
|
|
|
|
|
/* |
|
446
|
|
|
|
|
|
|
PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky |
|
447
|
|
|
|
|
|
|
decomposition of the desired covariance matrix. |
|
448
|
|
|
|
|
|
|
trans(A)(1,1) = PARM(P+2) |
|
449
|
|
|
|
|
|
|
trans(A)(2,1) = PARM(P+3) |
|
450
|
|
|
|
|
|
|
trans(A)(2,2) = PARM(P+2+P) |
|
451
|
|
|
|
|
|
|
trans(A)(3,1) = PARM(P+4) |
|
452
|
|
|
|
|
|
|
trans(A)(3,2) = PARM(P+3+P) |
|
453
|
|
|
|
|
|
|
trans(A)(3,3) = PARM(P+2-1+2P) ... |
|
454
|
|
|
|
|
|
|
trans(A)*WORK + MEANV ~ N(MEANV,COVM) |
|
455
|
|
|
|
|
|
|
*/ |
|
456
|
8
|
|
|
|
|
|
icount = 0; |
|
457
|
8
|
|
|
|
|
|
ae = 0.0; |
|
458
|
20
|
100
|
|
|
|
|
for(j=1,D1=1,D2=(i-j+D1)/D1; D2>0; D2--,j+=D1) { |
|
459
|
12
|
|
|
|
|
|
icount += (j-1); |
|
460
|
12
|
|
|
|
|
|
ae += (*(parm+i+(j-1)*p-icount+p)**(work+j-1)); |
|
461
|
|
|
|
|
|
|
} |
|
462
|
8
|
|
|
|
|
|
*(x+i-1) = ae+*(parm+i); |
|
463
|
|
|
|
|
|
|
} |
|
464
|
4
|
|
|
|
|
|
} |
|
465
|
|
|
|
|
|
|
|
|
466
|
2
|
|
|
|
|
|
void genmul(long n,double *p,long ncat,long *ix) |
|
467
|
|
|
|
|
|
|
/* |
|
468
|
|
|
|
|
|
|
********************************************************************** |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
void genmul(int n,double *p,int ncat,int *ix) |
|
471
|
|
|
|
|
|
|
GENerate an observation from the MULtinomial distribution |
|
472
|
|
|
|
|
|
|
Arguments |
|
473
|
|
|
|
|
|
|
N --> Number of events that will be classified into one of |
|
474
|
|
|
|
|
|
|
the categories 1..NCAT |
|
475
|
|
|
|
|
|
|
P --> Vector of probabilities. P(i) is the probability that |
|
476
|
|
|
|
|
|
|
an event will be classified into category i. Thus, P(i) |
|
477
|
|
|
|
|
|
|
must be [0,1]. Only the first NCAT-1 P(i) must be defined |
|
478
|
|
|
|
|
|
|
since P(NCAT) is 1.0 minus the sum of the first |
|
479
|
|
|
|
|
|
|
NCAT-1 P(i). |
|
480
|
|
|
|
|
|
|
NCAT --> Number of categories. Length of P and IX. |
|
481
|
|
|
|
|
|
|
IX <-- Observation from multinomial distribution. All IX(i) |
|
482
|
|
|
|
|
|
|
will be nonnegative and their sum will be N. |
|
483
|
|
|
|
|
|
|
Method |
|
484
|
|
|
|
|
|
|
Algorithm from page 559 of |
|
485
|
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
Devroye, Luc |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Non-Uniform Random Variate Generation. Springer-Verlag, |
|
489
|
|
|
|
|
|
|
New York, 1986. |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
********************************************************************** |
|
492
|
|
|
|
|
|
|
*/ |
|
493
|
|
|
|
|
|
|
{ |
|
494
|
|
|
|
|
|
|
static double prob,ptot,sum; |
|
495
|
|
|
|
|
|
|
static long i,icat,ntot; |
|
496
|
2
|
50
|
|
|
|
|
if(n < 0) ftnstop("N < 0 in GENMUL"); |
|
497
|
2
|
50
|
|
|
|
|
if(ncat <= 1) ftnstop("NCAT <= 1 in GENMUL"); |
|
498
|
2
|
|
|
|
|
|
ptot = 0.0F; |
|
499
|
6
|
100
|
|
|
|
|
for(i=0; i
|
|
500
|
4
|
50
|
|
|
|
|
if(*(p+i) < 0.0F) ftnstop("Some P(i) < 0 in GENMUL"); |
|
501
|
4
|
50
|
|
|
|
|
if(*(p+i) > 1.0F) ftnstop("Some P(i) > 1 in GENMUL"); |
|
502
|
4
|
|
|
|
|
|
ptot += *(p+i); |
|
503
|
|
|
|
|
|
|
} |
|
504
|
2
|
50
|
|
|
|
|
if(ptot > 0.99999F) ftnstop("Sum of P(i) > 1 in GENMUL"); |
|
505
|
|
|
|
|
|
|
/* |
|
506
|
|
|
|
|
|
|
Initialize variables |
|
507
|
|
|
|
|
|
|
*/ |
|
508
|
2
|
|
|
|
|
|
ntot = n; |
|
509
|
2
|
|
|
|
|
|
sum = 1.0F; |
|
510
|
8
|
100
|
|
|
|
|
for(i=0; i
|
|
511
|
|
|
|
|
|
|
/* |
|
512
|
|
|
|
|
|
|
Generate the observation |
|
513
|
|
|
|
|
|
|
*/ |
|
514
|
6
|
100
|
|
|
|
|
for(icat=0; icat
|
|
515
|
4
|
|
|
|
|
|
prob = *(p+icat)/sum; |
|
516
|
4
|
|
|
|
|
|
*(ix+icat) = ignbin(ntot,prob); |
|
517
|
4
|
|
|
|
|
|
ntot -= *(ix+icat); |
|
518
|
4
|
50
|
|
|
|
|
if(ntot <= 0) return; |
|
519
|
4
|
|
|
|
|
|
sum -= *(p+icat); |
|
520
|
|
|
|
|
|
|
} |
|
521
|
2
|
|
|
|
|
|
*(ix+ncat-1) = ntot; |
|
522
|
|
|
|
|
|
|
/* |
|
523
|
|
|
|
|
|
|
Finished |
|
524
|
|
|
|
|
|
|
*/ |
|
525
|
2
|
|
|
|
|
|
return; |
|
526
|
|
|
|
|
|
|
} |
|
527
|
|
|
|
|
|
|
|
|
528
|
6
|
|
|
|
|
|
double gennch(double df,double xnonc) |
|
529
|
|
|
|
|
|
|
/* |
|
530
|
|
|
|
|
|
|
********************************************************************** |
|
531
|
|
|
|
|
|
|
double gennch(double df,double xnonc) |
|
532
|
|
|
|
|
|
|
Generate random value of Noncentral CHIsquare variable |
|
533
|
|
|
|
|
|
|
Function |
|
534
|
|
|
|
|
|
|
Generates random deviate from the distribution of a noncentral |
|
535
|
|
|
|
|
|
|
chisquare with DF degrees of freedom and noncentrality parameter |
|
536
|
|
|
|
|
|
|
xnonc. |
|
537
|
|
|
|
|
|
|
Arguments |
|
538
|
|
|
|
|
|
|
df --> Degrees of freedom of the chisquare |
|
539
|
|
|
|
|
|
|
(Must be >= 1.0) |
|
540
|
|
|
|
|
|
|
xnonc --> Noncentrality parameter of the chisquare |
|
541
|
|
|
|
|
|
|
(Must be >= 0.0) |
|
542
|
|
|
|
|
|
|
Method |
|
543
|
|
|
|
|
|
|
Uses fact that noncentral chisquare is the sum of a chisquare |
|
544
|
|
|
|
|
|
|
deviate with DF-1 degrees of freedom plus the square of a normal |
|
545
|
|
|
|
|
|
|
deviate with mean XNONC and standard deviation 1. |
|
546
|
|
|
|
|
|
|
********************************************************************** |
|
547
|
|
|
|
|
|
|
*/ |
|
548
|
|
|
|
|
|
|
{ |
|
549
|
|
|
|
|
|
|
static double gennch; |
|
550
|
|
|
|
|
|
|
|
|
551
|
6
|
50
|
|
|
|
|
if(!(df < 1.0 || xnonc < 0.0)) goto S10; |
|
|
|
50
|
|
|
|
|
|
|
552
|
0
|
|
|
|
|
|
fputs("DF < 1 or XNONC < 0 in GENNCH - ABORT\n",stderr); |
|
553
|
0
|
|
|
|
|
|
fprintf(stderr,"Value of DF: %16.6E Value of XNONC: %16.6E\n",df,xnonc); |
|
554
|
0
|
|
|
|
|
|
exit(1); |
|
555
|
|
|
|
|
|
|
/* JJV changed code to call SGAMMA, SNORM directly */ |
|
556
|
6
|
|
|
|
|
|
S10: |
|
557
|
6
|
50
|
|
|
|
|
if(df >= 1.000000001) goto S20; |
|
558
|
|
|
|
|
|
|
/* |
|
559
|
|
|
|
|
|
|
* JJV case df == 1.0 |
|
560
|
|
|
|
|
|
|
* gennch = pow(gennor(sqrt(xnonc),1.0),2.0); <- OLD |
|
561
|
|
|
|
|
|
|
*/ |
|
562
|
0
|
|
|
|
|
|
gennch = pow(snorm()+sqrt(xnonc),2.0); |
|
563
|
0
|
|
|
|
|
|
goto S30; |
|
564
|
6
|
|
|
|
|
|
S20: |
|
565
|
|
|
|
|
|
|
/* |
|
566
|
|
|
|
|
|
|
* JJV case df > 1.0 |
|
567
|
|
|
|
|
|
|
* gennch = genchi(df-1.0)+pow(gennor(sqrt(xnonc),1.0),2.0); <- OLD |
|
568
|
|
|
|
|
|
|
*/ |
|
569
|
|
|
|
|
|
|
/* the following expression is split to ensure consistent evaluation |
|
570
|
|
|
|
|
|
|
across platforms. since sgamma() and snorm() both change the state |
|
571
|
|
|
|
|
|
|
of the random number generator, it is important that they be evaluated |
|
572
|
|
|
|
|
|
|
in the same order, regardless of how the compiler chooses to order |
|
573
|
|
|
|
|
|
|
things |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
gennch = 2.0*sgamma((df-1.0)/2.0)+pow(snorm()+sqrt(xnonc),2.0; |
|
576
|
|
|
|
|
|
|
*/ |
|
577
|
|
|
|
|
|
|
{ |
|
578
|
|
|
|
|
|
|
double t1, t2; |
|
579
|
6
|
|
|
|
|
|
t1 = 2.0*sgamma((df-1.0)/2.0); |
|
580
|
6
|
|
|
|
|
|
t2 = pow(snorm()+sqrt(xnonc),2.0); |
|
581
|
6
|
|
|
|
|
|
gennch = t1 + t2; |
|
582
|
|
|
|
|
|
|
} |
|
583
|
6
|
|
|
|
|
|
S30: |
|
584
|
6
|
|
|
|
|
|
return gennch; |
|
585
|
|
|
|
|
|
|
} |
|
586
|
|
|
|
|
|
|
|
|
587
|
6
|
|
|
|
|
|
double gennf(double dfn,double dfd,double xnonc) |
|
588
|
|
|
|
|
|
|
/* |
|
589
|
|
|
|
|
|
|
********************************************************************** |
|
590
|
|
|
|
|
|
|
double gennf(double dfn,double dfd,double xnonc) |
|
591
|
|
|
|
|
|
|
GENerate random deviate from the Noncentral F distribution |
|
592
|
|
|
|
|
|
|
Function |
|
593
|
|
|
|
|
|
|
Generates a random deviate from the noncentral F (variance ratio) |
|
594
|
|
|
|
|
|
|
distribution with DFN degrees of freedom in the numerator, and DFD |
|
595
|
|
|
|
|
|
|
degrees of freedom in the denominator, and noncentrality parameter |
|
596
|
|
|
|
|
|
|
XNONC. |
|
597
|
|
|
|
|
|
|
Arguments |
|
598
|
|
|
|
|
|
|
dfn --> Numerator degrees of freedom |
|
599
|
|
|
|
|
|
|
(Must be >= 1.0) |
|
600
|
|
|
|
|
|
|
dfd --> Denominator degrees of freedom |
|
601
|
|
|
|
|
|
|
(Must be positive) |
|
602
|
|
|
|
|
|
|
xnonc --> Noncentrality parameter |
|
603
|
|
|
|
|
|
|
(Must be nonnegative) |
|
604
|
|
|
|
|
|
|
Method |
|
605
|
|
|
|
|
|
|
Directly generates ratio of noncentral numerator chisquare variate |
|
606
|
|
|
|
|
|
|
to central denominator chisquare variate. |
|
607
|
|
|
|
|
|
|
********************************************************************** |
|
608
|
|
|
|
|
|
|
*/ |
|
609
|
|
|
|
|
|
|
{ |
|
610
|
|
|
|
|
|
|
static double gennf,xden,xnum; |
|
611
|
|
|
|
|
|
|
static long qcond; |
|
612
|
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
/* JJV changed qcond, error message to allow dfn == 1.0 */ |
|
614
|
6
|
50
|
|
|
|
|
qcond = dfn < 1.0 || dfd <= 0.0 || xnonc < 0.0; |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
615
|
6
|
50
|
|
|
|
|
if(!qcond) goto S10; |
|
616
|
0
|
|
|
|
|
|
fputs("In GENNF - Either (1) Numerator DF < 1.0 or\n",stderr); |
|
617
|
0
|
|
|
|
|
|
fputs(" (2) Denominator DF <= 0.0 or\n",stderr); |
|
618
|
0
|
|
|
|
|
|
fputs(" (3) Noncentrality parameter < 0.0\n",stderr); |
|
619
|
0
|
|
|
|
|
|
fprintf(stderr, |
|
620
|
|
|
|
|
|
|
"DFN value: %16.6E DFD value: %16.6E XNONC value: \n%16.6E\n",dfn,dfd, |
|
621
|
|
|
|
|
|
|
xnonc); |
|
622
|
0
|
|
|
|
|
|
exit(1); |
|
623
|
6
|
|
|
|
|
|
S10: |
|
624
|
|
|
|
|
|
|
/* |
|
625
|
|
|
|
|
|
|
* JJV changed the code to call SGAMMA and SNORM directly |
|
626
|
|
|
|
|
|
|
* GENNF = ( GENNCH( DFN, XNONC ) / DFN ) / ( GENCHI( DFD ) / DFD ) |
|
627
|
|
|
|
|
|
|
* xnum = gennch(dfn,xnonc)/dfn; <- OLD |
|
628
|
|
|
|
|
|
|
* xden = genchi(dfd)/dfd; <- OLD |
|
629
|
|
|
|
|
|
|
*/ |
|
630
|
6
|
50
|
|
|
|
|
if(dfn >= 1.000001) goto S20; |
|
631
|
|
|
|
|
|
|
/* JJV case dfn == 1.0, dfn is counted as exactly 1.0 */ |
|
632
|
0
|
|
|
|
|
|
xnum = pow(snorm()+sqrt(xnonc),2.0); |
|
633
|
0
|
|
|
|
|
|
goto S30; |
|
634
|
6
|
|
|
|
|
|
S20: |
|
635
|
|
|
|
|
|
|
/* JJV case df > 1.0 */ |
|
636
|
|
|
|
|
|
|
/* the following expression is split to ensure consistent evaluation |
|
637
|
|
|
|
|
|
|
across platforms. since sgamma() and snorm() both change the state |
|
638
|
|
|
|
|
|
|
of the random number generator, it is important that they be evaluated |
|
639
|
|
|
|
|
|
|
in the same order, regardless of how the compiler chooses to order |
|
640
|
|
|
|
|
|
|
things |
|
641
|
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
xnum = (2.0*sgamma((dfn-1.0)/2.0)+pow(snorm()+sqrt(xnonc),2.0))/dfn; |
|
643
|
|
|
|
|
|
|
*/ |
|
644
|
|
|
|
|
|
|
{ |
|
645
|
|
|
|
|
|
|
double t1, t2; |
|
646
|
6
|
|
|
|
|
|
t1 = 2.0*sgamma((dfn-1.0)/2.0); |
|
647
|
6
|
|
|
|
|
|
t2 = pow(snorm()+sqrt(xnonc),2.0); |
|
648
|
6
|
|
|
|
|
|
xnum = (t1 + t2) / dfn; |
|
649
|
|
|
|
|
|
|
} |
|
650
|
6
|
|
|
|
|
|
S30: |
|
651
|
6
|
|
|
|
|
|
xden = 2.0*sgamma(dfd/2.0)/dfd; |
|
652
|
|
|
|
|
|
|
/* |
|
653
|
|
|
|
|
|
|
* JJV changed constant to prevent underflow at compile time. |
|
654
|
|
|
|
|
|
|
* if(!(xden <= 9.999999999998E-39*xnum)) goto S40; |
|
655
|
|
|
|
|
|
|
*/ |
|
656
|
6
|
50
|
|
|
|
|
if(!(xden <= 1.0E-37*xnum)) goto S40; |
|
657
|
0
|
|
|
|
|
|
fputs(" GENNF - generated numbers would cause overflow\n",stderr); |
|
658
|
0
|
|
|
|
|
|
fprintf(stderr," Numerator %16.6E Denominator %16.6E\n",xnum,xden); |
|
659
|
|
|
|
|
|
|
/* |
|
660
|
|
|
|
|
|
|
* JJV changed next 2 lines to reflect constant change above in the |
|
661
|
|
|
|
|
|
|
* JJV truncated value returned. |
|
662
|
|
|
|
|
|
|
* fputs(" GENNF returning 1.0E38\n",stderr); |
|
663
|
|
|
|
|
|
|
* gennf = 1.0E38; |
|
664
|
|
|
|
|
|
|
*/ |
|
665
|
0
|
|
|
|
|
|
fputs(" GENNF returning 1.0E37\n",stderr); |
|
666
|
0
|
|
|
|
|
|
gennf = 1.0E37; |
|
667
|
0
|
|
|
|
|
|
goto S50; |
|
668
|
6
|
|
|
|
|
|
S40: |
|
669
|
6
|
|
|
|
|
|
gennf = xnum/xden; |
|
670
|
6
|
|
|
|
|
|
S50: |
|
671
|
6
|
|
|
|
|
|
return gennf; |
|
672
|
|
|
|
|
|
|
} |
|
673
|
|
|
|
|
|
|
|
|
674
|
6
|
|
|
|
|
|
double gennor(double av,double sd) |
|
675
|
|
|
|
|
|
|
/* |
|
676
|
|
|
|
|
|
|
********************************************************************** |
|
677
|
|
|
|
|
|
|
double gennor(double av,double sd) |
|
678
|
|
|
|
|
|
|
GENerate random deviate from a NORmal distribution |
|
679
|
|
|
|
|
|
|
Function |
|
680
|
|
|
|
|
|
|
Generates a single random deviate from a normal distribution |
|
681
|
|
|
|
|
|
|
with mean, AV, and standard deviation, SD. |
|
682
|
|
|
|
|
|
|
Arguments |
|
683
|
|
|
|
|
|
|
av --> Mean of the normal distribution. |
|
684
|
|
|
|
|
|
|
sd --> Standard deviation of the normal distribution. |
|
685
|
|
|
|
|
|
|
JJV (sd >= 0) |
|
686
|
|
|
|
|
|
|
Method |
|
687
|
|
|
|
|
|
|
Renames SNORM from TOMS as slightly modified by BWB to use RANF |
|
688
|
|
|
|
|
|
|
instead of SUNIF. |
|
689
|
|
|
|
|
|
|
For details see: |
|
690
|
|
|
|
|
|
|
Ahrens, J.H. and Dieter, U. |
|
691
|
|
|
|
|
|
|
Extensions of Forsythe's Method for Random |
|
692
|
|
|
|
|
|
|
Sampling from the Normal Distribution. |
|
693
|
|
|
|
|
|
|
Math. Comput., 27,124 (Oct. 1973), 927 - 937. |
|
694
|
|
|
|
|
|
|
********************************************************************** |
|
695
|
|
|
|
|
|
|
*/ |
|
696
|
|
|
|
|
|
|
{ |
|
697
|
|
|
|
|
|
|
static double gennor; |
|
698
|
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
/* JJV added argument checker */ |
|
700
|
6
|
50
|
|
|
|
|
if(sd >= 0.0) goto S10; |
|
701
|
0
|
|
|
|
|
|
fputs(" SD < 0 in GENNOR - ABORT\n",stderr); |
|
702
|
0
|
|
|
|
|
|
fprintf(stderr," Value of SD: %16.6E\n",sd); |
|
703
|
0
|
|
|
|
|
|
exit(1); |
|
704
|
6
|
|
|
|
|
|
S10: |
|
705
|
6
|
|
|
|
|
|
gennor = sd*snorm()+av; |
|
706
|
6
|
|
|
|
|
|
return gennor; |
|
707
|
|
|
|
|
|
|
} |
|
708
|
|
|
|
|
|
|
|
|
709
|
4
|
|
|
|
|
|
void genprm(long *iarray,int larray) |
|
710
|
|
|
|
|
|
|
/* |
|
711
|
|
|
|
|
|
|
********************************************************************** |
|
712
|
|
|
|
|
|
|
void genprm(long *iarray,int larray) |
|
713
|
|
|
|
|
|
|
GENerate random PeRMutation of iarray |
|
714
|
|
|
|
|
|
|
Arguments |
|
715
|
|
|
|
|
|
|
iarray <--> On output IARRAY is a random permutation of its |
|
716
|
|
|
|
|
|
|
value on input |
|
717
|
|
|
|
|
|
|
larray <--> Length of IARRAY |
|
718
|
|
|
|
|
|
|
********************************************************************** |
|
719
|
|
|
|
|
|
|
*/ |
|
720
|
|
|
|
|
|
|
{ |
|
721
|
|
|
|
|
|
|
static long i,itmp,iwhich,D1,D2; |
|
722
|
|
|
|
|
|
|
|
|
723
|
38
|
100
|
|
|
|
|
for(i=1,D1=1,D2=(larray-i+D1)/D1; D2>0; D2--,i+=D1) { |
|
724
|
34
|
|
|
|
|
|
iwhich = ignuin(i,larray); |
|
725
|
34
|
|
|
|
|
|
itmp = *(iarray+iwhich-1); |
|
726
|
34
|
|
|
|
|
|
*(iarray+iwhich-1) = *(iarray+i-1); |
|
727
|
34
|
|
|
|
|
|
*(iarray+i-1) = itmp; |
|
728
|
|
|
|
|
|
|
} |
|
729
|
4
|
|
|
|
|
|
} |
|
730
|
|
|
|
|
|
|
|
|
731
|
14
|
|
|
|
|
|
double genunf(double low,double high) |
|
732
|
|
|
|
|
|
|
/* |
|
733
|
|
|
|
|
|
|
********************************************************************** |
|
734
|
|
|
|
|
|
|
double genunf(double low,double high) |
|
735
|
|
|
|
|
|
|
GeNerate Uniform Real between LOW and HIGH |
|
736
|
|
|
|
|
|
|
Function |
|
737
|
|
|
|
|
|
|
Generates a real uniformly distributed between LOW and HIGH. |
|
738
|
|
|
|
|
|
|
Arguments |
|
739
|
|
|
|
|
|
|
low --> Low bound (exclusive) on real value to be generated |
|
740
|
|
|
|
|
|
|
high --> High bound (exclusive) on real value to be generated |
|
741
|
|
|
|
|
|
|
********************************************************************** |
|
742
|
|
|
|
|
|
|
*/ |
|
743
|
|
|
|
|
|
|
{ |
|
744
|
|
|
|
|
|
|
static double genunf; |
|
745
|
|
|
|
|
|
|
|
|
746
|
14
|
50
|
|
|
|
|
if(!(low > high)) goto S10; |
|
747
|
0
|
|
|
|
|
|
fprintf(stderr,"LOW > HIGH in GENUNF: LOW %16.6E HIGH: %16.6E\n",low,high); |
|
748
|
0
|
|
|
|
|
|
fputs("Abort\n",stderr); |
|
749
|
0
|
|
|
|
|
|
exit(1); |
|
750
|
14
|
|
|
|
|
|
S10: |
|
751
|
14
|
|
|
|
|
|
genunf = low+(high-low)*ranf(); |
|
752
|
14
|
|
|
|
|
|
return genunf; |
|
753
|
|
|
|
|
|
|
} |
|
754
|
|
|
|
|
|
|
|
|
755
|
1535
|
|
|
|
|
|
void gscgn(long getset,long *g) |
|
756
|
|
|
|
|
|
|
/* |
|
757
|
|
|
|
|
|
|
********************************************************************** |
|
758
|
|
|
|
|
|
|
void gscgn(long getset,long *g) |
|
759
|
|
|
|
|
|
|
Get/Set GeNerator |
|
760
|
|
|
|
|
|
|
Gets or returns in G the number of the current generator |
|
761
|
|
|
|
|
|
|
Arguments |
|
762
|
|
|
|
|
|
|
getset --> 0 Get |
|
763
|
|
|
|
|
|
|
1 Set |
|
764
|
|
|
|
|
|
|
g <-- Number of the current random number generator (1..32) |
|
765
|
|
|
|
|
|
|
********************************************************************** |
|
766
|
|
|
|
|
|
|
*/ |
|
767
|
|
|
|
|
|
|
{ |
|
768
|
|
|
|
|
|
|
#define numg 32L |
|
769
|
|
|
|
|
|
|
static long curntg = 1; |
|
770
|
1535
|
100
|
|
|
|
|
if(getset == 0) *g = curntg; |
|
771
|
|
|
|
|
|
|
else { |
|
772
|
513
|
50
|
|
|
|
|
if(*g < 0 || *g > numg) { |
|
|
|
50
|
|
|
|
|
|
|
773
|
0
|
|
|
|
|
|
fputs(" Generator number out of range in GSCGN\n",stderr); |
|
774
|
0
|
|
|
|
|
|
exit(0); |
|
775
|
|
|
|
|
|
|
} |
|
776
|
513
|
|
|
|
|
|
curntg = *g; |
|
777
|
|
|
|
|
|
|
} |
|
778
|
|
|
|
|
|
|
#undef numg |
|
779
|
1535
|
|
|
|
|
|
} |
|
780
|
|
|
|
|
|
|
|
|
781
|
1022
|
|
|
|
|
|
void gsrgs(long getset,long *qvalue) |
|
782
|
|
|
|
|
|
|
/* |
|
783
|
|
|
|
|
|
|
********************************************************************** |
|
784
|
|
|
|
|
|
|
void gsrgs(long getset,long *qvalue) |
|
785
|
|
|
|
|
|
|
Get/Set Random Generators Set |
|
786
|
|
|
|
|
|
|
Gets or sets whether random generators set (initialized). |
|
787
|
|
|
|
|
|
|
Initially (data statement) state is not set |
|
788
|
|
|
|
|
|
|
If getset is 1 state is set to qvalue |
|
789
|
|
|
|
|
|
|
If getset is 0 state returned in qvalue |
|
790
|
|
|
|
|
|
|
********************************************************************** |
|
791
|
|
|
|
|
|
|
*/ |
|
792
|
|
|
|
|
|
|
{ |
|
793
|
|
|
|
|
|
|
static long qinit = 0; |
|
794
|
|
|
|
|
|
|
|
|
795
|
1022
|
100
|
|
|
|
|
if(getset == 0) *qvalue = qinit; |
|
796
|
3
|
|
|
|
|
|
else qinit = *qvalue; |
|
797
|
1022
|
|
|
|
|
|
} |
|
798
|
|
|
|
|
|
|
|
|
799
|
485
|
|
|
|
|
|
void gssst(long getset,long *qset) |
|
800
|
|
|
|
|
|
|
/* |
|
801
|
|
|
|
|
|
|
********************************************************************** |
|
802
|
|
|
|
|
|
|
void gssst(long getset,long *qset) |
|
803
|
|
|
|
|
|
|
Get or Set whether Seed is Set |
|
804
|
|
|
|
|
|
|
Initialize to Seed not Set |
|
805
|
|
|
|
|
|
|
If getset is 1 sets state to Seed Set |
|
806
|
|
|
|
|
|
|
If getset is 0 returns T in qset if Seed Set |
|
807
|
|
|
|
|
|
|
Else returns F in qset |
|
808
|
|
|
|
|
|
|
********************************************************************** |
|
809
|
|
|
|
|
|
|
*/ |
|
810
|
|
|
|
|
|
|
{ |
|
811
|
|
|
|
|
|
|
static long qstate = 0; |
|
812
|
485
|
100
|
|
|
|
|
if(getset != 0) qstate = 1; |
|
813
|
469
|
|
|
|
|
|
else *qset = qstate; |
|
814
|
485
|
|
|
|
|
|
} |
|
815
|
|
|
|
|
|
|
|
|
816
|
10
|
|
|
|
|
|
long ignbin(long n,double pp) |
|
817
|
|
|
|
|
|
|
/* |
|
818
|
|
|
|
|
|
|
********************************************************************** |
|
819
|
|
|
|
|
|
|
long ignbin(long n,double pp) |
|
820
|
|
|
|
|
|
|
GENerate BINomial random deviate |
|
821
|
|
|
|
|
|
|
Function |
|
822
|
|
|
|
|
|
|
Generates a single random deviate from a binomial |
|
823
|
|
|
|
|
|
|
distribution whose number of trials is N and whose |
|
824
|
|
|
|
|
|
|
probability of an event in each trial is P. |
|
825
|
|
|
|
|
|
|
Arguments |
|
826
|
|
|
|
|
|
|
n --> The number of trials in the binomial distribution |
|
827
|
|
|
|
|
|
|
from which a random deviate is to be generated. |
|
828
|
|
|
|
|
|
|
JJV (N >= 0) |
|
829
|
|
|
|
|
|
|
pp --> The probability of an event in each trial of the |
|
830
|
|
|
|
|
|
|
binomial distribution from which a random deviate |
|
831
|
|
|
|
|
|
|
is to be generated. |
|
832
|
|
|
|
|
|
|
JJV (0.0 <= PP <= 1.0) |
|
833
|
|
|
|
|
|
|
ignbin <-- A random deviate yielding the number of events |
|
834
|
|
|
|
|
|
|
from N independent trials, each of which has |
|
835
|
|
|
|
|
|
|
a probability of event P. |
|
836
|
|
|
|
|
|
|
Method |
|
837
|
|
|
|
|
|
|
This is algorithm BTPE from: |
|
838
|
|
|
|
|
|
|
Kachitvichyanukul, V. and Schmeiser, B. W. |
|
839
|
|
|
|
|
|
|
Binomial Random Variate Generation. |
|
840
|
|
|
|
|
|
|
Communications of the ACM, 31, 2 |
|
841
|
|
|
|
|
|
|
(February, 1988) 216. |
|
842
|
|
|
|
|
|
|
********************************************************************** |
|
843
|
|
|
|
|
|
|
SUBROUTINE BTPEC(N,PP,ISEED,JX) |
|
844
|
|
|
|
|
|
|
BINOMIAL RANDOM VARIATE GENERATOR |
|
845
|
|
|
|
|
|
|
MEAN .LT. 30 -- INVERSE CDF |
|
846
|
|
|
|
|
|
|
MEAN .GE. 30 -- ALGORITHM BTPE: ACCEPTANCE-REJECTION VIA |
|
847
|
|
|
|
|
|
|
FOUR REGION COMPOSITION. THE FOUR REGIONS ARE A TRIANGLE |
|
848
|
|
|
|
|
|
|
(SYMMETRIC IN THE CENTER), A PAIR OF PARALLELOGRAMS (ABOVE |
|
849
|
|
|
|
|
|
|
THE TRIANGLE), AND EXPONENTIAL LEFT AND RIGHT TAILS. |
|
850
|
|
|
|
|
|
|
BTPE REFERS TO BINOMIAL-TRIANGLE-PARALLELOGRAM-EXPONENTIAL. |
|
851
|
|
|
|
|
|
|
BTPEC REFERS TO BTPE AND "COMBINED." THUS BTPE IS THE |
|
852
|
|
|
|
|
|
|
RESEARCH AND BTPEC IS THE IMPLEMENTATION OF A COMPLETE |
|
853
|
|
|
|
|
|
|
USABLE ALGORITHM. |
|
854
|
|
|
|
|
|
|
REFERENCE: VORATAS KACHITVICHYANUKUL AND BRUCE SCHMEISER, |
|
855
|
|
|
|
|
|
|
"BINOMIAL RANDOM VARIATE GENERATION," |
|
856
|
|
|
|
|
|
|
COMMUNICATIONS OF THE ACM, FORTHCOMING |
|
857
|
|
|
|
|
|
|
WRITTEN: SEPTEMBER 1980. |
|
858
|
|
|
|
|
|
|
LAST REVISED: MAY 1985, JULY 1987 |
|
859
|
|
|
|
|
|
|
REQUIRED SUBPROGRAM: RAND() -- A UNIFORM (0,1) RANDOM NUMBER |
|
860
|
|
|
|
|
|
|
GENERATOR |
|
861
|
|
|
|
|
|
|
ARGUMENTS |
|
862
|
|
|
|
|
|
|
N : NUMBER OF BERNOULLI TRIALS (INPUT) |
|
863
|
|
|
|
|
|
|
PP : PROBABILITY OF SUCCESS IN EACH TRIAL (INPUT) |
|
864
|
|
|
|
|
|
|
ISEED: RANDOM NUMBER SEED (INPUT AND OUTPUT) |
|
865
|
|
|
|
|
|
|
JX: RANDOMLY GENERATED OBSERVATION (OUTPUT) |
|
866
|
|
|
|
|
|
|
VARIABLES |
|
867
|
|
|
|
|
|
|
PSAVE: VALUE OF PP FROM THE LAST CALL TO BTPEC |
|
868
|
|
|
|
|
|
|
NSAVE: VALUE OF N FROM THE LAST CALL TO BTPEC |
|
869
|
|
|
|
|
|
|
XNP: VALUE OF THE MEAN FROM THE LAST CALL TO BTPEC |
|
870
|
|
|
|
|
|
|
P: PROBABILITY USED IN THE GENERATION PHASE OF BTPEC |
|
871
|
|
|
|
|
|
|
FFM: TEMPORARY VARIABLE EQUAL TO XNP + P |
|
872
|
|
|
|
|
|
|
M: INTEGER VALUE OF THE CURRENT MODE |
|
873
|
|
|
|
|
|
|
FM: FLOATING POINT VALUE OF THE CURRENT MODE |
|
874
|
|
|
|
|
|
|
XNPQ: TEMPORARY VARIABLE USED IN SETUP AND SQUEEZING STEPS |
|
875
|
|
|
|
|
|
|
P1: AREA OF THE TRIANGLE |
|
876
|
|
|
|
|
|
|
C: HEIGHT OF THE PARALLELOGRAMS |
|
877
|
|
|
|
|
|
|
XM: CENTER OF THE TRIANGLE |
|
878
|
|
|
|
|
|
|
XL: LEFT END OF THE TRIANGLE |
|
879
|
|
|
|
|
|
|
XR: RIGHT END OF THE TRIANGLE |
|
880
|
|
|
|
|
|
|
AL: TEMPORARY VARIABLE |
|
881
|
|
|
|
|
|
|
XLL: RATE FOR THE LEFT EXPONENTIAL TAIL |
|
882
|
|
|
|
|
|
|
XLR: RATE FOR THE RIGHT EXPONENTIAL TAIL |
|
883
|
|
|
|
|
|
|
P2: AREA OF THE PARALLELOGRAMS |
|
884
|
|
|
|
|
|
|
P3: AREA OF THE LEFT EXPONENTIAL TAIL |
|
885
|
|
|
|
|
|
|
P4: AREA OF THE RIGHT EXPONENTIAL TAIL |
|
886
|
|
|
|
|
|
|
U: A U(0,P4) RANDOM VARIATE USED FIRST TO SELECT ONE OF THE |
|
887
|
|
|
|
|
|
|
FOUR REGIONS AND THEN CONDITIONALLY TO GENERATE A VALUE |
|
888
|
|
|
|
|
|
|
FROM THE REGION |
|
889
|
|
|
|
|
|
|
V: A U(0,1) RANDOM NUMBER USED TO GENERATE THE RANDOM VALUE |
|
890
|
|
|
|
|
|
|
(REGION 1) OR TRANSFORMED INTO THE VARIATE TO ACCEPT OR |
|
891
|
|
|
|
|
|
|
REJECT THE CANDIDATE VALUE |
|
892
|
|
|
|
|
|
|
IX: INTEGER CANDIDATE VALUE |
|
893
|
|
|
|
|
|
|
X: PRELIMINARY CONTINUOUS CANDIDATE VALUE IN REGION 2 LOGIC |
|
894
|
|
|
|
|
|
|
AND A FLOATING POINT IX IN THE ACCEPT/REJECT LOGIC |
|
895
|
|
|
|
|
|
|
K: ABSOLUTE VALUE OF (IX-M) |
|
896
|
|
|
|
|
|
|
F: THE HEIGHT OF THE SCALED DENSITY FUNCTION USED IN THE |
|
897
|
|
|
|
|
|
|
ACCEPT/REJECT DECISION WHEN BOTH M AND IX ARE SMALL |
|
898
|
|
|
|
|
|
|
ALSO USED IN THE INVERSE TRANSFORMATION |
|
899
|
|
|
|
|
|
|
R: THE RATIO P/Q |
|
900
|
|
|
|
|
|
|
G: CONSTANT USED IN CALCULATION OF PROBABILITY |
|
901
|
|
|
|
|
|
|
MP: MODE PLUS ONE, THE LOWER INDEX FOR EXPLICIT CALCULATION |
|
902
|
|
|
|
|
|
|
OF F WHEN IX IS GREATER THAN M |
|
903
|
|
|
|
|
|
|
IX1: CANDIDATE VALUE PLUS ONE, THE LOWER INDEX FOR EXPLICIT |
|
904
|
|
|
|
|
|
|
CALCULATION OF F WHEN IX IS LESS THAN M |
|
905
|
|
|
|
|
|
|
I: INDEX FOR EXPLICIT CALCULATION OF F FOR BTPE |
|
906
|
|
|
|
|
|
|
AMAXP: MAXIMUM ERROR OF THE LOGARITHM OF NORMAL BOUND |
|
907
|
|
|
|
|
|
|
YNORM: LOGARITHM OF NORMAL BOUND |
|
908
|
|
|
|
|
|
|
ALV: NATURAL LOGARITHM OF THE ACCEPT/REJECT VARIATE V |
|
909
|
|
|
|
|
|
|
X1,F1,Z,W,Z2,X2,F2, AND W2 ARE TEMPORARY VARIABLES TO BE |
|
910
|
|
|
|
|
|
|
USED IN THE FINAL ACCEPT/REJECT TEST |
|
911
|
|
|
|
|
|
|
QN: PROBABILITY OF NO SUCCESS IN N TRIALS |
|
912
|
|
|
|
|
|
|
REMARK |
|
913
|
|
|
|
|
|
|
IX AND JX COULD LOGICALLY BE THE SAME VARIABLE, WHICH WOULD |
|
914
|
|
|
|
|
|
|
SAVE A MEMORY POSITION AND A LINE OF CODE. HOWEVER, SOME |
|
915
|
|
|
|
|
|
|
COMPILERS (E.G.,CDC MNF) OPTIMIZE BETTER WHEN THE ARGUMENTS |
|
916
|
|
|
|
|
|
|
ARE NOT INVOLVED. |
|
917
|
|
|
|
|
|
|
ISEED NEEDS TO BE DOUBLE PRECISION IF THE IMSL ROUTINE |
|
918
|
|
|
|
|
|
|
GGUBFS IS USED TO GENERATE UNIFORM RANDOM NUMBER, OTHERWISE |
|
919
|
|
|
|
|
|
|
TYPE OF ISEED SHOULD BE DICTATED BY THE UNIFORM GENERATOR |
|
920
|
|
|
|
|
|
|
********************************************************************** |
|
921
|
|
|
|
|
|
|
*****DETERMINE APPROPRIATE ALGORITHM AND WHETHER SETUP IS NECESSARY |
|
922
|
|
|
|
|
|
|
*/ |
|
923
|
|
|
|
|
|
|
{ |
|
924
|
|
|
|
|
|
|
/* JJV changed initial values to ridiculous values */ |
|
925
|
|
|
|
|
|
|
static double psave = -1.0E37; |
|
926
|
|
|
|
|
|
|
static long nsave = -214748365; |
|
927
|
|
|
|
|
|
|
static long ignbin,i,ix,ix1,k,m,mp,T1; |
|
928
|
|
|
|
|
|
|
static double al,alv,amaxp,c,f,f1,f2,ffm,fm,g,p,p1,p2,p3,p4,q,qn,r,u,v,w,w2,x,x1, |
|
929
|
|
|
|
|
|
|
x2,xl,xll,xlr,xm,xnp,xnpq,xr,ynorm,z,z2; |
|
930
|
|
|
|
|
|
|
|
|
931
|
10
|
100
|
|
|
|
|
if(pp != psave) goto S10; |
|
932
|
4
|
50
|
|
|
|
|
if(n != nsave) goto S20; |
|
933
|
4
|
50
|
|
|
|
|
if(xnp < 30.0) goto S150; |
|
934
|
0
|
|
|
|
|
|
goto S30; |
|
935
|
6
|
|
|
|
|
|
S10: |
|
936
|
|
|
|
|
|
|
/* |
|
937
|
|
|
|
|
|
|
*****SETUP, PERFORM ONLY WHEN PARAMETERS CHANGE |
|
938
|
|
|
|
|
|
|
JJV added checks to ensure 0.0 <= PP <= 1.0 |
|
939
|
|
|
|
|
|
|
*/ |
|
940
|
6
|
50
|
|
|
|
|
if(pp < 0.0F) ftnstop("PP < 0.0 in IGNBIN"); |
|
941
|
6
|
50
|
|
|
|
|
if(pp > 1.0F) ftnstop("PP > 1.0 in IGNBIN"); |
|
942
|
6
|
|
|
|
|
|
psave = pp; |
|
943
|
6
|
100
|
|
|
|
|
p = min(psave,1.0-psave); |
|
944
|
6
|
|
|
|
|
|
q = 1.0-p; |
|
945
|
6
|
|
|
|
|
|
S20: |
|
946
|
|
|
|
|
|
|
/* |
|
947
|
|
|
|
|
|
|
JJV added check to ensure N >= 0 |
|
948
|
|
|
|
|
|
|
*/ |
|
949
|
6
|
50
|
|
|
|
|
if(n < 0L) ftnstop("N < 0 in IGNBIN"); |
|
950
|
6
|
|
|
|
|
|
xnp = n*p; |
|
951
|
6
|
|
|
|
|
|
nsave = n; |
|
952
|
6
|
50
|
|
|
|
|
if(xnp < 30.0) goto S140; |
|
953
|
0
|
|
|
|
|
|
ffm = xnp+p; |
|
954
|
0
|
|
|
|
|
|
m = ffm; |
|
955
|
0
|
|
|
|
|
|
fm = m; |
|
956
|
0
|
|
|
|
|
|
xnpq = xnp*q; |
|
957
|
0
|
|
|
|
|
|
p1 = (long) (2.195*sqrt(xnpq)-4.6*q)+0.5; |
|
958
|
0
|
|
|
|
|
|
xm = fm+0.5; |
|
959
|
0
|
|
|
|
|
|
xl = xm-p1; |
|
960
|
0
|
|
|
|
|
|
xr = xm+p1; |
|
961
|
0
|
|
|
|
|
|
c = 0.134+20.5/(15.3+fm); |
|
962
|
0
|
|
|
|
|
|
al = (ffm-xl)/(ffm-xl*p); |
|
963
|
0
|
|
|
|
|
|
xll = al*(1.0+0.5*al); |
|
964
|
0
|
|
|
|
|
|
al = (xr-ffm)/(xr*q); |
|
965
|
0
|
|
|
|
|
|
xlr = al*(1.0+0.5*al); |
|
966
|
0
|
|
|
|
|
|
p2 = p1*(1.0+c+c); |
|
967
|
0
|
|
|
|
|
|
p3 = p2+c/xll; |
|
968
|
0
|
|
|
|
|
|
p4 = p3+c/xlr; |
|
969
|
0
|
|
|
|
|
|
S30: |
|
970
|
|
|
|
|
|
|
/* |
|
971
|
|
|
|
|
|
|
*****GENERATE VARIATE |
|
972
|
|
|
|
|
|
|
*/ |
|
973
|
0
|
|
|
|
|
|
u = ranf()*p4; |
|
974
|
0
|
|
|
|
|
|
v = ranf(); |
|
975
|
|
|
|
|
|
|
/* |
|
976
|
|
|
|
|
|
|
TRIANGULAR REGION |
|
977
|
|
|
|
|
|
|
*/ |
|
978
|
0
|
0
|
|
|
|
|
if(u > p1) goto S40; |
|
979
|
0
|
|
|
|
|
|
ix = xm-p1*v+u; |
|
980
|
0
|
|
|
|
|
|
goto S170; |
|
981
|
0
|
|
|
|
|
|
S40: |
|
982
|
|
|
|
|
|
|
/* |
|
983
|
|
|
|
|
|
|
PARALLELOGRAM REGION |
|
984
|
|
|
|
|
|
|
*/ |
|
985
|
0
|
0
|
|
|
|
|
if(u > p2) goto S50; |
|
986
|
0
|
|
|
|
|
|
x = xl+(u-p1)/c; |
|
987
|
0
|
0
|
|
|
|
|
v = v*c+1.0-ABS(xm-x)/p1; |
|
988
|
0
|
0
|
|
|
|
|
if(v > 1.0 || v <= 0.0) goto S30; |
|
|
|
0
|
|
|
|
|
|
|
989
|
0
|
|
|
|
|
|
ix = x; |
|
990
|
0
|
|
|
|
|
|
goto S70; |
|
991
|
0
|
|
|
|
|
|
S50: |
|
992
|
|
|
|
|
|
|
/* |
|
993
|
|
|
|
|
|
|
LEFT TAIL |
|
994
|
|
|
|
|
|
|
*/ |
|
995
|
0
|
0
|
|
|
|
|
if(u > p3) goto S60; |
|
996
|
0
|
|
|
|
|
|
ix = xl+log(v)/xll; |
|
997
|
0
|
0
|
|
|
|
|
if(ix < 0) goto S30; |
|
998
|
0
|
|
|
|
|
|
v *= ((u-p2)*xll); |
|
999
|
0
|
|
|
|
|
|
goto S70; |
|
1000
|
0
|
|
|
|
|
|
S60: |
|
1001
|
|
|
|
|
|
|
/* |
|
1002
|
|
|
|
|
|
|
RIGHT TAIL |
|
1003
|
|
|
|
|
|
|
*/ |
|
1004
|
0
|
|
|
|
|
|
ix = xr-log(v)/xlr; |
|
1005
|
0
|
0
|
|
|
|
|
if(ix > n) goto S30; |
|
1006
|
0
|
|
|
|
|
|
v *= ((u-p3)*xlr); |
|
1007
|
0
|
|
|
|
|
|
S70: |
|
1008
|
|
|
|
|
|
|
/* |
|
1009
|
|
|
|
|
|
|
*****DETERMINE APPROPRIATE WAY TO PERFORM ACCEPT/REJECT TEST |
|
1010
|
|
|
|
|
|
|
*/ |
|
1011
|
0
|
|
|
|
|
|
k = ABS(ix-m); |
|
1012
|
0
|
0
|
|
|
|
|
if(k > 20 && k < xnpq/2-1) goto S130; |
|
|
|
0
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
/* |
|
1014
|
|
|
|
|
|
|
EXPLICIT EVALUATION |
|
1015
|
|
|
|
|
|
|
*/ |
|
1016
|
0
|
|
|
|
|
|
f = 1.0; |
|
1017
|
0
|
|
|
|
|
|
r = p/q; |
|
1018
|
0
|
|
|
|
|
|
g = (n+1)*r; |
|
1019
|
0
|
|
|
|
|
|
T1 = m-ix; |
|
1020
|
0
|
0
|
|
|
|
|
if(T1 < 0) goto S80; |
|
1021
|
0
|
0
|
|
|
|
|
else if(T1 == 0) goto S120; |
|
1022
|
0
|
|
|
|
|
|
else goto S100; |
|
1023
|
0
|
|
|
|
|
|
S80: |
|
1024
|
0
|
|
|
|
|
|
mp = m+1; |
|
1025
|
0
|
0
|
|
|
|
|
for(i=mp; i<=ix; i++) f *= (g/i-r); |
|
1026
|
0
|
|
|
|
|
|
goto S120; |
|
1027
|
0
|
|
|
|
|
|
S100: |
|
1028
|
0
|
|
|
|
|
|
ix1 = ix+1; |
|
1029
|
0
|
0
|
|
|
|
|
for(i=ix1; i<=m; i++) f /= (g/i-r); |
|
1030
|
0
|
|
|
|
|
|
S120: |
|
1031
|
0
|
0
|
|
|
|
|
if(v <= f) goto S170; |
|
1032
|
0
|
|
|
|
|
|
goto S30; |
|
1033
|
0
|
|
|
|
|
|
S130: |
|
1034
|
|
|
|
|
|
|
/* |
|
1035
|
|
|
|
|
|
|
SQUEEZING USING UPPER AND LOWER BOUNDS ON ALOG(F(X)) |
|
1036
|
|
|
|
|
|
|
*/ |
|
1037
|
0
|
|
|
|
|
|
amaxp = k/xnpq*((k*(k/3.0+0.625)+0.1666666666666)/xnpq+0.5); |
|
1038
|
0
|
|
|
|
|
|
ynorm = -(k*k/(2.0*xnpq)); |
|
1039
|
0
|
|
|
|
|
|
alv = log(v); |
|
1040
|
0
|
0
|
|
|
|
|
if(alv < ynorm-amaxp) goto S170; |
|
1041
|
0
|
0
|
|
|
|
|
if(alv > ynorm+amaxp) goto S30; |
|
1042
|
|
|
|
|
|
|
/* |
|
1043
|
|
|
|
|
|
|
STIRLING'S FORMULA TO MACHINE ACCURACY FOR |
|
1044
|
|
|
|
|
|
|
THE FINAL ACCEPTANCE/REJECTION TEST |
|
1045
|
|
|
|
|
|
|
*/ |
|
1046
|
0
|
|
|
|
|
|
x1 = ix+1.0; |
|
1047
|
0
|
|
|
|
|
|
f1 = fm+1.0; |
|
1048
|
0
|
|
|
|
|
|
z = n+1.0-fm; |
|
1049
|
0
|
|
|
|
|
|
w = n-ix+1.0; |
|
1050
|
0
|
|
|
|
|
|
z2 = z*z; |
|
1051
|
0
|
|
|
|
|
|
x2 = x1*x1; |
|
1052
|
0
|
|
|
|
|
|
f2 = f1*f1; |
|
1053
|
0
|
|
|
|
|
|
w2 = w*w; |
|
1054
|
0
|
|
|
|
|
|
if(alv <= xm*log(f1/x1)+(n-m+0.5)*log(z/w)+(ix-m)*log(w*p/(x1*q))+(13860.0- |
|
1055
|
0
|
|
|
|
|
|
(462.0-(132.0-(99.0-140.0/f2)/f2)/f2)/f2)/f1/166320.0+(13860.0-(462.0- |
|
1056
|
0
|
|
|
|
|
|
(132.0-(99.0-140.0/z2)/z2)/z2)/z2)/z/166320.0+(13860.0-(462.0-(132.0- |
|
1057
|
0
|
|
|
|
|
|
(99.0-140.0/x2)/x2)/x2)/x2)/x1/166320.0+(13860.0-(462.0-(132.0-(99.0 |
|
1058
|
0
|
0
|
|
|
|
|
-140.0/w2)/w2)/w2)/w2)/w/166320.0) goto S170; |
|
1059
|
0
|
|
|
|
|
|
goto S30; |
|
1060
|
6
|
|
|
|
|
|
S140: |
|
1061
|
|
|
|
|
|
|
/* |
|
1062
|
|
|
|
|
|
|
INVERSE CDF LOGIC FOR MEAN LESS THAN 30 |
|
1063
|
|
|
|
|
|
|
*/ |
|
1064
|
|
|
|
|
|
|
/* The following change was recommended by Paul B. to get around an |
|
1065
|
|
|
|
|
|
|
error when using gcc under AIX. 2006-09-12. */ |
|
1066
|
|
|
|
|
|
|
/** qn = pow(q,(double)n); <- OLD **/ |
|
1067
|
6
|
|
|
|
|
|
qn = exp( (double)n * log(q) ); |
|
1068
|
6
|
|
|
|
|
|
r = p/q; |
|
1069
|
6
|
|
|
|
|
|
g = r*(n+1); |
|
1070
|
10
|
|
|
|
|
|
S150: |
|
1071
|
10
|
|
|
|
|
|
ix = 0; |
|
1072
|
10
|
|
|
|
|
|
f = qn; |
|
1073
|
10
|
|
|
|
|
|
u = ranf(); |
|
1074
|
86
|
|
|
|
|
|
S160: |
|
1075
|
86
|
100
|
|
|
|
|
if(u < f) goto S170; |
|
1076
|
76
|
50
|
|
|
|
|
if(ix > 110) goto S150; |
|
1077
|
76
|
|
|
|
|
|
u -= f; |
|
1078
|
76
|
|
|
|
|
|
ix += 1; |
|
1079
|
76
|
|
|
|
|
|
f *= (g/ix-r); |
|
1080
|
76
|
|
|
|
|
|
goto S160; |
|
1081
|
10
|
|
|
|
|
|
S170: |
|
1082
|
10
|
100
|
|
|
|
|
if(psave > 0.5) ix = n-ix; |
|
1083
|
10
|
|
|
|
|
|
ignbin = ix; |
|
1084
|
10
|
|
|
|
|
|
return ignbin; |
|
1085
|
|
|
|
|
|
|
} |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
6
|
|
|
|
|
|
long ignnbn(long n,double p) |
|
1088
|
|
|
|
|
|
|
/* |
|
1089
|
|
|
|
|
|
|
********************************************************************** |
|
1090
|
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
long ignnbn(long n,double p) |
|
1092
|
|
|
|
|
|
|
GENerate Negative BiNomial random deviate |
|
1093
|
|
|
|
|
|
|
Function |
|
1094
|
|
|
|
|
|
|
Generates a single random deviate from a negative binomial |
|
1095
|
|
|
|
|
|
|
distribution. |
|
1096
|
|
|
|
|
|
|
Arguments |
|
1097
|
|
|
|
|
|
|
N --> The number of trials in the negative binomial distribution |
|
1098
|
|
|
|
|
|
|
from which a random deviate is to be generated. |
|
1099
|
|
|
|
|
|
|
JJV (N > 0) |
|
1100
|
|
|
|
|
|
|
P --> The probability of an event. |
|
1101
|
|
|
|
|
|
|
JJV (0.0 < P < 1.0) |
|
1102
|
|
|
|
|
|
|
Method |
|
1103
|
|
|
|
|
|
|
Algorithm from page 480 of |
|
1104
|
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
Devroye, Luc |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
Non-Uniform Random Variate Generation. Springer-Verlag, |
|
1108
|
|
|
|
|
|
|
New York, 1986. |
|
1109
|
|
|
|
|
|
|
********************************************************************** |
|
1110
|
|
|
|
|
|
|
*/ |
|
1111
|
|
|
|
|
|
|
{ |
|
1112
|
|
|
|
|
|
|
static long ignnbn; |
|
1113
|
|
|
|
|
|
|
static double y,a,r; |
|
1114
|
|
|
|
|
|
|
/* |
|
1115
|
|
|
|
|
|
|
.. |
|
1116
|
|
|
|
|
|
|
.. Executable Statements .. |
|
1117
|
|
|
|
|
|
|
*/ |
|
1118
|
|
|
|
|
|
|
/* |
|
1119
|
|
|
|
|
|
|
Check Arguments |
|
1120
|
|
|
|
|
|
|
*/ |
|
1121
|
6
|
50
|
|
|
|
|
if(n <= 0L) ftnstop("N <= 0 in IGNNBN"); |
|
1122
|
6
|
50
|
|
|
|
|
if(p <= 0.0F) ftnstop("P <= 0.0 in IGNNBN"); |
|
1123
|
6
|
50
|
|
|
|
|
if(p >= 1.0F) ftnstop("P >= 1.0 in IGNNBN"); |
|
1124
|
|
|
|
|
|
|
/* |
|
1125
|
|
|
|
|
|
|
Generate Y, a random gamma (n,(1-p)/p) variable |
|
1126
|
|
|
|
|
|
|
JJV Note: the above parametrization is consistent with Devroye, |
|
1127
|
|
|
|
|
|
|
JJV but gamma (p/(1-p),n) is the equivalent in our code |
|
1128
|
|
|
|
|
|
|
*/ |
|
1129
|
6
|
|
|
|
|
|
r = (double)n; |
|
1130
|
6
|
|
|
|
|
|
a = p/(1.0F-p); |
|
1131
|
|
|
|
|
|
|
/* |
|
1132
|
|
|
|
|
|
|
* JJV changed this to call SGAMMA directly |
|
1133
|
|
|
|
|
|
|
* y = gengam(a,r); <- OLD |
|
1134
|
|
|
|
|
|
|
*/ |
|
1135
|
6
|
|
|
|
|
|
y = sgamma(r)/a; |
|
1136
|
|
|
|
|
|
|
/* |
|
1137
|
|
|
|
|
|
|
Generate a random Poisson(y) variable |
|
1138
|
|
|
|
|
|
|
*/ |
|
1139
|
6
|
|
|
|
|
|
ignnbn = ignpoi(y); |
|
1140
|
6
|
|
|
|
|
|
return ignnbn; |
|
1141
|
|
|
|
|
|
|
} |
|
1142
|
|
|
|
|
|
|
|
|
1143
|
12
|
|
|
|
|
|
long ignpoi(double mu) |
|
1144
|
|
|
|
|
|
|
/* |
|
1145
|
|
|
|
|
|
|
********************************************************************** |
|
1146
|
|
|
|
|
|
|
long ignpoi(double mu) |
|
1147
|
|
|
|
|
|
|
GENerate POIsson random deviate |
|
1148
|
|
|
|
|
|
|
Function |
|
1149
|
|
|
|
|
|
|
Generates a single random deviate from a Poisson |
|
1150
|
|
|
|
|
|
|
distribution with mean MU. |
|
1151
|
|
|
|
|
|
|
Arguments |
|
1152
|
|
|
|
|
|
|
mu --> The mean of the Poisson distribution from which |
|
1153
|
|
|
|
|
|
|
a random deviate is to be generated. |
|
1154
|
|
|
|
|
|
|
(mu >= 0.0) |
|
1155
|
|
|
|
|
|
|
ignpoi <-- The random deviate. |
|
1156
|
|
|
|
|
|
|
Method |
|
1157
|
|
|
|
|
|
|
Renames KPOIS from TOMS as slightly modified by BWB to use RANF |
|
1158
|
|
|
|
|
|
|
instead of SUNIF. |
|
1159
|
|
|
|
|
|
|
For details see: |
|
1160
|
|
|
|
|
|
|
Ahrens, J.H. and Dieter, U. |
|
1161
|
|
|
|
|
|
|
Computer Generation of Poisson Deviates |
|
1162
|
|
|
|
|
|
|
From Modified Normal Distributions. |
|
1163
|
|
|
|
|
|
|
ACM Trans. Math. Software, 8, 2 |
|
1164
|
|
|
|
|
|
|
(June 1982),163-179 |
|
1165
|
|
|
|
|
|
|
********************************************************************** |
|
1166
|
|
|
|
|
|
|
********************************************************************** |
|
1167
|
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
P O I S S O N DISTRIBUTION |
|
1170
|
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
********************************************************************** |
|
1173
|
|
|
|
|
|
|
********************************************************************** |
|
1174
|
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
FOR DETAILS SEE: |
|
1176
|
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
AHRENS, J.H. AND DIETER, U. |
|
1178
|
|
|
|
|
|
|
COMPUTER GENERATION OF POISSON DEVIATES |
|
1179
|
|
|
|
|
|
|
FROM MODIFIED NORMAL DISTRIBUTIONS. |
|
1180
|
|
|
|
|
|
|
ACM TRANS. MATH. SOFTWARE, 8,2 (JUNE 1982), 163 - 179. |
|
1181
|
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
(SLIGHTLY MODIFIED VERSION OF THE PROGRAM IN THE ABOVE ARTICLE) |
|
1183
|
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
********************************************************************** |
|
1185
|
|
|
|
|
|
|
INTEGER FUNCTION IGNPOI(IR,MU) |
|
1186
|
|
|
|
|
|
|
INPUT: IR=CURRENT STATE OF BASIC RANDOM NUMBER GENERATOR |
|
1187
|
|
|
|
|
|
|
MU=MEAN MU OF THE POISSON DISTRIBUTION |
|
1188
|
|
|
|
|
|
|
OUTPUT: IGNPOI=SAMPLE FROM THE POISSON-(MU)-DISTRIBUTION |
|
1189
|
|
|
|
|
|
|
MUPREV=PREVIOUS MU, MUOLD=MU AT LAST EXECUTION OF STEP P OR B. |
|
1190
|
|
|
|
|
|
|
TABLES: COEFFICIENTS A0-A7 FOR STEP F. FACTORIALS FACT |
|
1191
|
|
|
|
|
|
|
COEFFICIENTS A(K) - FOR PX = FK*V*V*SUM(A(K)*V**K)-DEL |
|
1192
|
|
|
|
|
|
|
SEPARATION OF CASES A AND B |
|
1193
|
|
|
|
|
|
|
*/ |
|
1194
|
|
|
|
|
|
|
{ |
|
1195
|
|
|
|
|
|
|
extern double fsign( double num, double sign ); |
|
1196
|
|
|
|
|
|
|
static double a0 = -0.5; |
|
1197
|
|
|
|
|
|
|
static double a1 = 0.3333333343; |
|
1198
|
|
|
|
|
|
|
static double a2 = -0.2499998565; |
|
1199
|
|
|
|
|
|
|
static double a3 = 0.1999997049; |
|
1200
|
|
|
|
|
|
|
static double a4 = -0.1666848753; |
|
1201
|
|
|
|
|
|
|
static double a5 = 0.1428833286; |
|
1202
|
|
|
|
|
|
|
static double a6 = -0.1241963125; |
|
1203
|
|
|
|
|
|
|
static double a7 = 0.1101687109; |
|
1204
|
|
|
|
|
|
|
static double a8 = -0.1142650302; |
|
1205
|
|
|
|
|
|
|
static double a9 = 0.1055093006; |
|
1206
|
|
|
|
|
|
|
/* JJV changed the initial values of MUPREV and MUOLD */ |
|
1207
|
|
|
|
|
|
|
static double muold = -1.0E37; |
|
1208
|
|
|
|
|
|
|
static double muprev = -1.0E37; |
|
1209
|
|
|
|
|
|
|
static double fact[10] = { |
|
1210
|
|
|
|
|
|
|
1.0,1.0,2.0,6.0,24.0,120.0,720.0,5040.0,40320.0,362880.0 |
|
1211
|
|
|
|
|
|
|
}; |
|
1212
|
|
|
|
|
|
|
/* JJV added ll to the list, for Case A */ |
|
1213
|
|
|
|
|
|
|
static long ignpoi,j,k,kflag,l,ll,m; |
|
1214
|
|
|
|
|
|
|
static double b1,b2,c,c0,c1,c2,c3,d,del,difmuk,e,fk,fx,fy,g,omega,p,p0,px,py,q,s, |
|
1215
|
|
|
|
|
|
|
t,u,v,x,xx,pp[35]; |
|
1216
|
|
|
|
|
|
|
|
|
1217
|
12
|
100
|
|
|
|
|
if(mu == muprev) goto S10; |
|
1218
|
8
|
100
|
|
|
|
|
if(mu < 10.0) goto S120; |
|
1219
|
|
|
|
|
|
|
/* |
|
1220
|
|
|
|
|
|
|
C A S E A. (RECALCULATION OF S,D,LL IF MU HAS CHANGED) |
|
1221
|
|
|
|
|
|
|
JJV changed l in Case A to ll |
|
1222
|
|
|
|
|
|
|
*/ |
|
1223
|
2
|
|
|
|
|
|
muprev = mu; |
|
1224
|
2
|
|
|
|
|
|
s = sqrt(mu); |
|
1225
|
2
|
|
|
|
|
|
d = 6.0*mu*mu; |
|
1226
|
|
|
|
|
|
|
/* |
|
1227
|
|
|
|
|
|
|
THE POISSON PROBABILITIES PK EXCEED THE DISCRETE NORMAL |
|
1228
|
|
|
|
|
|
|
PROBABILITIES FK WHENEVER K >= M(MU). LL=IFIX(MU-1.1484) |
|
1229
|
|
|
|
|
|
|
IS AN UPPER BOUND TO M(MU) FOR ALL MU >= 10 . |
|
1230
|
|
|
|
|
|
|
*/ |
|
1231
|
2
|
|
|
|
|
|
ll = (long) (mu-1.1484); |
|
1232
|
6
|
|
|
|
|
|
S10: |
|
1233
|
|
|
|
|
|
|
/* |
|
1234
|
|
|
|
|
|
|
STEP N. NORMAL SAMPLE - SNORM(IR) FOR STANDARD NORMAL DEVIATE |
|
1235
|
|
|
|
|
|
|
*/ |
|
1236
|
6
|
|
|
|
|
|
g = mu+s*snorm(); |
|
1237
|
6
|
50
|
|
|
|
|
if(g < 0.0) goto S20; |
|
1238
|
6
|
|
|
|
|
|
ignpoi = (long) (g); |
|
1239
|
|
|
|
|
|
|
/* |
|
1240
|
|
|
|
|
|
|
STEP I. IMMEDIATE ACCEPTANCE IF IGNPOI IS LARGE ENOUGH |
|
1241
|
|
|
|
|
|
|
*/ |
|
1242
|
6
|
100
|
|
|
|
|
if(ignpoi >= ll) return ignpoi; |
|
1243
|
|
|
|
|
|
|
/* |
|
1244
|
|
|
|
|
|
|
STEP S. SQUEEZE ACCEPTANCE - SUNIF(IR) FOR (0,1)-SAMPLE U |
|
1245
|
|
|
|
|
|
|
*/ |
|
1246
|
4
|
|
|
|
|
|
fk = (double)ignpoi; |
|
1247
|
4
|
|
|
|
|
|
difmuk = mu-fk; |
|
1248
|
4
|
|
|
|
|
|
u = ranf(); |
|
1249
|
4
|
50
|
|
|
|
|
if(d*u >= difmuk*difmuk*difmuk) return ignpoi; |
|
1250
|
0
|
|
|
|
|
|
S20: |
|
1251
|
|
|
|
|
|
|
/* |
|
1252
|
|
|
|
|
|
|
STEP P. PREPARATIONS FOR STEPS Q AND H. |
|
1253
|
|
|
|
|
|
|
(RECALCULATIONS OF PARAMETERS IF NECESSARY) |
|
1254
|
|
|
|
|
|
|
.3989423=(2*PI)**(-.5) .416667E-1=1./24. .1428571=1./7. |
|
1255
|
|
|
|
|
|
|
THE QUANTITIES B1, B2, C3, C2, C1, C0 ARE FOR THE HERMITE |
|
1256
|
|
|
|
|
|
|
APPROXIMATIONS TO THE DISCRETE NORMAL PROBABILITIES FK. |
|
1257
|
|
|
|
|
|
|
C=.1069/MU GUARANTEES MAJORIZATION BY THE 'HAT'-FUNCTION. |
|
1258
|
|
|
|
|
|
|
*/ |
|
1259
|
0
|
0
|
|
|
|
|
if(mu == muold) goto S30; |
|
1260
|
0
|
|
|
|
|
|
muold = mu; |
|
1261
|
0
|
|
|
|
|
|
omega = 0.398942280401433/s; |
|
1262
|
0
|
|
|
|
|
|
b1 = 4.16666666666667E-2/mu; |
|
1263
|
0
|
|
|
|
|
|
b2 = 0.3*b1*b1; |
|
1264
|
0
|
|
|
|
|
|
c3 = 0.142857142857143*b1*b2; |
|
1265
|
0
|
|
|
|
|
|
c2 = b2-15.0*c3; |
|
1266
|
0
|
|
|
|
|
|
c1 = b1-6.0*b2+45.0*c3; |
|
1267
|
0
|
|
|
|
|
|
c0 = 1.0-b1+3.0*b2-15.0*c3; |
|
1268
|
0
|
|
|
|
|
|
c = 0.1069/mu; |
|
1269
|
0
|
|
|
|
|
|
S30: |
|
1270
|
0
|
0
|
|
|
|
|
if(g < 0.0) goto S50; |
|
1271
|
|
|
|
|
|
|
/* |
|
1272
|
|
|
|
|
|
|
'SUBROUTINE' F IS CALLED (KFLAG=0 FOR CORRECT RETURN) |
|
1273
|
|
|
|
|
|
|
*/ |
|
1274
|
0
|
|
|
|
|
|
kflag = 0; |
|
1275
|
0
|
|
|
|
|
|
goto S70; |
|
1276
|
0
|
|
|
|
|
|
S40: |
|
1277
|
|
|
|
|
|
|
/* |
|
1278
|
|
|
|
|
|
|
STEP Q. QUOTIENT ACCEPTANCE (RARE CASE) |
|
1279
|
|
|
|
|
|
|
*/ |
|
1280
|
0
|
0
|
|
|
|
|
if(fy-u*fy <= py*exp(px-fx)) return ignpoi; |
|
1281
|
0
|
|
|
|
|
|
S50: |
|
1282
|
|
|
|
|
|
|
/* |
|
1283
|
|
|
|
|
|
|
STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL |
|
1284
|
|
|
|
|
|
|
DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT' |
|
1285
|
|
|
|
|
|
|
(IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.) |
|
1286
|
|
|
|
|
|
|
*/ |
|
1287
|
0
|
|
|
|
|
|
e = sexpo(); |
|
1288
|
0
|
|
|
|
|
|
u = ranf(); |
|
1289
|
0
|
|
|
|
|
|
u += (u-1.0); |
|
1290
|
0
|
|
|
|
|
|
t = 1.8+fsign(e,u); |
|
1291
|
0
|
0
|
|
|
|
|
if(t <= -0.6744) goto S50; |
|
1292
|
0
|
|
|
|
|
|
ignpoi = (long) (mu+s*t); |
|
1293
|
0
|
|
|
|
|
|
fk = (double)ignpoi; |
|
1294
|
0
|
|
|
|
|
|
difmuk = mu-fk; |
|
1295
|
|
|
|
|
|
|
/* |
|
1296
|
|
|
|
|
|
|
'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN) |
|
1297
|
|
|
|
|
|
|
*/ |
|
1298
|
0
|
|
|
|
|
|
kflag = 1; |
|
1299
|
0
|
|
|
|
|
|
goto S70; |
|
1300
|
0
|
|
|
|
|
|
S60: |
|
1301
|
|
|
|
|
|
|
/* |
|
1302
|
|
|
|
|
|
|
STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION) |
|
1303
|
|
|
|
|
|
|
*/ |
|
1304
|
0
|
0
|
|
|
|
|
if(c*fabs(u) > py*exp(px+e)-fy*exp(fx+e)) goto S50; |
|
1305
|
0
|
|
|
|
|
|
return ignpoi; |
|
1306
|
0
|
|
|
|
|
|
S70: |
|
1307
|
|
|
|
|
|
|
/* |
|
1308
|
|
|
|
|
|
|
STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY. |
|
1309
|
|
|
|
|
|
|
CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT |
|
1310
|
|
|
|
|
|
|
*/ |
|
1311
|
0
|
0
|
|
|
|
|
if(ignpoi >= 10) goto S80; |
|
1312
|
0
|
|
|
|
|
|
px = -mu; |
|
1313
|
0
|
|
|
|
|
|
py = pow(mu,(double)ignpoi)/ *(fact+ignpoi); |
|
1314
|
0
|
|
|
|
|
|
goto S110; |
|
1315
|
0
|
|
|
|
|
|
S80: |
|
1316
|
|
|
|
|
|
|
/* |
|
1317
|
|
|
|
|
|
|
CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION |
|
1318
|
|
|
|
|
|
|
A0-A7 FOR ACCURACY WHEN ADVISABLE |
|
1319
|
|
|
|
|
|
|
.8333333E-1=1./12. .3989423=(2*PI)**(-.5) |
|
1320
|
|
|
|
|
|
|
*/ |
|
1321
|
0
|
|
|
|
|
|
del = 8.33333333E-2/fk; |
|
1322
|
0
|
|
|
|
|
|
del -= (4.8*del*del*del); |
|
1323
|
0
|
|
|
|
|
|
v = difmuk/fk; |
|
1324
|
0
|
0
|
|
|
|
|
if(fabs(v) <= 0.25) goto S90; |
|
1325
|
0
|
|
|
|
|
|
px = fk*log(1.0+v)-difmuk-del; |
|
1326
|
0
|
|
|
|
|
|
goto S100; |
|
1327
|
0
|
|
|
|
|
|
S90: |
|
1328
|
0
|
|
|
|
|
|
px = fk*v*v*((((((((a8*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0)-del; |
|
1329
|
0
|
|
|
|
|
|
S100: |
|
1330
|
0
|
|
|
|
|
|
py = 0.398942280401433/sqrt(fk); |
|
1331
|
0
|
|
|
|
|
|
S110: |
|
1332
|
0
|
|
|
|
|
|
x = (0.5-difmuk)/s; |
|
1333
|
0
|
|
|
|
|
|
xx = x*x; |
|
1334
|
0
|
|
|
|
|
|
fx = -0.5*xx; |
|
1335
|
0
|
|
|
|
|
|
fy = omega*(((c3*xx+c2)*xx+c1)*xx+c0); |
|
1336
|
0
|
0
|
|
|
|
|
if(kflag <= 0) goto S40; |
|
1337
|
0
|
|
|
|
|
|
goto S60; |
|
1338
|
6
|
|
|
|
|
|
S120: |
|
1339
|
|
|
|
|
|
|
/* |
|
1340
|
|
|
|
|
|
|
C A S E B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY) |
|
1341
|
|
|
|
|
|
|
JJV changed MUPREV assignment to initial value |
|
1342
|
|
|
|
|
|
|
*/ |
|
1343
|
6
|
|
|
|
|
|
muprev = -1.0E37; |
|
1344
|
6
|
50
|
|
|
|
|
if(mu == muold) goto S130; |
|
1345
|
|
|
|
|
|
|
/* JJV added argument checker here */ |
|
1346
|
6
|
50
|
|
|
|
|
if(mu >= 0.0) goto S125; |
|
1347
|
0
|
|
|
|
|
|
fprintf(stderr,"MU < 0 in IGNPOI: MU %16.6E\n",mu); |
|
1348
|
0
|
|
|
|
|
|
fputs("Abort\n",stderr); |
|
1349
|
0
|
|
|
|
|
|
exit(1); |
|
1350
|
6
|
|
|
|
|
|
S125: |
|
1351
|
6
|
|
|
|
|
|
muold = mu; |
|
1352
|
6
|
|
|
|
|
|
m = max(1L,(long) (mu)); |
|
1353
|
6
|
|
|
|
|
|
l = 0; |
|
1354
|
6
|
|
|
|
|
|
p = exp(-mu); |
|
1355
|
6
|
|
|
|
|
|
q = p0 = p; |
|
1356
|
0
|
|
|
|
|
|
S130: |
|
1357
|
|
|
|
|
|
|
/* |
|
1358
|
|
|
|
|
|
|
STEP U. UNIFORM SAMPLE FOR INVERSION METHOD |
|
1359
|
|
|
|
|
|
|
*/ |
|
1360
|
6
|
|
|
|
|
|
u = ranf(); |
|
1361
|
6
|
|
|
|
|
|
ignpoi = 0; |
|
1362
|
6
|
100
|
|
|
|
|
if(u <= p0) return ignpoi; |
|
1363
|
|
|
|
|
|
|
/* |
|
1364
|
|
|
|
|
|
|
STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE |
|
1365
|
|
|
|
|
|
|
PP-TABLE OF CUMULATIVE POISSON PROBABILITIES |
|
1366
|
|
|
|
|
|
|
(0.458=PP(9) FOR MU=10) |
|
1367
|
|
|
|
|
|
|
*/ |
|
1368
|
4
|
50
|
|
|
|
|
if(l == 0) goto S150; |
|
1369
|
0
|
|
|
|
|
|
j = 1; |
|
1370
|
0
|
0
|
|
|
|
|
if(u > 0.458) j = min(l,m); |
|
1371
|
0
|
0
|
|
|
|
|
for(k=j; k<=l; k++) { |
|
1372
|
0
|
0
|
|
|
|
|
if(u <= *(pp+k-1)) goto S180; |
|
1373
|
|
|
|
|
|
|
} |
|
1374
|
0
|
0
|
|
|
|
|
if(l == 35) goto S130; |
|
1375
|
0
|
|
|
|
|
|
S150: |
|
1376
|
|
|
|
|
|
|
/* |
|
1377
|
|
|
|
|
|
|
STEP C. CREATION OF NEW POISSON PROBABILITIES P |
|
1378
|
|
|
|
|
|
|
AND THEIR CUMULATIVES Q=PP(K) |
|
1379
|
|
|
|
|
|
|
*/ |
|
1380
|
4
|
|
|
|
|
|
l += 1; |
|
1381
|
14
|
50
|
|
|
|
|
for(k=l; k<=35; k++) { |
|
1382
|
14
|
|
|
|
|
|
p = p*mu/(double)k; |
|
1383
|
14
|
|
|
|
|
|
q += p; |
|
1384
|
14
|
|
|
|
|
|
*(pp+k-1) = q; |
|
1385
|
14
|
100
|
|
|
|
|
if(u <= q) goto S170; |
|
1386
|
|
|
|
|
|
|
} |
|
1387
|
0
|
|
|
|
|
|
l = 35; |
|
1388
|
0
|
|
|
|
|
|
goto S130; |
|
1389
|
4
|
|
|
|
|
|
S170: |
|
1390
|
4
|
|
|
|
|
|
l = k; |
|
1391
|
4
|
|
|
|
|
|
S180: |
|
1392
|
4
|
|
|
|
|
|
ignpoi = k; |
|
1393
|
4
|
|
|
|
|
|
return ignpoi; |
|
1394
|
|
|
|
|
|
|
} |
|
1395
|
|
|
|
|
|
|
|
|
1396
|
40
|
|
|
|
|
|
long ignuin(long low,long high) |
|
1397
|
|
|
|
|
|
|
/* |
|
1398
|
|
|
|
|
|
|
********************************************************************** |
|
1399
|
|
|
|
|
|
|
long ignuin(long low,long high) |
|
1400
|
|
|
|
|
|
|
GeNerate Uniform INteger |
|
1401
|
|
|
|
|
|
|
Function |
|
1402
|
|
|
|
|
|
|
Generates an integer uniformly distributed between LOW and HIGH. |
|
1403
|
|
|
|
|
|
|
Arguments |
|
1404
|
|
|
|
|
|
|
low --> Low bound (inclusive) on integer value to be generated |
|
1405
|
|
|
|
|
|
|
high --> High bound (inclusive) on integer value to be generated |
|
1406
|
|
|
|
|
|
|
Note |
|
1407
|
|
|
|
|
|
|
If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and |
|
1408
|
|
|
|
|
|
|
stops the program. |
|
1409
|
|
|
|
|
|
|
********************************************************************** |
|
1410
|
|
|
|
|
|
|
IGNLGI generates integers between 1 and 2147483562 |
|
1411
|
|
|
|
|
|
|
MAXNUM is 1 less than maximum generable value |
|
1412
|
|
|
|
|
|
|
*/ |
|
1413
|
|
|
|
|
|
|
{ |
|
1414
|
|
|
|
|
|
|
#define maxnum 2147483561L |
|
1415
|
|
|
|
|
|
|
static long ignuin,ign,maxnow,range,ranp1; |
|
1416
|
|
|
|
|
|
|
|
|
1417
|
40
|
50
|
|
|
|
|
if(!(low > high)) goto S10; |
|
1418
|
0
|
|
|
|
|
|
fputs(" low > high in ignuin - ABORT\n",stderr); |
|
1419
|
0
|
|
|
|
|
|
exit(1); |
|
1420
|
|
|
|
|
|
|
|
|
1421
|
40
|
|
|
|
|
|
S10: |
|
1422
|
40
|
|
|
|
|
|
range = high-low; |
|
1423
|
40
|
50
|
|
|
|
|
if(!(range > maxnum)) goto S20; |
|
1424
|
0
|
|
|
|
|
|
fputs(" high - low too large in ignuin - ABORT\n",stderr); |
|
1425
|
0
|
|
|
|
|
|
exit(1); |
|
1426
|
|
|
|
|
|
|
|
|
1427
|
40
|
|
|
|
|
|
S20: |
|
1428
|
40
|
100
|
|
|
|
|
if(!(low == high)) goto S30; |
|
1429
|
4
|
|
|
|
|
|
ignuin = low; |
|
1430
|
4
|
|
|
|
|
|
return ignuin; |
|
1431
|
|
|
|
|
|
|
|
|
1432
|
36
|
|
|
|
|
|
S30: |
|
1433
|
|
|
|
|
|
|
/* |
|
1434
|
|
|
|
|
|
|
Number to be generated should be in range 0..RANGE |
|
1435
|
|
|
|
|
|
|
Set MAXNOW so that the number of integers in 0..MAXNOW is an |
|
1436
|
|
|
|
|
|
|
integral multiple of the number in 0..RANGE |
|
1437
|
|
|
|
|
|
|
*/ |
|
1438
|
36
|
|
|
|
|
|
ranp1 = range+1; |
|
1439
|
36
|
|
|
|
|
|
maxnow = maxnum/ranp1*ranp1; |
|
1440
|
36
|
|
|
|
|
|
S40: |
|
1441
|
36
|
|
|
|
|
|
ign = ignlgi()-1; |
|
1442
|
36
|
50
|
|
|
|
|
if(!(ign <= maxnow)) goto S40; |
|
1443
|
36
|
|
|
|
|
|
ignuin = low+ign%ranp1; |
|
1444
|
36
|
|
|
|
|
|
return ignuin; |
|
1445
|
|
|
|
|
|
|
#undef maxnum |
|
1446
|
|
|
|
|
|
|
#undef err1 |
|
1447
|
|
|
|
|
|
|
#undef err2 |
|
1448
|
|
|
|
|
|
|
} |
|
1449
|
|
|
|
|
|
|
|
|
1450
|
16
|
|
|
|
|
|
long lennob( char *str ) |
|
1451
|
|
|
|
|
|
|
/* |
|
1452
|
|
|
|
|
|
|
Returns the length of str ignoring trailing blanks but not |
|
1453
|
|
|
|
|
|
|
other white space. |
|
1454
|
|
|
|
|
|
|
*/ |
|
1455
|
|
|
|
|
|
|
{ |
|
1456
|
|
|
|
|
|
|
long i, i_nb; |
|
1457
|
|
|
|
|
|
|
|
|
1458
|
221
|
100
|
|
|
|
|
for (i=0, i_nb= -1L; *(str+i); i++) |
|
1459
|
205
|
100
|
|
|
|
|
if ( *(str+i) != ' ' ) i_nb = i; |
|
1460
|
16
|
|
|
|
|
|
return (i_nb+1); |
|
1461
|
|
|
|
|
|
|
} |
|
1462
|
|
|
|
|
|
|
|
|
1463
|
1062
|
|
|
|
|
|
long mltmod(long a,long s,long m) |
|
1464
|
|
|
|
|
|
|
/* |
|
1465
|
|
|
|
|
|
|
********************************************************************** |
|
1466
|
|
|
|
|
|
|
long mltmod(long a,long s,long m) |
|
1467
|
|
|
|
|
|
|
Returns (A*S) MOD M |
|
1468
|
|
|
|
|
|
|
This is a transcription from Pascal to C of routine |
|
1469
|
|
|
|
|
|
|
MultMod_Decompos from the paper |
|
1470
|
|
|
|
|
|
|
L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package |
|
1471
|
|
|
|
|
|
|
with Splitting Facilities." ACM Transactions on Mathematical |
|
1472
|
|
|
|
|
|
|
Software, 17:98-111 (1991) |
|
1473
|
|
|
|
|
|
|
Arguments |
|
1474
|
|
|
|
|
|
|
a, s, m --> |
|
1475
|
|
|
|
|
|
|
WGR, 12/19/00: replaced S10, S20, etc. with C blocks {} per |
|
1476
|
|
|
|
|
|
|
original paper. |
|
1477
|
|
|
|
|
|
|
********************************************************************** |
|
1478
|
|
|
|
|
|
|
*/ |
|
1479
|
|
|
|
|
|
|
{ |
|
1480
|
|
|
|
|
|
|
#define h 32768L |
|
1481
|
|
|
|
|
|
|
static long a0,a1,k,p,q,qh,rh; |
|
1482
|
|
|
|
|
|
|
/* |
|
1483
|
|
|
|
|
|
|
H = 2**((b-2)/2) where b = 32 because we are using a 32 bit |
|
1484
|
|
|
|
|
|
|
machine. On a different machine recompute H. |
|
1485
|
|
|
|
|
|
|
*/ |
|
1486
|
1062
|
50
|
|
|
|
|
if (a <= 0 || a >= m || s <= 0 || s >= m) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1487
|
0
|
|
|
|
|
|
fputs(" a, m, s out of order in mltmod - ABORT!\n",stderr); |
|
1488
|
0
|
|
|
|
|
|
fprintf(stderr," a = %12ld s = %12ld m = %12ld\n",a,s,m); |
|
1489
|
0
|
|
|
|
|
|
fputs(" mltmod requires: 0 < a < m; 0 < s < m\n",stderr); |
|
1490
|
0
|
|
|
|
|
|
exit(1); |
|
1491
|
|
|
|
|
|
|
} |
|
1492
|
|
|
|
|
|
|
|
|
1493
|
1062
|
50
|
|
|
|
|
if (a < h) { |
|
1494
|
0
|
|
|
|
|
|
a0 = a; |
|
1495
|
0
|
|
|
|
|
|
p = 0; |
|
1496
|
|
|
|
|
|
|
} else { |
|
1497
|
1062
|
|
|
|
|
|
a1 = a/h; |
|
1498
|
1062
|
|
|
|
|
|
a0 = a - h*a1; |
|
1499
|
1062
|
|
|
|
|
|
qh = m/h; |
|
1500
|
1062
|
|
|
|
|
|
rh = m - h*qh; |
|
1501
|
1062
|
100
|
|
|
|
|
if (a1 >= h) { /* A2=1 */ |
|
1502
|
529
|
|
|
|
|
|
a1 -= h; |
|
1503
|
529
|
|
|
|
|
|
k = s/qh; |
|
1504
|
529
|
|
|
|
|
|
p = h*(s-k*qh) - k*rh; |
|
1505
|
656
|
100
|
|
|
|
|
while (p < 0) { p += m; } |
|
1506
|
|
|
|
|
|
|
} else { |
|
1507
|
533
|
|
|
|
|
|
p = 0; |
|
1508
|
|
|
|
|
|
|
} |
|
1509
|
|
|
|
|
|
|
/* |
|
1510
|
|
|
|
|
|
|
P = (A2*S*H)MOD M |
|
1511
|
|
|
|
|
|
|
*/ |
|
1512
|
1062
|
50
|
|
|
|
|
if (a1 != 0) { |
|
1513
|
1062
|
|
|
|
|
|
q = m/a1; |
|
1514
|
1062
|
|
|
|
|
|
k = s/q; |
|
1515
|
1062
|
|
|
|
|
|
p -= k*(m - a1*q); |
|
1516
|
1062
|
100
|
|
|
|
|
if (p > 0) { p -= m; } |
|
1517
|
1062
|
|
|
|
|
|
p += a1*(s - k*q); |
|
1518
|
1338
|
100
|
|
|
|
|
while (p < 0) { p += m; } |
|
1519
|
|
|
|
|
|
|
} |
|
1520
|
|
|
|
|
|
|
/* |
|
1521
|
|
|
|
|
|
|
P = ((A2*H + A1)*S)MOD M |
|
1522
|
|
|
|
|
|
|
*/ |
|
1523
|
1062
|
|
|
|
|
|
k = p/qh; |
|
1524
|
1062
|
|
|
|
|
|
p = h*(p-k*qh) - k*rh; |
|
1525
|
1341
|
100
|
|
|
|
|
while (p < 0) { p += m; } |
|
1526
|
|
|
|
|
|
|
} |
|
1527
|
|
|
|
|
|
|
/* |
|
1528
|
|
|
|
|
|
|
P = ((A2*H + A1)*H*S)MOD M |
|
1529
|
|
|
|
|
|
|
*/ |
|
1530
|
1062
|
50
|
|
|
|
|
if (a0 != 0) { |
|
1531
|
1062
|
|
|
|
|
|
q = m/a0; |
|
1532
|
1062
|
|
|
|
|
|
k = s/q; |
|
1533
|
1062
|
|
|
|
|
|
p -= k*(m-a0*q); |
|
1534
|
1062
|
100
|
|
|
|
|
if (p > 0) { p -= m; } |
|
1535
|
1062
|
|
|
|
|
|
p += a0*(s-k*q); |
|
1536
|
1641
|
100
|
|
|
|
|
while (p < 0) { p += m; } |
|
1537
|
|
|
|
|
|
|
} |
|
1538
|
1062
|
|
|
|
|
|
return p; |
|
1539
|
|
|
|
|
|
|
#undef h |
|
1540
|
|
|
|
|
|
|
} |
|
1541
|
|
|
|
|
|
|
|
|
1542
|
16
|
|
|
|
|
|
void phrtsd(char* phrase,long *seed1,long *seed2) |
|
1543
|
|
|
|
|
|
|
/* |
|
1544
|
|
|
|
|
|
|
********************************************************************** |
|
1545
|
|
|
|
|
|
|
void phrtsd(char* phrase,long *seed1,long *seed2) |
|
1546
|
|
|
|
|
|
|
PHRase To SeeDs |
|
1547
|
|
|
|
|
|
|
|
|
1548
|
|
|
|
|
|
|
Function |
|
1549
|
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
Uses a phrase (character string) to generate two seeds for the RGN |
|
1551
|
|
|
|
|
|
|
random number generator. |
|
1552
|
|
|
|
|
|
|
Arguments |
|
1553
|
|
|
|
|
|
|
phrase --> Phrase to be used for random number generation |
|
1554
|
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
seed1 <-- First seed for generator |
|
1556
|
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
seed2 <-- Second seed for generator |
|
1558
|
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
Note |
|
1560
|
|
|
|
|
|
|
|
|
1561
|
|
|
|
|
|
|
Trailing blanks are eliminated before the seeds are generated. |
|
1562
|
|
|
|
|
|
|
Generated seed values will fall in the range 1..2^30 |
|
1563
|
|
|
|
|
|
|
(1..1,073,741,824) |
|
1564
|
|
|
|
|
|
|
********************************************************************** |
|
1565
|
|
|
|
|
|
|
*/ |
|
1566
|
|
|
|
|
|
|
{ |
|
1567
|
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
static char table[] = |
|
1569
|
|
|
|
|
|
|
"abcdefghijklmnopqrstuvwxyz\ |
|
1570
|
|
|
|
|
|
|
ABCDEFGHIJKLMNOPQRSTUVWXYZ\ |
|
1571
|
|
|
|
|
|
|
0123456789\ |
|
1572
|
|
|
|
|
|
|
!@#$%^&*()_+[];:'\\\"<>?,./ "; /* WGR added space, 5/19/1999 */ |
|
1573
|
|
|
|
|
|
|
|
|
1574
|
|
|
|
|
|
|
long ix; |
|
1575
|
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
static long twop30 = 1073741824L; |
|
1577
|
|
|
|
|
|
|
static long shift[5] = { |
|
1578
|
|
|
|
|
|
|
1L,64L,4096L,262144L,16777216L |
|
1579
|
|
|
|
|
|
|
}; |
|
1580
|
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
#ifdef PHRTSD_ORIG |
|
1582
|
|
|
|
|
|
|
/*----------------------------- Original phrtsd */ |
|
1583
|
|
|
|
|
|
|
static long i,ichr,j,lphr,values[5]; |
|
1584
|
|
|
|
|
|
|
extern long lennob(char *str); |
|
1585
|
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
*seed1 = 1234567890L; |
|
1587
|
|
|
|
|
|
|
*seed2 = 123456789L; |
|
1588
|
|
|
|
|
|
|
lphr = lennob(phrase); |
|
1589
|
|
|
|
|
|
|
if(lphr < 1) return; |
|
1590
|
|
|
|
|
|
|
for(i=0; i<=(lphr-1); i++) { |
|
1591
|
|
|
|
|
|
|
for (ix=0; table[ix]; ix++) if (*(phrase+i) == table[ix]) break; |
|
1592
|
|
|
|
|
|
|
/* JJV added ix++; to bring index in line with fortran's index*/ |
|
1593
|
|
|
|
|
|
|
ix++; |
|
1594
|
|
|
|
|
|
|
if (!table[ix]) ix = 0; |
|
1595
|
|
|
|
|
|
|
ichr = ix % 64; |
|
1596
|
|
|
|
|
|
|
if(ichr == 0) ichr = 63; |
|
1597
|
|
|
|
|
|
|
for(j=1; j<=5; j++) { |
|
1598
|
|
|
|
|
|
|
*(values+j-1) = ichr-j; |
|
1599
|
|
|
|
|
|
|
if(*(values+j-1) < 1) *(values+j-1) += 63; |
|
1600
|
|
|
|
|
|
|
} |
|
1601
|
|
|
|
|
|
|
for(j=1; j<=5; j++) { |
|
1602
|
|
|
|
|
|
|
*seed1 = ( *seed1+*(shift+j-1)**(values+j-1) ) % twop30; |
|
1603
|
|
|
|
|
|
|
*seed2 = ( *seed2+*(shift+j-1)**(values+6-j-1) ) % twop30; |
|
1604
|
|
|
|
|
|
|
} |
|
1605
|
|
|
|
|
|
|
} |
|
1606
|
|
|
|
|
|
|
#else |
|
1607
|
|
|
|
|
|
|
/*----------------------------- New phrtsd */ |
|
1608
|
|
|
|
|
|
|
static long i,j, ichr,lphr; |
|
1609
|
|
|
|
|
|
|
static long values[8] = { 8521739, 5266711, 3254959, 2011673, |
|
1610
|
|
|
|
|
|
|
1243273, 768389, 474899, 293507 }; |
|
1611
|
|
|
|
|
|
|
extern long lennob(char *str); |
|
1612
|
|
|
|
|
|
|
|
|
1613
|
16
|
|
|
|
|
|
*seed1 = 1234567890L; |
|
1614
|
16
|
|
|
|
|
|
*seed2 = 123456789L; |
|
1615
|
16
|
|
|
|
|
|
lphr = lennob(phrase); |
|
1616
|
16
|
50
|
|
|
|
|
if(lphr < 1) return; |
|
1617
|
205
|
100
|
|
|
|
|
for(i=0; i<(lphr-1); i++) { |
|
1618
|
189
|
|
|
|
|
|
ichr = phrase[i]; |
|
1619
|
189
|
|
|
|
|
|
j = i % 8; |
|
1620
|
189
|
|
|
|
|
|
*seed1 = ( *seed1 + (values[j] * ichr) ) % twop30; |
|
1621
|
189
|
|
|
|
|
|
*seed2 = ( *seed2 + (values[7-j] * ichr) ) % twop30; |
|
1622
|
|
|
|
|
|
|
} |
|
1623
|
|
|
|
|
|
|
#endif |
|
1624
|
|
|
|
|
|
|
} |
|
1625
|
|
|
|
|
|
|
|
|
1626
|
224
|
|
|
|
|
|
double ranf(void) |
|
1627
|
|
|
|
|
|
|
/* |
|
1628
|
|
|
|
|
|
|
********************************************************************** |
|
1629
|
|
|
|
|
|
|
double ranf(void) |
|
1630
|
|
|
|
|
|
|
RANDom number generator as a Function |
|
1631
|
|
|
|
|
|
|
Returns a random floating point number from a uniform distribution |
|
1632
|
|
|
|
|
|
|
over 0 - 1 (endpoints of this interval are not returned) using the |
|
1633
|
|
|
|
|
|
|
current generator. |
|
1634
|
|
|
|
|
|
|
This is a transcription from Pascal to C of routine |
|
1635
|
|
|
|
|
|
|
Uniform_01 from the paper |
|
1636
|
|
|
|
|
|
|
L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package |
|
1637
|
|
|
|
|
|
|
with Splitting Facilities." ACM Transactions on Mathematical |
|
1638
|
|
|
|
|
|
|
Software, 17:98-111 (1991) |
|
1639
|
|
|
|
|
|
|
WGR, 2/12/01: increased precision. |
|
1640
|
|
|
|
|
|
|
********************************************************************** |
|
1641
|
|
|
|
|
|
|
*/ |
|
1642
|
|
|
|
|
|
|
{ |
|
1643
|
|
|
|
|
|
|
static double ranf; |
|
1644
|
|
|
|
|
|
|
/* |
|
1645
|
|
|
|
|
|
|
4.656613057E-10 is 1/M1 M1 is set in a data statement in IGNLGI |
|
1646
|
|
|
|
|
|
|
and is currently 2147483563. If M1 changes, change this also. |
|
1647
|
|
|
|
|
|
|
*/ |
|
1648
|
224
|
|
|
|
|
|
ranf = ignlgi()*4.65661305739177E-10; |
|
1649
|
224
|
|
|
|
|
|
return ranf; |
|
1650
|
|
|
|
|
|
|
} |
|
1651
|
|
|
|
|
|
|
|
|
1652
|
3
|
|
|
|
|
|
void setgmn(double *meanv,double *covm,long p,double *parm) |
|
1653
|
|
|
|
|
|
|
/* |
|
1654
|
|
|
|
|
|
|
********************************************************************** |
|
1655
|
|
|
|
|
|
|
void setgmn(double *meanv,double *covm,long p,double *parm) |
|
1656
|
|
|
|
|
|
|
SET Generate Multivariate Normal random deviate |
|
1657
|
|
|
|
|
|
|
Function |
|
1658
|
|
|
|
|
|
|
Places P, MEANV, and the Cholesky factorization of COVM |
|
1659
|
|
|
|
|
|
|
in GENMN. |
|
1660
|
|
|
|
|
|
|
Arguments |
|
1661
|
|
|
|
|
|
|
meanv --> Mean vector of multivariate normal distribution. |
|
1662
|
|
|
|
|
|
|
covm <--> (Input) Covariance matrix of the multivariate |
|
1663
|
|
|
|
|
|
|
normal distribution |
|
1664
|
|
|
|
|
|
|
(Output) Destroyed on output |
|
1665
|
|
|
|
|
|
|
p --> Dimension of the normal, or length of MEANV. |
|
1666
|
|
|
|
|
|
|
parm <-- Array of parameters needed to generate multivariate norma |
|
1667
|
|
|
|
|
|
|
deviates (P, MEANV and Cholesky decomposition of |
|
1668
|
|
|
|
|
|
|
COVM). |
|
1669
|
|
|
|
|
|
|
1 : 1 - P |
|
1670
|
|
|
|
|
|
|
2 : P + 1 - MEANV |
|
1671
|
|
|
|
|
|
|
P+2 : P*(P+3)/2 + 1 - Cholesky decomposition of COVM |
|
1672
|
|
|
|
|
|
|
Needed dimension is (p*(p+3)/2 + 1) |
|
1673
|
|
|
|
|
|
|
********************************************************************** |
|
1674
|
|
|
|
|
|
|
*/ |
|
1675
|
|
|
|
|
|
|
{ |
|
1676
|
|
|
|
|
|
|
extern void spofa(double *a,long lda,long n,long *info); |
|
1677
|
|
|
|
|
|
|
static long T1; |
|
1678
|
|
|
|
|
|
|
static long i,icount,info,j,D2,D3,D4,D5; |
|
1679
|
3
|
|
|
|
|
|
T1 = p*(p+3)/2+1; |
|
1680
|
|
|
|
|
|
|
/* |
|
1681
|
|
|
|
|
|
|
TEST THE INPUT |
|
1682
|
|
|
|
|
|
|
*/ |
|
1683
|
3
|
50
|
|
|
|
|
if(!(p <= 0)) goto S10; |
|
1684
|
0
|
|
|
|
|
|
fputs("P nonpositive in SETGMN\n",stderr); |
|
1685
|
0
|
|
|
|
|
|
fprintf(stderr,"Value of P: %12ld\n",p); |
|
1686
|
0
|
|
|
|
|
|
exit(1); |
|
1687
|
3
|
|
|
|
|
|
S10: |
|
1688
|
3
|
|
|
|
|
|
*parm = p; |
|
1689
|
|
|
|
|
|
|
/* |
|
1690
|
|
|
|
|
|
|
PUT P AND MEANV INTO PARM |
|
1691
|
|
|
|
|
|
|
*/ |
|
1692
|
9
|
100
|
|
|
|
|
for(i=2,D2=1,D3=(p+1-i+D2)/D2; D3>0; D3--,i+=D2) *(parm+i-1) = *(meanv+i-2); |
|
1693
|
|
|
|
|
|
|
/* |
|
1694
|
|
|
|
|
|
|
Cholesky decomposition to find A s.t. trans(A)*(A) = COVM |
|
1695
|
|
|
|
|
|
|
*/ |
|
1696
|
3
|
|
|
|
|
|
spofa(covm,p,p,&info); |
|
1697
|
3
|
50
|
|
|
|
|
if(!(info != 0)) goto S30; |
|
1698
|
0
|
|
|
|
|
|
fputs(" COVM not positive definite in SETGMN\n",stderr); |
|
1699
|
0
|
|
|
|
|
|
exit(1); |
|
1700
|
3
|
|
|
|
|
|
S30: |
|
1701
|
3
|
|
|
|
|
|
icount = p+1; |
|
1702
|
|
|
|
|
|
|
/* |
|
1703
|
|
|
|
|
|
|
PUT UPPER HALF OF A, WHICH IS NOW THE CHOLESKY FACTOR, INTO PARM |
|
1704
|
|
|
|
|
|
|
COVM(1,1) = PARM(P+2) |
|
1705
|
|
|
|
|
|
|
COVM(1,2) = PARM(P+3) |
|
1706
|
|
|
|
|
|
|
: |
|
1707
|
|
|
|
|
|
|
COVM(1,P) = PARM(2P+1) |
|
1708
|
|
|
|
|
|
|
COVM(2,2) = PARM(2P+2) ... |
|
1709
|
|
|
|
|
|
|
*/ |
|
1710
|
9
|
100
|
|
|
|
|
for(i=1,D4=1,D5=(p-i+D4)/D4; D5>0; D5--,i+=D4) { |
|
1711
|
15
|
100
|
|
|
|
|
for(j=i-1; j
|
|
1712
|
9
|
|
|
|
|
|
icount += 1; |
|
1713
|
9
|
|
|
|
|
|
*(parm+icount-1) = *(covm+i-1+j*p); |
|
1714
|
|
|
|
|
|
|
} |
|
1715
|
|
|
|
|
|
|
} |
|
1716
|
3
|
|
|
|
|
|
} |
|
1717
|
|
|
|
|
|
|
|
|
1718
|
24
|
|
|
|
|
|
double sexpo(void) |
|
1719
|
|
|
|
|
|
|
/* |
|
1720
|
|
|
|
|
|
|
********************************************************************** |
|
1721
|
|
|
|
|
|
|
|
|
1722
|
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
(STANDARD-) E X P O N E N T I A L DISTRIBUTION |
|
1724
|
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
********************************************************************** |
|
1727
|
|
|
|
|
|
|
********************************************************************** |
|
1728
|
|
|
|
|
|
|
|
|
1729
|
|
|
|
|
|
|
FOR DETAILS SEE: |
|
1730
|
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
AHRENS, J.H. AND DIETER, U. |
|
1732
|
|
|
|
|
|
|
COMPUTER METHODS FOR SAMPLING FROM THE |
|
1733
|
|
|
|
|
|
|
EXPONENTIAL AND NORMAL DISTRIBUTIONS. |
|
1734
|
|
|
|
|
|
|
COMM. ACM, 15,10 (OCT. 1972), 873 - 882. |
|
1735
|
|
|
|
|
|
|
|
|
1736
|
|
|
|
|
|
|
ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM |
|
1737
|
|
|
|
|
|
|
'SA' IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION) |
|
1738
|
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of |
|
1740
|
|
|
|
|
|
|
SUNIF. The argument IR thus goes away. |
|
1741
|
|
|
|
|
|
|
|
|
1742
|
|
|
|
|
|
|
********************************************************************** |
|
1743
|
|
|
|
|
|
|
Q(N) = SUM(ALOG(2.0)**K/K!) K=1,..,N , THE HIGHEST N |
|
1744
|
|
|
|
|
|
|
(HERE 8) IS DETERMINED BY Q(N)=1.0 WITHIN STANDARD PRECISION |
|
1745
|
|
|
|
|
|
|
*/ |
|
1746
|
|
|
|
|
|
|
{ |
|
1747
|
|
|
|
|
|
|
static double q[8] = { |
|
1748
|
|
|
|
|
|
|
0.69314718055995, 0.93337368751905, 0.98887779618387, 0.99849592529150, |
|
1749
|
|
|
|
|
|
|
0.99982928110614, 0.99998331641007, 0.99999856914388, 0.99999989069256 |
|
1750
|
|
|
|
|
|
|
}; |
|
1751
|
|
|
|
|
|
|
static long i; |
|
1752
|
|
|
|
|
|
|
static double sexpo,a,u,ustar,umin; |
|
1753
|
|
|
|
|
|
|
static double *q1 = q; |
|
1754
|
24
|
|
|
|
|
|
a = 0.0; |
|
1755
|
24
|
|
|
|
|
|
u = ranf(); |
|
1756
|
24
|
|
|
|
|
|
goto S30; |
|
1757
|
6
|
|
|
|
|
|
S20: |
|
1758
|
6
|
|
|
|
|
|
a += *q1; |
|
1759
|
30
|
|
|
|
|
|
S30: |
|
1760
|
30
|
|
|
|
|
|
u += u; |
|
1761
|
|
|
|
|
|
|
/* |
|
1762
|
|
|
|
|
|
|
* JJV changed the following to reflect the true algorithm and prevent |
|
1763
|
|
|
|
|
|
|
* JJV unpredictable behavior if U is initially 0.5. |
|
1764
|
|
|
|
|
|
|
* if(u <= 1.0) goto S20; |
|
1765
|
|
|
|
|
|
|
*/ |
|
1766
|
30
|
100
|
|
|
|
|
if(u < 1.0) goto S20; |
|
1767
|
24
|
|
|
|
|
|
u -= 1.0; |
|
1768
|
24
|
100
|
|
|
|
|
if(u > *q1) goto S60; |
|
1769
|
18
|
|
|
|
|
|
sexpo = a+u; |
|
1770
|
18
|
|
|
|
|
|
return sexpo; |
|
1771
|
6
|
|
|
|
|
|
S60: |
|
1772
|
6
|
|
|
|
|
|
i = 1; |
|
1773
|
6
|
|
|
|
|
|
ustar = ranf(); |
|
1774
|
6
|
|
|
|
|
|
umin = ustar; |
|
1775
|
6
|
|
|
|
|
|
S70: |
|
1776
|
6
|
|
|
|
|
|
ustar = ranf(); |
|
1777
|
6
|
100
|
|
|
|
|
if(ustar < umin) umin = ustar; |
|
1778
|
6
|
|
|
|
|
|
i += 1; |
|
1779
|
6
|
50
|
|
|
|
|
if(u > *(q+i-1)) goto S70; |
|
1780
|
6
|
|
|
|
|
|
sexpo = a+umin**q1; |
|
1781
|
6
|
|
|
|
|
|
return sexpo; |
|
1782
|
|
|
|
|
|
|
} |
|
1783
|
|
|
|
|
|
|
|
|
1784
|
48
|
|
|
|
|
|
double sgamma(double a) |
|
1785
|
|
|
|
|
|
|
/* |
|
1786
|
|
|
|
|
|
|
********************************************************************** |
|
1787
|
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
|
|
1789
|
|
|
|
|
|
|
(STANDARD-) G A M M A DISTRIBUTION |
|
1790
|
|
|
|
|
|
|
|
|
1791
|
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
********************************************************************** |
|
1793
|
|
|
|
|
|
|
********************************************************************** |
|
1794
|
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
PARAMETER A >= 1.0 ! |
|
1796
|
|
|
|
|
|
|
|
|
1797
|
|
|
|
|
|
|
********************************************************************** |
|
1798
|
|
|
|
|
|
|
|
|
1799
|
|
|
|
|
|
|
FOR DETAILS SEE: |
|
1800
|
|
|
|
|
|
|
|
|
1801
|
|
|
|
|
|
|
AHRENS, J.H. AND DIETER, U. |
|
1802
|
|
|
|
|
|
|
GENERATING GAMMA VARIATES BY A |
|
1803
|
|
|
|
|
|
|
MODIFIED REJECTION TECHNIQUE. |
|
1804
|
|
|
|
|
|
|
COMM. ACM, 25,1 (JAN. 1982), 47 - 54. |
|
1805
|
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
STEP NUMBERS CORRESPOND TO ALGORITHM 'GD' IN THE ABOVE PAPER |
|
1807
|
|
|
|
|
|
|
(STRAIGHTFORWARD IMPLEMENTATION) |
|
1808
|
|
|
|
|
|
|
|
|
1809
|
|
|
|
|
|
|
Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of |
|
1810
|
|
|
|
|
|
|
SUNIF. The argument IR thus goes away. |
|
1811
|
|
|
|
|
|
|
|
|
1812
|
|
|
|
|
|
|
********************************************************************** |
|
1813
|
|
|
|
|
|
|
|
|
1814
|
|
|
|
|
|
|
PARAMETER 0.0 < A < 1.0 ! |
|
1815
|
|
|
|
|
|
|
|
|
1816
|
|
|
|
|
|
|
********************************************************************** |
|
1817
|
|
|
|
|
|
|
|
|
1818
|
|
|
|
|
|
|
FOR DETAILS SEE: |
|
1819
|
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
AHRENS, J.H. AND DIETER, U. |
|
1821
|
|
|
|
|
|
|
COMPUTER METHODS FOR SAMPLING FROM GAMMA, |
|
1822
|
|
|
|
|
|
|
BETA, POISSON AND BINOMIAL DISTRIBUTIONS. |
|
1823
|
|
|
|
|
|
|
COMPUTING, 12 (1974), 223 - 246. |
|
1824
|
|
|
|
|
|
|
|
|
1825
|
|
|
|
|
|
|
(ADAPTED IMPLEMENTATION OF ALGORITHM 'GS' IN THE ABOVE PAPER) |
|
1826
|
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
********************************************************************** |
|
1828
|
|
|
|
|
|
|
INPUT: A =PARAMETER (MEAN) OF THE STANDARD GAMMA DISTRIBUTION |
|
1829
|
|
|
|
|
|
|
OUTPUT: SGAMMA = SAMPLE FROM THE GAMMA-(A)-DISTRIBUTION |
|
1830
|
|
|
|
|
|
|
COEFFICIENTS Q(K) - FOR Q0 = SUM(Q(K)*A**(-K)) |
|
1831
|
|
|
|
|
|
|
COEFFICIENTS A(K) - FOR Q = Q0+(T*T/2)*SUM(A(K)*V**K) |
|
1832
|
|
|
|
|
|
|
COEFFICIENTS E(K) - FOR EXP(Q)-1 = SUM(E(K)*Q**K) |
|
1833
|
|
|
|
|
|
|
PREVIOUS A PRE-SET TO ZERO - AA IS A', AAA IS A" |
|
1834
|
|
|
|
|
|
|
SQRT32 IS THE SQUAREROOT OF 32 = 5.656854249492380 |
|
1835
|
|
|
|
|
|
|
*/ |
|
1836
|
|
|
|
|
|
|
{ |
|
1837
|
|
|
|
|
|
|
extern double fsign( double num, double sign ); |
|
1838
|
|
|
|
|
|
|
static double q1 = 4.16666664E-2; |
|
1839
|
|
|
|
|
|
|
static double q2 = 2.08333723E-2; |
|
1840
|
|
|
|
|
|
|
static double q3 = 7.9849875E-3; |
|
1841
|
|
|
|
|
|
|
static double q4 = 1.5746717E-3; |
|
1842
|
|
|
|
|
|
|
static double q5 = -3.349403E-4; |
|
1843
|
|
|
|
|
|
|
static double q6 = 3.340332E-4; |
|
1844
|
|
|
|
|
|
|
static double q7 = 6.053049E-4; |
|
1845
|
|
|
|
|
|
|
static double q8 = -4.701849E-4; |
|
1846
|
|
|
|
|
|
|
static double q9 = 1.710320E-4; |
|
1847
|
|
|
|
|
|
|
static double a1 = 0.333333333; |
|
1848
|
|
|
|
|
|
|
static double a2 = -0.249999949; |
|
1849
|
|
|
|
|
|
|
static double a3 = 0.199999867; |
|
1850
|
|
|
|
|
|
|
static double a4 = -0.166677482; |
|
1851
|
|
|
|
|
|
|
static double a5 = 0.142873973; |
|
1852
|
|
|
|
|
|
|
static double a6 = -0.124385581; |
|
1853
|
|
|
|
|
|
|
static double a7 = 0.110368310; |
|
1854
|
|
|
|
|
|
|
static double a8 = -0.112750886; |
|
1855
|
|
|
|
|
|
|
static double a9 = 0.104089866; |
|
1856
|
|
|
|
|
|
|
static double e1 = 1.0; |
|
1857
|
|
|
|
|
|
|
static double e2 = 0.499999994; |
|
1858
|
|
|
|
|
|
|
static double e3 = 0.166666848; |
|
1859
|
|
|
|
|
|
|
static double e4 = 4.1664508E-2; |
|
1860
|
|
|
|
|
|
|
static double e5 = 8.345522E-3; |
|
1861
|
|
|
|
|
|
|
static double e6 = 1.353826E-3; |
|
1862
|
|
|
|
|
|
|
static double e7 = 2.47453E-4; |
|
1863
|
|
|
|
|
|
|
static double aa = 0.0; |
|
1864
|
|
|
|
|
|
|
static double aaa = 0.0; |
|
1865
|
|
|
|
|
|
|
static double sqrt32 = 5.65685424949238; |
|
1866
|
|
|
|
|
|
|
/* JJV added b0 to fix rare and subtle bug */ |
|
1867
|
|
|
|
|
|
|
static double sgamma,s2,s,d,t,x,u,r,q0,b,b0,si,c,v,q,e,w,p; |
|
1868
|
48
|
100
|
|
|
|
|
if(a == aa) goto S10; |
|
1869
|
30
|
50
|
|
|
|
|
if(a < 1.0) goto S120; |
|
1870
|
|
|
|
|
|
|
/* |
|
1871
|
|
|
|
|
|
|
STEP 1: RECALCULATIONS OF S2,S,D IF A HAS CHANGED |
|
1872
|
|
|
|
|
|
|
*/ |
|
1873
|
30
|
|
|
|
|
|
aa = a; |
|
1874
|
30
|
|
|
|
|
|
s2 = a-0.5; |
|
1875
|
30
|
|
|
|
|
|
s = sqrt(s2); |
|
1876
|
30
|
|
|
|
|
|
d = sqrt32-12.0*s; |
|
1877
|
48
|
|
|
|
|
|
S10: |
|
1878
|
|
|
|
|
|
|
/* |
|
1879
|
|
|
|
|
|
|
STEP 2: T=STANDARD NORMAL DEVIATE, |
|
1880
|
|
|
|
|
|
|
X=(S,1/2)-NORMAL DEVIATE. |
|
1881
|
|
|
|
|
|
|
IMMEDIATE ACCEPTANCE (I) |
|
1882
|
|
|
|
|
|
|
*/ |
|
1883
|
48
|
|
|
|
|
|
t = snorm(); |
|
1884
|
48
|
|
|
|
|
|
x = s+0.5*t; |
|
1885
|
48
|
|
|
|
|
|
sgamma = x*x; |
|
1886
|
48
|
100
|
|
|
|
|
if(t >= 0.0) return sgamma; |
|
1887
|
|
|
|
|
|
|
/* |
|
1888
|
|
|
|
|
|
|
STEP 3: U= 0,1 -UNIFORM SAMPLE. SQUEEZE ACCEPTANCE (S) |
|
1889
|
|
|
|
|
|
|
*/ |
|
1890
|
28
|
|
|
|
|
|
u = ranf(); |
|
1891
|
28
|
100
|
|
|
|
|
if(d*u <= t*t*t) return sgamma; |
|
1892
|
|
|
|
|
|
|
/* |
|
1893
|
|
|
|
|
|
|
STEP 4: RECALCULATIONS OF Q0,B,SI,C IF NECESSARY |
|
1894
|
|
|
|
|
|
|
*/ |
|
1895
|
6
|
100
|
|
|
|
|
if(a == aaa) goto S40; |
|
1896
|
4
|
|
|
|
|
|
aaa = a; |
|
1897
|
4
|
|
|
|
|
|
r = 1.0/a; |
|
1898
|
4
|
|
|
|
|
|
q0 = ((((((((q9*r+q8)*r+q7)*r+q6)*r+q5)*r+q4)*r+q3)*r+q2)*r+q1)*r; |
|
1899
|
|
|
|
|
|
|
/* |
|
1900
|
|
|
|
|
|
|
APPROXIMATION DEPENDING ON SIZE OF PARAMETER A |
|
1901
|
|
|
|
|
|
|
THE CONSTANTS IN THE EXPRESSIONS FOR B, SI AND |
|
1902
|
|
|
|
|
|
|
C WERE ESTABLISHED BY NUMERICAL EXPERIMENTS |
|
1903
|
|
|
|
|
|
|
*/ |
|
1904
|
4
|
50
|
|
|
|
|
if(a <= 3.686) goto S30; |
|
1905
|
0
|
0
|
|
|
|
|
if(a <= 13.022) goto S20; |
|
1906
|
|
|
|
|
|
|
/* |
|
1907
|
|
|
|
|
|
|
CASE 3: A .GT. 13.022 |
|
1908
|
|
|
|
|
|
|
*/ |
|
1909
|
0
|
|
|
|
|
|
b = 1.77; |
|
1910
|
0
|
|
|
|
|
|
si = 0.75; |
|
1911
|
0
|
|
|
|
|
|
c = 0.1515/s; |
|
1912
|
0
|
|
|
|
|
|
goto S40; |
|
1913
|
0
|
|
|
|
|
|
S20: |
|
1914
|
|
|
|
|
|
|
/* |
|
1915
|
|
|
|
|
|
|
CASE 2: 3.686 .LT. A .LE. 13.022 |
|
1916
|
|
|
|
|
|
|
*/ |
|
1917
|
0
|
|
|
|
|
|
b = 1.654+7.6E-3*s2; |
|
1918
|
0
|
|
|
|
|
|
si = 1.68/s+0.275; |
|
1919
|
0
|
|
|
|
|
|
c = 6.2E-2/s+2.4E-2; |
|
1920
|
0
|
|
|
|
|
|
goto S40; |
|
1921
|
4
|
|
|
|
|
|
S30: |
|
1922
|
|
|
|
|
|
|
/* |
|
1923
|
|
|
|
|
|
|
CASE 1: A .LE. 3.686 |
|
1924
|
|
|
|
|
|
|
*/ |
|
1925
|
4
|
|
|
|
|
|
b = 0.463+s+0.178*s2; |
|
1926
|
4
|
|
|
|
|
|
si = 1.235; |
|
1927
|
4
|
|
|
|
|
|
c = 0.195/s-7.9E-2+1.6E-1*s; |
|
1928
|
6
|
|
|
|
|
|
S40: |
|
1929
|
|
|
|
|
|
|
/* |
|
1930
|
|
|
|
|
|
|
STEP 5: NO QUOTIENT TEST IF X NOT POSITIVE |
|
1931
|
|
|
|
|
|
|
*/ |
|
1932
|
6
|
100
|
|
|
|
|
if(x <= 0.0) goto S70; |
|
1933
|
|
|
|
|
|
|
/* |
|
1934
|
|
|
|
|
|
|
STEP 6: CALCULATION OF V AND QUOTIENT Q |
|
1935
|
|
|
|
|
|
|
*/ |
|
1936
|
4
|
|
|
|
|
|
v = t/(s+s); |
|
1937
|
4
|
50
|
|
|
|
|
if(fabs(v) <= 0.25) goto S50; |
|
1938
|
4
|
|
|
|
|
|
q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v); |
|
1939
|
4
|
|
|
|
|
|
goto S60; |
|
1940
|
0
|
|
|
|
|
|
S50: |
|
1941
|
0
|
|
|
|
|
|
q = q0+0.5*t*t*((((((((a9*v+a8)*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v; |
|
1942
|
4
|
|
|
|
|
|
S60: |
|
1943
|
|
|
|
|
|
|
/* |
|
1944
|
|
|
|
|
|
|
STEP 7: QUOTIENT ACCEPTANCE (Q) |
|
1945
|
|
|
|
|
|
|
*/ |
|
1946
|
4
|
100
|
|
|
|
|
if(log(1.0-u) <= q) return sgamma; |
|
1947
|
16
|
|
|
|
|
|
S70: |
|
1948
|
|
|
|
|
|
|
/* |
|
1949
|
|
|
|
|
|
|
STEP 8: E=STANDARD EXPONENTIAL DEVIATE |
|
1950
|
|
|
|
|
|
|
U= 0,1 -UNIFORM DEVIATE |
|
1951
|
|
|
|
|
|
|
T=(B,SI)-DOUBLE EXPONENTIAL (LAPLACE) SAMPLE |
|
1952
|
|
|
|
|
|
|
*/ |
|
1953
|
18
|
|
|
|
|
|
e = sexpo(); |
|
1954
|
18
|
|
|
|
|
|
u = ranf(); |
|
1955
|
18
|
|
|
|
|
|
u += (u-1.0); |
|
1956
|
18
|
|
|
|
|
|
t = b+fsign(si*e,u); |
|
1957
|
|
|
|
|
|
|
/* |
|
1958
|
|
|
|
|
|
|
STEP 9: REJECTION IF T .LT. TAU(1) = -.71874483771719 |
|
1959
|
|
|
|
|
|
|
*/ |
|
1960
|
18
|
50
|
|
|
|
|
if(t < -0.71874483771719) goto S70; |
|
1961
|
|
|
|
|
|
|
/* |
|
1962
|
|
|
|
|
|
|
STEP 10: CALCULATION OF V AND QUOTIENT Q |
|
1963
|
|
|
|
|
|
|
*/ |
|
1964
|
18
|
|
|
|
|
|
v = t/(s+s); |
|
1965
|
18
|
100
|
|
|
|
|
if(fabs(v) <= 0.25) goto S80; |
|
1966
|
16
|
|
|
|
|
|
q = q0-s*t+0.25*t*t+(s2+s2)*log(1.0+v); |
|
1967
|
16
|
|
|
|
|
|
goto S90; |
|
1968
|
2
|
|
|
|
|
|
S80: |
|
1969
|
2
|
|
|
|
|
|
q = q0+0.5*t*t*((((((((a9*v+a8)*v+a7)*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v; |
|
1970
|
18
|
|
|
|
|
|
S90: |
|
1971
|
|
|
|
|
|
|
/* |
|
1972
|
|
|
|
|
|
|
STEP 11: HAT ACCEPTANCE (H) (IF Q NOT POSITIVE GO TO STEP 8) |
|
1973
|
|
|
|
|
|
|
*/ |
|
1974
|
18
|
50
|
|
|
|
|
if(q <= 0.0) goto S70; |
|
1975
|
18
|
100
|
|
|
|
|
if(q <= 0.5) goto S100; |
|
1976
|
|
|
|
|
|
|
/* |
|
1977
|
|
|
|
|
|
|
* JJV modified the code through line 115 to handle large Q case |
|
1978
|
|
|
|
|
|
|
*/ |
|
1979
|
8
|
50
|
|
|
|
|
if(q < 15.0) goto S95; |
|
1980
|
|
|
|
|
|
|
/* |
|
1981
|
|
|
|
|
|
|
* JJV Here Q is large enough that Q = log(exp(Q) - 1.0) (for real Q) |
|
1982
|
|
|
|
|
|
|
* JJV so reformulate test at 110 in terms of one EXP, if not too big |
|
1983
|
|
|
|
|
|
|
* JJV 87.49823 is close to the largest real which can be |
|
1984
|
|
|
|
|
|
|
* JJV exponentiated (87.49823 = log(1.0E38)) |
|
1985
|
|
|
|
|
|
|
*/ |
|
1986
|
0
|
0
|
|
|
|
|
if((q+e-0.5*t*t) > 87.4982335337737) goto S115; |
|
1987
|
0
|
0
|
|
|
|
|
if(c*fabs(u) > exp(q+e-0.5*t*t)) goto S70; |
|
1988
|
0
|
|
|
|
|
|
goto S115; |
|
1989
|
8
|
|
|
|
|
|
S95: |
|
1990
|
8
|
|
|
|
|
|
w = exp(q)-1.0; |
|
1991
|
8
|
|
|
|
|
|
goto S110; |
|
1992
|
10
|
|
|
|
|
|
S100: |
|
1993
|
10
|
|
|
|
|
|
w = ((((((e7*q+e6)*q+e5)*q+e4)*q+e3)*q+e2)*q+e1)*q; |
|
1994
|
18
|
|
|
|
|
|
S110: |
|
1995
|
|
|
|
|
|
|
/* |
|
1996
|
|
|
|
|
|
|
IF T IS REJECTED, SAMPLE AGAIN AT STEP 8 |
|
1997
|
|
|
|
|
|
|
*/ |
|
1998
|
18
|
100
|
|
|
|
|
if(c*fabs(u) > w*exp(e-0.5*t*t)) goto S70; |
|
1999
|
4
|
|
|
|
|
|
S115: |
|
2000
|
4
|
|
|
|
|
|
x = s+0.5*t; |
|
2001
|
4
|
|
|
|
|
|
sgamma = x*x; |
|
2002
|
4
|
|
|
|
|
|
return sgamma; |
|
2003
|
0
|
|
|
|
|
|
S120: |
|
2004
|
|
|
|
|
|
|
/* |
|
2005
|
|
|
|
|
|
|
ALTERNATE METHOD FOR PARAMETERS A BELOW 1 (.3678794=EXP(-1.)) |
|
2006
|
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
JJV changed B to B0 (which was added to declarations for this) |
|
2008
|
|
|
|
|
|
|
JJV in 120 to END to fix rare and subtle bug. |
|
2009
|
|
|
|
|
|
|
JJV Line: 'aa = 0.0' was removed (unnecessary, wasteful). |
|
2010
|
|
|
|
|
|
|
JJV Reasons: the state of AA only serves to tell the A >= 1.0 |
|
2011
|
|
|
|
|
|
|
JJV case if certain A-dependent constants need to be recalculated. |
|
2012
|
|
|
|
|
|
|
JJV The A < 1.0 case (here) no longer changes any of these, and |
|
2013
|
|
|
|
|
|
|
JJV the recalculation of B (which used to change with an |
|
2014
|
|
|
|
|
|
|
JJV A < 1.0 call) is governed by the state of AAA anyway. |
|
2015
|
|
|
|
|
|
|
aa = 0.0; |
|
2016
|
|
|
|
|
|
|
*/ |
|
2017
|
0
|
|
|
|
|
|
b0 = 1.0+ 0.3678794411714423*a; |
|
2018
|
0
|
|
|
|
|
|
S130: |
|
2019
|
0
|
|
|
|
|
|
p = b0*ranf(); |
|
2020
|
0
|
0
|
|
|
|
|
if(p >= 1.0) goto S140; |
|
2021
|
0
|
|
|
|
|
|
sgamma = exp(log(p)/ a); |
|
2022
|
0
|
0
|
|
|
|
|
if(sexpo() < sgamma) goto S130; |
|
2023
|
0
|
|
|
|
|
|
return sgamma; |
|
2024
|
0
|
|
|
|
|
|
S140: |
|
2025
|
0
|
|
|
|
|
|
sgamma = -log((b0-p)/ a); |
|
2026
|
0
|
0
|
|
|
|
|
if(sexpo() < (1.0-a)*log(sgamma)) goto S130; |
|
2027
|
0
|
|
|
|
|
|
return sgamma; |
|
2028
|
|
|
|
|
|
|
} |
|
2029
|
|
|
|
|
|
|
|
|
2030
|
80
|
|
|
|
|
|
double snorm(void) |
|
2031
|
|
|
|
|
|
|
/* |
|
2032
|
|
|
|
|
|
|
********************************************************************** |
|
2033
|
|
|
|
|
|
|
|
|
2034
|
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
(STANDARD-) N O R M A L DISTRIBUTION |
|
2036
|
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
********************************************************************** |
|
2039
|
|
|
|
|
|
|
********************************************************************** |
|
2040
|
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
FOR DETAILS SEE: |
|
2042
|
|
|
|
|
|
|
|
|
2043
|
|
|
|
|
|
|
AHRENS, J.H. AND DIETER, U. |
|
2044
|
|
|
|
|
|
|
EXTENSIONS OF FORSYTHE'S METHOD FOR RANDOM |
|
2045
|
|
|
|
|
|
|
SAMPLING FROM THE NORMAL DISTRIBUTION. |
|
2046
|
|
|
|
|
|
|
MATH. COMPUT., 27,124 (OCT. 1973), 927 - 937. |
|
2047
|
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
ALL STATEMENT NUMBERS CORRESPOND TO THE STEPS OF ALGORITHM 'FL' |
|
2049
|
|
|
|
|
|
|
(M=5) IN THE ABOVE PAPER (SLIGHTLY MODIFIED IMPLEMENTATION) |
|
2050
|
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
Modified by Barry W. Brown, Feb 3, 1988 to use RANF instead of |
|
2052
|
|
|
|
|
|
|
SUNIF. The argument IR thus goes away. |
|
2053
|
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
********************************************************************** |
|
2055
|
|
|
|
|
|
|
THE DEFINITIONS OF THE CONSTANTS A(K), D(K), T(K) AND |
|
2056
|
|
|
|
|
|
|
H(K) ARE ACCORDING TO THE ABOVEMENTIONED ARTICLE |
|
2057
|
|
|
|
|
|
|
*/ |
|
2058
|
|
|
|
|
|
|
{ |
|
2059
|
|
|
|
|
|
|
static double a[32] = { |
|
2060
|
|
|
|
|
|
|
0.0, 0.03917608550309, 0.07841241273311, 0.11776987457909, |
|
2061
|
|
|
|
|
|
|
0.15731068461017, 0.19709908429430, 0.23720210932878, 0.27769043982157, |
|
2062
|
|
|
|
|
|
|
0.31863936396437, 0.36012989178957, 0.40225006532172, 0.44509652498551, |
|
2063
|
|
|
|
|
|
|
0.48877641111466, 0.53340970624127, 0.57913216225555, 0.62609901234641, |
|
2064
|
|
|
|
|
|
|
0.67448975019607, 0.72451438349236, 0.77642176114792, 0.83051087820539, |
|
2065
|
|
|
|
|
|
|
0.88714655901887, 0.94678175630104, 1.00999016924958, 1.07751556704027, |
|
2066
|
|
|
|
|
|
|
1.15034938037600, 1.22985875921658, 1.31801089730353, 1.41779713799625, |
|
2067
|
|
|
|
|
|
|
1.53412054435253, 1.67593972277344, 1.86273186742164, 2.15387469406144 |
|
2068
|
|
|
|
|
|
|
}; |
|
2069
|
|
|
|
|
|
|
static double d[31] = { |
|
2070
|
|
|
|
|
|
|
0.0, 0.0, 0.0, 0.0, |
|
2071
|
|
|
|
|
|
|
0.0, 0.26368432217502, 0.24250845238097, 0.22556744380930, |
|
2072
|
|
|
|
|
|
|
0.21163416577204, 0.19992426749317, 0.18991075842246, 0.18122518100691, |
|
2073
|
|
|
|
|
|
|
0.17360140038056, 0.16684190866667, 0.16079672918053, 0.15534971747692, |
|
2074
|
|
|
|
|
|
|
0.15040938382813, 0.14590257684509, 0.14177003276856, 0.13796317369537, |
|
2075
|
|
|
|
|
|
|
0.13444176150074, 0.13117215026483, 0.12812596512583, 0.12527909006226, |
|
2076
|
|
|
|
|
|
|
0.12261088288608, 0.12010355965651, 0.11774170701949, 0.11551189226063, |
|
2077
|
|
|
|
|
|
|
0.11340234879117, 0.11140272044119, 0.10950385201710 |
|
2078
|
|
|
|
|
|
|
}; |
|
2079
|
|
|
|
|
|
|
static double t[31] = { |
|
2080
|
|
|
|
|
|
|
7.6738283767E-4, 2.30687039764E-3, 3.86061844387E-3, 5.43845406707E-3, |
|
2081
|
|
|
|
|
|
|
7.05069876857E-3, 8.70839582019E-3, 1.042356984914E-2, 1.220953194966E-2, |
|
2082
|
|
|
|
|
|
|
1.408124734637E-2, 1.605578804548E-2, 1.815290075142E-2, 2.039573175398E-2, |
|
2083
|
|
|
|
|
|
|
2.281176732513E-2, 2.543407332319E-2, 2.830295595118E-2, 3.146822492920E-2, |
|
2084
|
|
|
|
|
|
|
3.499233438388E-2, 3.895482964836E-2, 4.345878381672E-2, 4.864034918076E-2, |
|
2085
|
|
|
|
|
|
|
5.468333844273E-2, 6.184222395816E-2, 7.047982761667E-2, 8.113194985866E-2, |
|
2086
|
|
|
|
|
|
|
9.462443534514E-2, 0.11230007889456, 0.13649799954975, 0.17168856004707, |
|
2087
|
|
|
|
|
|
|
0.22762405488269, 0.33049802776911, 0.58470309390507 |
|
2088
|
|
|
|
|
|
|
}; |
|
2089
|
|
|
|
|
|
|
static double h[31] = { |
|
2090
|
|
|
|
|
|
|
3.920617164634E-2, 3.932704963665E-2, 3.950999486086E-2, 3.975702679515E-2, |
|
2091
|
|
|
|
|
|
|
4.007092772490E-2, 4.045532602655E-2, 4.091480886081E-2, 4.145507115859E-2, |
|
2092
|
|
|
|
|
|
|
4.208311051344E-2, 4.280748137995E-2, 4.363862733472E-2, 4.458931789605E-2, |
|
2093
|
|
|
|
|
|
|
4.567522779560E-2, 4.691571371696E-2, 4.833486978119E-2, 4.996298427702E-2, |
|
2094
|
|
|
|
|
|
|
5.183858644724E-2, 5.401138183398E-2, 5.654656186515E-2, 5.953130423884E-2, |
|
2095
|
|
|
|
|
|
|
6.308488965373E-2, 6.737503494905E-2, 7.264543556657E-2, 7.926471414968E-2, |
|
2096
|
|
|
|
|
|
|
8.781922325338E-2, 9.930398323927E-2, 0.11555994154118, 0.14043438342816, |
|
2097
|
|
|
|
|
|
|
0.18361418337460, 0.27900163464163, 0.70104742502766 |
|
2098
|
|
|
|
|
|
|
}; |
|
2099
|
|
|
|
|
|
|
static long i; |
|
2100
|
|
|
|
|
|
|
static double snorm,u,s,ustar,aa,w,y,tt; |
|
2101
|
80
|
|
|
|
|
|
u = ranf(); |
|
2102
|
80
|
|
|
|
|
|
s = 0.0; |
|
2103
|
80
|
100
|
|
|
|
|
if(u > 0.5) s = 1.0; |
|
2104
|
80
|
|
|
|
|
|
u += (u-s); |
|
2105
|
80
|
|
|
|
|
|
u = 32.0*u; |
|
2106
|
80
|
|
|
|
|
|
i = (long) (u); |
|
2107
|
80
|
50
|
|
|
|
|
if(i == 32) i = 31; |
|
2108
|
80
|
100
|
|
|
|
|
if(i == 0) goto S100; |
|
2109
|
|
|
|
|
|
|
/* |
|
2110
|
|
|
|
|
|
|
START CENTER |
|
2111
|
|
|
|
|
|
|
*/ |
|
2112
|
78
|
|
|
|
|
|
ustar = u-(double)i; |
|
2113
|
78
|
|
|
|
|
|
aa = *(a+i-1); |
|
2114
|
82
|
|
|
|
|
|
S40: |
|
2115
|
82
|
100
|
|
|
|
|
if(ustar <= *(t+i-1)) goto S60; |
|
2116
|
76
|
|
|
|
|
|
w = (ustar-*(t+i-1))**(h+i-1); |
|
2117
|
80
|
|
|
|
|
|
S50: |
|
2118
|
|
|
|
|
|
|
/* |
|
2119
|
|
|
|
|
|
|
EXIT (BOTH CASES) |
|
2120
|
|
|
|
|
|
|
*/ |
|
2121
|
80
|
|
|
|
|
|
y = aa+w; |
|
2122
|
80
|
|
|
|
|
|
snorm = y; |
|
2123
|
80
|
100
|
|
|
|
|
if(s == 1.0) snorm = -y; |
|
2124
|
80
|
|
|
|
|
|
return snorm; |
|
2125
|
6
|
|
|
|
|
|
S60: |
|
2126
|
|
|
|
|
|
|
/* |
|
2127
|
|
|
|
|
|
|
CENTER CONTINUED |
|
2128
|
|
|
|
|
|
|
*/ |
|
2129
|
6
|
|
|
|
|
|
u = ranf(); |
|
2130
|
6
|
|
|
|
|
|
w = u*(*(a+i)-aa); |
|
2131
|
6
|
|
|
|
|
|
tt = (0.5*w+aa)*w; |
|
2132
|
6
|
|
|
|
|
|
goto S80; |
|
2133
|
0
|
|
|
|
|
|
S70: |
|
2134
|
0
|
|
|
|
|
|
tt = u; |
|
2135
|
0
|
|
|
|
|
|
ustar = ranf(); |
|
2136
|
6
|
|
|
|
|
|
S80: |
|
2137
|
6
|
100
|
|
|
|
|
if(ustar > tt) goto S50; |
|
2138
|
4
|
|
|
|
|
|
u = ranf(); |
|
2139
|
4
|
50
|
|
|
|
|
if(ustar >= u) goto S70; |
|
2140
|
4
|
|
|
|
|
|
ustar = ranf(); |
|
2141
|
4
|
|
|
|
|
|
goto S40; |
|
2142
|
2
|
|
|
|
|
|
S100: |
|
2143
|
|
|
|
|
|
|
/* |
|
2144
|
|
|
|
|
|
|
START TAIL |
|
2145
|
|
|
|
|
|
|
*/ |
|
2146
|
2
|
|
|
|
|
|
i = 6; |
|
2147
|
2
|
|
|
|
|
|
aa = *(a+31); |
|
2148
|
2
|
|
|
|
|
|
goto S120; |
|
2149
|
10
|
|
|
|
|
|
S110: |
|
2150
|
10
|
|
|
|
|
|
aa += *(d+i-1); |
|
2151
|
10
|
|
|
|
|
|
i += 1; |
|
2152
|
12
|
|
|
|
|
|
S120: |
|
2153
|
12
|
|
|
|
|
|
u += u; |
|
2154
|
12
|
100
|
|
|
|
|
if(u < 1.0) goto S110; |
|
2155
|
2
|
|
|
|
|
|
u -= 1.0; |
|
2156
|
2
|
|
|
|
|
|
S140: |
|
2157
|
2
|
|
|
|
|
|
w = u**(d+i-1); |
|
2158
|
2
|
|
|
|
|
|
tt = (0.5*w+aa)*w; |
|
2159
|
2
|
|
|
|
|
|
goto S160; |
|
2160
|
0
|
|
|
|
|
|
S150: |
|
2161
|
0
|
|
|
|
|
|
tt = u; |
|
2162
|
2
|
|
|
|
|
|
S160: |
|
2163
|
2
|
|
|
|
|
|
ustar = ranf(); |
|
2164
|
2
|
50
|
|
|
|
|
if(ustar > tt) goto S50; |
|
2165
|
0
|
|
|
|
|
|
u = ranf(); |
|
2166
|
0
|
0
|
|
|
|
|
if(ustar >= u) goto S150; |
|
2167
|
0
|
|
|
|
|
|
u = ranf(); |
|
2168
|
0
|
|
|
|
|
|
goto S140; |
|
2169
|
|
|
|
|
|
|
} |
|
2170
|
|
|
|
|
|
|
|
|
2171
|
18
|
|
|
|
|
|
double fsign( double num, double sign ) |
|
2172
|
|
|
|
|
|
|
/* Transfers sign of argument sign to argument num */ |
|
2173
|
|
|
|
|
|
|
{ |
|
2174
|
18
|
100
|
|
|
|
|
if ( ( sign>0.0f && num<0.0f ) || ( sign<0.0f && num>0.0f ) ) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
2175
|
8
|
|
|
|
|
|
return -num; |
|
2176
|
10
|
|
|
|
|
|
else return num; |
|
2177
|
|
|
|
|
|
|
} |
|
2178
|
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
/************************************************************************ |
|
2180
|
|
|
|
|
|
|
FTNSTOP: |
|
2181
|
|
|
|
|
|
|
Prints msg to standard error and then exits |
|
2182
|
|
|
|
|
|
|
************************************************************************/ |
|
2183
|
0
|
|
|
|
|
|
void ftnstop(char* msg) |
|
2184
|
|
|
|
|
|
|
/* msg - error message */ |
|
2185
|
|
|
|
|
|
|
{ |
|
2186
|
0
|
0
|
|
|
|
|
if (msg != NULL) fprintf(stderr,"%s\n",msg); |
|
2187
|
0
|
|
|
|
|
|
exit(0); |
|
2188
|
|
|
|
|
|
|
} |