statsample 0.3.4 → 0.4.0

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