rubylabs 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +9 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/bin/bb.rb +12 -0
- data/bin/statistics2-0.53/ext/extconf.rb +11 -0
- data/bin/statistics2-0.53/ext/show.rb +11 -0
- data/bin/statistics2-0.53/ext/t.rb +46 -0
- data/bin/statistics2-0.53/mklist.rb +26 -0
- data/bin/statistics2-0.53/sample-tbl.rb +129 -0
- data/bin/statistics2-0.53/statistics2.rb +532 -0
- data/bin/statistics2-0.53/t-inv.rb +54 -0
- data/bin/statistics2.rb +532 -0
- data/data/aafreq.txt +20 -0
- data/data/cars.txt +50 -0
- data/data/century.txt +1 -0
- data/data/colors.txt +64 -0
- data/data/earth.yaml +15 -0
- data/data/fruit.txt +45 -0
- data/data/hacodes.txt +35 -0
- data/data/hafreq.txt +16 -0
- data/data/hvfreq.txt +5 -0
- data/data/nbody.R +23 -0
- data/data/nbody.out +731 -0
- data/data/nbody.pdf +3111 -0
- data/data/nbody.png +0 -0
- data/data/nbody3d.pdf +3201 -0
- data/data/outer.pdf +182785 -0
- data/data/solar.dat +36501 -0
- data/data/solarsystem.txt +17 -0
- data/data/suits.txt +1 -0
- data/data/wordlist.txt +210653 -0
- data/lib/bitlab.rb +624 -0
- data/lib/elizalab.rb +523 -0
- data/lib/encryptionlab.rb +42 -0
- data/lib/hashlab.rb +224 -0
- data/lib/introlab.rb +14 -0
- data/lib/iterationlab.rb +130 -0
- data/lib/randomlab.rb +294 -0
- data/lib/recursionlab.rb +228 -0
- data/lib/rubylabs.rb +507 -0
- data/lib/sievelab.rb +58 -0
- data/lib/sortlab.rb +213 -0
- data/lib/spherelab.rb +352 -0
- data/lib/temps.rb +41 -0
- data/lib/tsplab.rb +416 -0
- data/lib/viewer.rb +65 -0
- data/test/bit_test.rb +175 -0
- data/test/encryption_test.rb +20 -0
- data/test/iteration_test.rb +40 -0
- data/test/random_test.rb +64 -0
- data/test/recursion_test.rb +47 -0
- data/test/rubylabs_test.rb +18 -0
- data/test/sieve_test.rb +28 -0
- data/test/sphere_test.rb +130 -0
- data/test/temps_test.rb +24 -0
- data/test/test_helper.rb +18 -0
- metadata +112 -0
@@ -0,0 +1,532 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# statistics2.rb
|
4
|
+
#
|
5
|
+
# distributions of statistics
|
6
|
+
# by Shin-ichiro HARA
|
7
|
+
#
|
8
|
+
# 2003.09.25
|
9
|
+
#
|
10
|
+
# Ref:
|
11
|
+
# [1] http://www.matsusaka-u.ac.jp/~okumura/algo/
|
12
|
+
# [2] http://www5.airnet.ne.jp/tomy/cpro/sslib11.htm
|
13
|
+
|
14
|
+
module Statistics2
|
15
|
+
SQ2PI = Math.sqrt(2 * Math::PI)
|
16
|
+
|
17
|
+
# Newton approximation
|
18
|
+
def newton_a(y, ini, epsilon = 1.0e-6, limit = 30)
|
19
|
+
x = ini
|
20
|
+
limit.times do |i|
|
21
|
+
prev = x
|
22
|
+
f, df = yield(prev)
|
23
|
+
x = (y - f)/df + prev
|
24
|
+
if (x - prev).abs < epsilon
|
25
|
+
return x
|
26
|
+
end
|
27
|
+
end
|
28
|
+
$stderr.puts("Warning(newton approximation): over limit")
|
29
|
+
x
|
30
|
+
end
|
31
|
+
|
32
|
+
module_function :newton_a
|
33
|
+
private :newton_a
|
34
|
+
private_class_method :newton_a
|
35
|
+
|
36
|
+
# Gamma function
|
37
|
+
LOG_2PI = Math.log(2 * Math::PI)# log(2PI)
|
38
|
+
N = 8
|
39
|
+
B0 = 1.0
|
40
|
+
B1 = -1.0 / 2.0
|
41
|
+
B2 = 1.0 / 6.0
|
42
|
+
B4 = -1.0 / 30.0
|
43
|
+
B6 = 1.0 / 42.0
|
44
|
+
B8 = -1.0 / 30.0
|
45
|
+
B10 = 5.0 / 66.0
|
46
|
+
B12 = -691.0 / 2730.0
|
47
|
+
B14 = 7.0 / 6.0
|
48
|
+
B16 = -3617.0 / 510.0
|
49
|
+
|
50
|
+
def loggamma(x)
|
51
|
+
v = 1.0
|
52
|
+
while (x < N)
|
53
|
+
v *= x
|
54
|
+
x += 1.0
|
55
|
+
end
|
56
|
+
w = 1.0 / (x * x)
|
57
|
+
ret = B16 / (16 * 15)
|
58
|
+
ret = ret * w + B14 / (14 * 13)
|
59
|
+
ret = ret * w + B12 / (12 * 11)
|
60
|
+
ret = ret * w + B10 / (10 * 9)
|
61
|
+
ret = ret * w + B8 / ( 8 * 7)
|
62
|
+
ret = ret * w + B6 / ( 6 * 5)
|
63
|
+
ret = ret * w + B4 / ( 4 * 3)
|
64
|
+
ret = ret * w + B2 / ( 2 * 1)
|
65
|
+
ret = ret / x + 0.5 * LOG_2PI - Math.log(v) - x + (x - 0.5) * Math.log(x)
|
66
|
+
ret
|
67
|
+
end
|
68
|
+
|
69
|
+
def gamma(x)
|
70
|
+
if (x < 0.0)
|
71
|
+
return Math::PI / (Math.sin(Math.PI * x) * Math.exp(loggamma(1 - x))) #/
|
72
|
+
end
|
73
|
+
Math.exp(loggamma(x))
|
74
|
+
end
|
75
|
+
|
76
|
+
module_function :loggamma, :gamma
|
77
|
+
private :loggamma, :gamma
|
78
|
+
private_class_method :loggamma, :gamma
|
79
|
+
|
80
|
+
#normal-distribution
|
81
|
+
# (-\infty, z]
|
82
|
+
def p_nor(z)
|
83
|
+
if z < -12 then return 0.0 end
|
84
|
+
if z > 12 then return 1.0 end
|
85
|
+
if z == 0.0 then return 0.5 end
|
86
|
+
|
87
|
+
if z > 0.0
|
88
|
+
e = true
|
89
|
+
else
|
90
|
+
e = false
|
91
|
+
z = -z
|
92
|
+
end
|
93
|
+
z = z.to_f
|
94
|
+
z2 = z * z
|
95
|
+
t = q = z * Math.exp(-0.5 * z2) / SQ2PI
|
96
|
+
|
97
|
+
3.step(199, 2) do |i|
|
98
|
+
prev = q
|
99
|
+
t *= z2 / i
|
100
|
+
q += t
|
101
|
+
if q <= prev
|
102
|
+
return(e ? 0.5 + q : 0.5 - q)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
e ? 1.0 : 0.0
|
106
|
+
end
|
107
|
+
|
108
|
+
# inverse of normal distribution ([2])
|
109
|
+
# Pr( (-\infty, x] ) = qn -> x
|
110
|
+
def pnorm(qn)
|
111
|
+
b = [1.570796288, 0.03706987906, -0.8364353589e-3,
|
112
|
+
-0.2250947176e-3, 0.6841218299e-5, 0.5824238515e-5,
|
113
|
+
-0.104527497e-5, 0.8360937017e-7, -0.3231081277e-8,
|
114
|
+
0.3657763036e-10, 0.6936233982e-12]
|
115
|
+
|
116
|
+
if(qn < 0.0 || 1.0 < qn)
|
117
|
+
$stderr.printf("Error : qn <= 0 or qn >= 1 in pnorm()!\n")
|
118
|
+
return 0.0;
|
119
|
+
end
|
120
|
+
qn == 0.5 and return 0.0
|
121
|
+
|
122
|
+
w1 = qn
|
123
|
+
qn > 0.5 and w1 = 1.0 - w1
|
124
|
+
w3 = -Math.log(4.0 * w1 * (1.0 - w1))
|
125
|
+
w1 = b[0]
|
126
|
+
1.upto 10 do |i|
|
127
|
+
w1 += b[i] * w3**i;
|
128
|
+
end
|
129
|
+
qn > 0.5 and return Math.sqrt(w1 * w3)
|
130
|
+
-Math.sqrt(w1 * w3)
|
131
|
+
end
|
132
|
+
|
133
|
+
private :p_nor, :pnorm
|
134
|
+
module_function :p_nor, :pnorm
|
135
|
+
private_class_method :p_nor, :pnorm
|
136
|
+
|
137
|
+
#normal-distribution interface
|
138
|
+
def normaldist(z)
|
139
|
+
p_nor(z)
|
140
|
+
end
|
141
|
+
|
142
|
+
def pnormaldist(y)
|
143
|
+
pnorm(y)
|
144
|
+
end
|
145
|
+
|
146
|
+
#chi-square distribution ([1])
|
147
|
+
#[x, \infty)
|
148
|
+
def q_chi2(df, chi2)
|
149
|
+
chi2 = chi2.to_f
|
150
|
+
if (df & 1) != 0
|
151
|
+
chi = Math.sqrt(chi2)
|
152
|
+
if (df == 1) then return 2 * normal___x(chi); end
|
153
|
+
s = t = chi * Math.exp(-0.5 * chi2) / SQ2PI
|
154
|
+
k = 3
|
155
|
+
while k < df
|
156
|
+
t *= chi2 / k; s += t;
|
157
|
+
k += 2
|
158
|
+
end
|
159
|
+
2 * (normal___x(chi) + s)
|
160
|
+
else
|
161
|
+
s = t = Math.exp(-0.5 * chi2)
|
162
|
+
k = 2
|
163
|
+
while k < df
|
164
|
+
t *= chi2 / k; s += t;
|
165
|
+
k += 2
|
166
|
+
end
|
167
|
+
s
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def chi2dens(n, x)
|
172
|
+
if n == 1
|
173
|
+
1.0/Math.sqrt(2 * Math::PI * x) * Math::E**(-x/2.0)
|
174
|
+
elsif n == 2
|
175
|
+
0.5 * Math::E**(-x/2.0)
|
176
|
+
else
|
177
|
+
n = n.to_f
|
178
|
+
n2 = n/2
|
179
|
+
x = x.to_f
|
180
|
+
1.0 / 2**n2 / gamma(n2) * x**(n2 - 1.0) * Math.exp(-x/2.0)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# [x, \infty)
|
185
|
+
# Pr([x, \infty)) = y -> x
|
186
|
+
def pchi2(n, y)
|
187
|
+
if n == 1
|
188
|
+
w = pnorm(1 - y/2) # = pnormal___x(y/2)
|
189
|
+
w * w
|
190
|
+
elsif n == 2
|
191
|
+
# v = (1.0 / y - 1.0) / 33.0
|
192
|
+
# newton_a(y, v) {|x| [q_chi2(n, x), -chi2dens(n, x)] }
|
193
|
+
-2.0 * Math.log(y)
|
194
|
+
else
|
195
|
+
eps = 1.0e-5
|
196
|
+
v = 0.0
|
197
|
+
s = 10.0
|
198
|
+
loop do
|
199
|
+
v += s
|
200
|
+
if s <= eps then break end
|
201
|
+
if (qe = q_chi2(n, v) - y) == 0.0 then break end
|
202
|
+
if qe < 0.0
|
203
|
+
v -= s
|
204
|
+
s /= 10.0 #/
|
205
|
+
end
|
206
|
+
end
|
207
|
+
v
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
private :q_chi2, :pchi2, :chi2dens
|
212
|
+
module_function :q_chi2, :pchi2, :chi2dens
|
213
|
+
private_class_method :q_chi2, :pchi2, :chi2dens
|
214
|
+
|
215
|
+
# chi-square-distribution interface
|
216
|
+
def chi2dist(n, x); 1.0 - q_chi2(n, x); end
|
217
|
+
def pchi2dist(n, y); pchi2(n, 1.0 - y); end
|
218
|
+
|
219
|
+
|
220
|
+
# t-distribution ([1])
|
221
|
+
# (-\infty, x]
|
222
|
+
def p_t(df, t)
|
223
|
+
c2 = df.to_f / (df + t * t);
|
224
|
+
s = Math.sqrt(1.0 - c2)
|
225
|
+
s = -s if t < 0.0
|
226
|
+
p = 0.0;
|
227
|
+
i = df % 2 + 2
|
228
|
+
while i <= df
|
229
|
+
p += s
|
230
|
+
s *= (i - 1) * c2 / i
|
231
|
+
i += 2
|
232
|
+
end
|
233
|
+
if df & 1 != 0
|
234
|
+
0.5+(p*Math.sqrt(c2)+Math.atan(t/Math.sqrt(df)))/Math::PI
|
235
|
+
else
|
236
|
+
(1.0 + p) / 2.0
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# inverse of t-distribution ([2])
|
241
|
+
# (-\infty, -q/2] + [q/2, \infty)
|
242
|
+
def ptsub(q, n)
|
243
|
+
q = q.to_f
|
244
|
+
if(n == 1 && 0.001 < q && q < 0.01)
|
245
|
+
eps = 1.0e-4
|
246
|
+
elsif (n == 2 && q < 0.0001)
|
247
|
+
eps = 1.0e-4
|
248
|
+
elsif (n == 1 && q < 0.001)
|
249
|
+
eps = 1.0e-2
|
250
|
+
else
|
251
|
+
eps = 1.0e-5
|
252
|
+
end
|
253
|
+
s = 10000.0
|
254
|
+
w = 0.0
|
255
|
+
loop do
|
256
|
+
w += s
|
257
|
+
if(s <= eps) then return w end
|
258
|
+
if((qe = 2.0 - p_t(n, w)*2.0 - q) == 0.0) then return w end
|
259
|
+
if(qe < 0.0)
|
260
|
+
w -= s
|
261
|
+
s /= 10.0 #/
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def pt(q, n)
|
267
|
+
q = q.to_f
|
268
|
+
if(q < 1.0e-5 || q > 1.0 || n < 1)
|
269
|
+
$stderr.printf("Error : Illigal parameter in pt()!\n")
|
270
|
+
return 0.0
|
271
|
+
end
|
272
|
+
|
273
|
+
if(n <= 5) then return ptsub(q, n) end
|
274
|
+
if(q <= 5.0e-3 && n <= 13) then return ptsub(q, n) end
|
275
|
+
|
276
|
+
f1 = 4.0 * (f = n.to_f)
|
277
|
+
f5 = (f4 = (f3 = (f2 = f * f) * f) * f) * f
|
278
|
+
f2 *= 96.0
|
279
|
+
f3 *= 384.0
|
280
|
+
f4 *= 92160.0
|
281
|
+
f5 *= 368640.0
|
282
|
+
u = pnormaldist(1.0 - q / 2.0)
|
283
|
+
|
284
|
+
w0 = (u2 = u * u) * u
|
285
|
+
w1 = w0 * u2
|
286
|
+
w2 = w1 * u2
|
287
|
+
w3 = w2 * u2
|
288
|
+
w4 = w3 * u2
|
289
|
+
w = (w0 + u) / f1
|
290
|
+
w += (5.0 * w1 + 16.0 * w0 + 3.0 * u) / f2
|
291
|
+
w += (3.0 * w2 + 19.0 * w1 + 17.0 * w0 - 15.0 * u) / f3
|
292
|
+
w += (79.0 * w3 + 776.0 * w2 + 1482.0 * w1 - 1920.0 * w0 - 9450.0 * u) / f4
|
293
|
+
w += (27.0 * w4 + 339.0 * w3 + 930.0 * w2 - 1782.0 * w1 - 765.0 * w0 + 17955.0 * u) / f5
|
294
|
+
u + w
|
295
|
+
end
|
296
|
+
|
297
|
+
private :p_t, :pt, :ptsub
|
298
|
+
module_function :p_t, :pt, :ptsub
|
299
|
+
private_class_method :p_t, :pt, :ptsub
|
300
|
+
|
301
|
+
# t-distribution interface
|
302
|
+
def tdist(n, t); p_t(n, t); end
|
303
|
+
def ptdist(n, y)
|
304
|
+
if y > 0.5
|
305
|
+
pt(2.0 - y*2.0, n)
|
306
|
+
else
|
307
|
+
- pt(y*2.0, n)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# F-distribution ([1])
|
312
|
+
# [x, \infty)
|
313
|
+
def q_f(df1, df2, f)
|
314
|
+
if (f <= 0.0) then return 1.0; end
|
315
|
+
if (df1 % 2 != 0 && df2 % 2 == 0)
|
316
|
+
return 1.0 - q_f(df2, df1, 1.0 / f)
|
317
|
+
end
|
318
|
+
cos2 = 1.0 / (1.0 + df1.to_f * f / df2.to_f)
|
319
|
+
sin2 = 1.0 - cos2
|
320
|
+
|
321
|
+
if (df1 % 2 == 0)
|
322
|
+
prob = cos2 ** (df2.to_f / 2.0)
|
323
|
+
temp = prob
|
324
|
+
i = 2
|
325
|
+
while i < df1
|
326
|
+
temp *= (df2.to_f + i - 2) * sin2 / i
|
327
|
+
prob += temp
|
328
|
+
i += 2
|
329
|
+
end
|
330
|
+
return prob
|
331
|
+
end
|
332
|
+
prob = Math.atan(Math.sqrt(df2.to_f / (df1.to_f * f)))
|
333
|
+
temp = Math.sqrt(sin2 * cos2)
|
334
|
+
i = 3
|
335
|
+
while i <= df1
|
336
|
+
prob += temp
|
337
|
+
temp *= (i - 1).to_f * sin2 / i.to_f;
|
338
|
+
i += 2.0
|
339
|
+
end
|
340
|
+
temp *= df1.to_f
|
341
|
+
i = 3
|
342
|
+
while i <= df2
|
343
|
+
prob -= temp
|
344
|
+
temp *= (df1.to_f + i - 2) * cos2 / i.to_f
|
345
|
+
i += 2
|
346
|
+
end
|
347
|
+
prob * 2.0 / Math::PI
|
348
|
+
end
|
349
|
+
|
350
|
+
# inverse of F-distribution ([2])
|
351
|
+
def pfsub(x, y, z)
|
352
|
+
(Math.sqrt(z) - y) / x / 2.0
|
353
|
+
end
|
354
|
+
|
355
|
+
# [x, \infty)
|
356
|
+
def pf(q, n1, n2)
|
357
|
+
if(q < 0.0 || q > 1.0 || n1 < 1 || n2 < 1)
|
358
|
+
$stderr.printf("Error : Illegal parameter in pf()!\n")
|
359
|
+
return 0.0
|
360
|
+
end
|
361
|
+
|
362
|
+
if n1 <= 240 || n2 <= 240
|
363
|
+
eps = 1.0e-5
|
364
|
+
if(n2 == 1) then eps = 1.0e-4 end
|
365
|
+
fw = 0.0
|
366
|
+
s = 1000.0
|
367
|
+
loop do
|
368
|
+
fw += s
|
369
|
+
if s <= eps then return fw end
|
370
|
+
if (qe = q_f(n1, n2, fw) - q) == 0.0 then return fw end
|
371
|
+
if qe < 0.0
|
372
|
+
fw -= s
|
373
|
+
s /= 10.0 #/
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
eps = 1.0e-6
|
379
|
+
qn = q
|
380
|
+
if q < 0.5 then qn = 1.0 - q
|
381
|
+
u = pnorm(qn)
|
382
|
+
w1 = 2.0 / n1 / 9.0
|
383
|
+
w2 = 2.0 / n2 / 9.0
|
384
|
+
w3 = 1.0 - w1
|
385
|
+
w4 = 1.0 - w2
|
386
|
+
u2 = u * u
|
387
|
+
a = w4 * w4 - u2 * w2
|
388
|
+
b = -2. * w3 * w4
|
389
|
+
c = w3 * w3 - u2 * w1
|
390
|
+
d = b * b - 4 * a * c
|
391
|
+
if(d < 0.0)
|
392
|
+
fw = pfsub(a, b, 0.0)
|
393
|
+
else
|
394
|
+
if(a.abs > eps)
|
395
|
+
fw = pfsub(a, b, d)
|
396
|
+
else
|
397
|
+
if(b.abs > eps) then return -c / b end
|
398
|
+
fw = pfsub(a, b, 0.0)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
fw * fw * fw
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
private :q_f, :pf, :pfsub
|
406
|
+
module_function :q_f, :pf, :pfsub
|
407
|
+
private_class_method :q_f, :pf, :pfsub
|
408
|
+
|
409
|
+
# F-distribution interface
|
410
|
+
def fdist(n1, n2, f); 1.0 - q_f(n1, n2, f); end
|
411
|
+
def pfdist(n1, n2, y); pf(1.0 - y, n1, n2); end
|
412
|
+
|
413
|
+
############################################################################
|
414
|
+
# discrete distributions
|
415
|
+
|
416
|
+
def perm(n, x = n)
|
417
|
+
raise RangeError if n < 0 || x < 0
|
418
|
+
r = 1
|
419
|
+
while x >= 1
|
420
|
+
r *= n
|
421
|
+
n -= 1
|
422
|
+
x -= 1
|
423
|
+
end
|
424
|
+
r
|
425
|
+
end
|
426
|
+
|
427
|
+
def combi(n, x)
|
428
|
+
raise RangeError if n < 0 || x < 0
|
429
|
+
x = n - x if x*2 > n
|
430
|
+
perm(n, x) / perm(x, x)
|
431
|
+
end
|
432
|
+
|
433
|
+
module_function :perm, :combi
|
434
|
+
private_class_method :perm, :combi
|
435
|
+
|
436
|
+
def bindens(n, p, x)
|
437
|
+
p = p.to_f
|
438
|
+
q = 1.0 - p
|
439
|
+
combi(n, x) * p**x * q**(n - x)
|
440
|
+
end
|
441
|
+
|
442
|
+
def bindist(n, p, x)
|
443
|
+
(0..x).inject(0.0) do |s, k|
|
444
|
+
s + bindens(n, p, k)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def poissondens(m, x)
|
449
|
+
return 0.0 if x < 0
|
450
|
+
m = m.to_f
|
451
|
+
m ** x * Math::E ** (-m) / perm(x)
|
452
|
+
end
|
453
|
+
|
454
|
+
def poissondist(m, x)
|
455
|
+
(0..x).inject(0.0) do |s, k|
|
456
|
+
s + poissondens(m, k)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
############################################################################
|
461
|
+
|
462
|
+
# normal-distribution
|
463
|
+
def normalxXX_(z); normaldist(z); end
|
464
|
+
def normal__X_(z); normaldist(z) - 0.5; end
|
465
|
+
def normal___x(z); 1.0 - normaldist(z); end
|
466
|
+
def normalx__x(z); 2.0 - normaldist(z) * 2.0; end
|
467
|
+
module_function :normaldist, :normalxXX_, :normal__X_, :normal___x, :normalx__x
|
468
|
+
|
469
|
+
# inverse of normal-distribution
|
470
|
+
def pnormalxXX_(z); pnormaldist(z); end
|
471
|
+
def pnormal__X_(y); pnormalxXX_(y + 0.5); end
|
472
|
+
def pnormal___x(y); pnormalxXX_(1.0 - y); end
|
473
|
+
def pnormalx__x(y); pnormalxXX_(1.0 - y/2.0); end
|
474
|
+
module_function :pnormaldist, :pnormalxXX_, :pnormal__X_, :pnormal___x, :pnormalx__x
|
475
|
+
|
476
|
+
|
477
|
+
# chi2-distribution
|
478
|
+
def chi2_x(n, x); 1.0 - chi2dist(n, x); end
|
479
|
+
def chi2X_(n, x); chi2dist(n, x); end
|
480
|
+
module_function :chi2dist, :chi2X_, :chi2_x
|
481
|
+
|
482
|
+
# inverse of chi2-distribution
|
483
|
+
def pchi2_x(n, y); pchi2dist(n, 1.0 - y); end
|
484
|
+
def pchi2X_(n, y); pchi2dist(n, y); end
|
485
|
+
module_function :pchi2dist, :pchi2X_, :pchi2_x
|
486
|
+
|
487
|
+
|
488
|
+
# t-distribution
|
489
|
+
def tx__x(n, x); 2.0 - tdist(n, x) * 2.0; end
|
490
|
+
def txXX_(n, x); tdist(n, x); end
|
491
|
+
def t__X_(n, x); tdist(n, x) - 0.5; end
|
492
|
+
def t___x(n, x); 1.0 - tdist(n, x); end
|
493
|
+
module_function :tdist, :txXX_, :t__X_, :t___x, :tx__x
|
494
|
+
|
495
|
+
# inverse of t-distribution
|
496
|
+
def ptx__x(n, y); ptdist(n, 1.0 - y / 2.0); end
|
497
|
+
def ptxXX_(n, y); ptdist(n, y); end
|
498
|
+
def pt__X_(n, y); ptdist(n, 0.5 + y); end
|
499
|
+
def pt___x(n, y); ptdist(n, 1.0 - y); end
|
500
|
+
module_function :ptdist, :ptxXX_, :pt__X_, :pt___x, :ptx__x
|
501
|
+
|
502
|
+
|
503
|
+
# F-distribution
|
504
|
+
def f_x(n1, n2, x); 1.0 - fdist(n1, n2, x); end
|
505
|
+
def fX_(n1, n2, x); fdist(n1, n2, x); end
|
506
|
+
module_function :fdist, :fX_, :f_x
|
507
|
+
|
508
|
+
# inverse of F-distribution
|
509
|
+
def pf_x(n1, n2, x); pfdist(n1, n2, 1.0 - x); end
|
510
|
+
def pfX_(n1, n2, x); pfdist(n1, n2, x); end
|
511
|
+
module_function :pfdist, :pfX_, :pf_x
|
512
|
+
|
513
|
+
# discrete distributions
|
514
|
+
def binX_(n, p, x); bindist(n, p, x); end
|
515
|
+
def bin_x(n, p, x); bindist(n, 1.0 - p, n - x); end
|
516
|
+
module_function :bindens, :bindist, :binX_, :bin_x
|
517
|
+
|
518
|
+
def poissonX_(m, x); poissondist(m, x); end
|
519
|
+
def poisson_x(m, x); 1.0 - poissondist(m, x-1); end
|
520
|
+
module_function :poissondens, :poissondist, :poissonX_, :poisson_x
|
521
|
+
end
|
522
|
+
|
523
|
+
|
524
|
+
if $0 == __FILE__
|
525
|
+
if ARGV.empty?
|
526
|
+
puts "Example:"
|
527
|
+
puts " #$0 normaldist 0.01"
|
528
|
+
puts " #$0 pf_x 2 3 0.01"
|
529
|
+
exit
|
530
|
+
end
|
531
|
+
p Statistics2.send(ARGV[0], *ARGV[1..-1].map{|x| eval(x)})
|
532
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
if $0 == __FILE__
|
2
|
+
require 'test/unit'
|
3
|
+
$test = true
|
4
|
+
require 'sample-tbl'
|
5
|
+
require 'statistics2.rb'
|
6
|
+
end
|
7
|
+
|
8
|
+
class T_Statistics2 < Test::Unit::TestCase
|
9
|
+
$mod = Statistics2
|
10
|
+
|
11
|
+
def inv(s); "p" + s; end
|
12
|
+
|
13
|
+
def test_inv_normal
|
14
|
+
delta = 1.0e-6
|
15
|
+
meth = "normal___x"
|
16
|
+
norm_tbl(0.00001, 4.0) do |x|
|
17
|
+
pr = $mod.send(meth, x)
|
18
|
+
x0 = $mod.send(inv(meth), pr)
|
19
|
+
assert_in_delta x0/x, 1.0, delta
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_inv_chi
|
24
|
+
delta = 1.0e-4
|
25
|
+
meth = "chi2_x"
|
26
|
+
chi2_tbl() do |n, pr|
|
27
|
+
x = $mod.send(inv(meth), n, pr)
|
28
|
+
pr0 = $mod.send(meth, n, x)
|
29
|
+
assert_in_delta pr0/pr, 1.0, delta
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_inv_t
|
34
|
+
delta = 1.0e-3
|
35
|
+
meth = "tx__x"
|
36
|
+
t_tbl() do |n, pr|
|
37
|
+
x = $mod.send(inv(meth), n, pr)
|
38
|
+
pr0 = $mod.send(meth, n, x)
|
39
|
+
assert_in_delta pr0/pr, 1.0, delta
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_inv_f
|
44
|
+
delta = 1.0e-3
|
45
|
+
meth = "f_x"
|
46
|
+
[0.01, 0.025, 0.05].each do |opt|
|
47
|
+
f_tbl(opt) do |n1, n2, pr|
|
48
|
+
x = $mod.send(inv(meth), n1, n2, pr)
|
49
|
+
pr0 = $mod.send(meth, n1, n2, x)
|
50
|
+
assert_in_delta pr0/pr, 1.0, delta
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|