statistics2 0.54

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.
@@ -0,0 +1,12 @@
1
+ = 0.53(2008.07.14)
2
+
3
+ * fix pt for p < 0.5.
4
+
5
+ = 0.52(2008.02.24)
6
+
7
+ * fix p_nor for z < 0.0.
8
+
9
+ = 0.51(2007.06.17)
10
+ * fix p_nor.
11
+ * simplify chi2 n = 1 or 2.
12
+
@@ -0,0 +1,15 @@
1
+ History.rdoc
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ examples/mklist.rb
6
+ examples/show.rb
7
+ ext/extconf.rb
8
+ ext/statistics2.c
9
+ lib/statistics2.rb
10
+ lib/statistics2/no_ext.rb
11
+ lib/statistics2/version.rb
12
+ statistics2.gemspec
13
+ test/sample_tbl.rb
14
+ test/test_ext.rb
15
+ test/test_inv.rb
@@ -0,0 +1,29 @@
1
+ = Statistics2: Statistical Distributions for Ruby
2
+
3
+ Authors: Shin-ichiro HARA(sinara@blade.nagaokaut.ac.jp), Brendan Ribera (brendan.ribera@gmail.com)
4
+
5
+ == REQUIREMENTS:
6
+
7
+ * ruby-1.8 or higher
8
+
9
+
10
+ == INSTALL:
11
+
12
+ * Get the gem from Github!
13
+ $ gem sources -a http://gems.github.com (you only have to do this once)
14
+ $ sudo gem install abscondment-statistics2
15
+
16
+
17
+ == USAGE:
18
+
19
+ * Example:
20
+ require "statistics2"
21
+ puts Statistics2.normaldist(0.27) #=> 0.60641987319804
22
+
23
+ * If you don't want to use the C extension:
24
+ require "statistics2/no_ext"
25
+ puts Statistics2.normaldist(0.27) #=> 0.606419873198039 (delta of 9.99200722162641e-16)
26
+
27
+ == LICENSE:
28
+
29
+ Ruby's (see http://www.ruby-lang.org/en/LICENSE.txt)
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require 'lib/statistics2/version'
4
+
5
+ EXT = "ext/statistics2.so"
6
+
7
+ Hoe.spec 'statistics2' do
8
+ developer 'Brendan Ribera', 'brendan.ribera@gmail.com'
9
+ developer 'Shin-ichiro Hara', 'sinara@blade.nagaokaut.ac.jp'
10
+
11
+ self.version = Statistics2::VERSION
12
+ self.readme_file = 'README.rdoc'
13
+ self.history_file = 'History.rdoc'
14
+ self.url = 'http://github.com/abscondment/statistics2'
15
+ self.summary = 'Statistical Distributions for Ruby. Based on Shin-ichiro Hara\'s original library, updated for Ruby 1.9'
16
+ self.description = 'Statistics2 is a module that provides normal, Chi-square, t- and F- probability distributions for Ruby. It is a fork/continuation of Shin-ichiro Hara\'s original code. It provides a native, compiled extension and a pure Ruby implementation.'
17
+ # C extension goodness
18
+ self.spec_extras[:extensions] = "ext/extconf.rb"
19
+ self.clean_globs << EXT << 'ext/*.o' << 'ext/Makefile'
20
+ end
21
+
22
+ desc "Compile extensions"
23
+ task :compile => EXT
24
+ task :test => :compile
25
+
26
+ file EXT => ['ext/extconf.rb', 'ext/statistics2.c'] do
27
+ Dir.chdir 'ext' do
28
+ ruby 'extconf.rb'
29
+ sh 'make'
30
+ end
31
+ end
32
+
33
+ desc "Prepare for github upload"
34
+ task :github do
35
+ system "git ls-files | egrep -v \"\\.gitignore\" > Manifest.txt"
36
+ system "rake debug_gem | egrep -v \"^\\(in\" > statistics2.gemspec"
37
+ end
38
+
39
+ task :gem => :github
40
+
41
+ task :default => [:test]
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ cmd = "ruby #{File.expand_path(File.join(File.dirname(__FILE__), '/../test/sample_tbl.rb'))}"
3
+ param_tbl = {
4
+ "norm" => "tbl-normal.tbl",
5
+ "chi2" => "tbl-chi2.tbl",
6
+ "t" => "tbl-t.tbl",
7
+ "f 0.05" => "tbl-F50.tbl",
8
+ "f 0.025" => "tbl-F25.tbl",
9
+ "f 0.01" => "tbl-F10.tbl"
10
+ }
11
+
12
+ printf 'Generating tables'
13
+ param_tbl.each do |pa, tbl|
14
+ printf '.'
15
+ STDOUT.flush()
16
+ `#{cmd} #{pa} > #{File.expand_path(File.join(File.dirname(__FILE__), tbl))}`
17
+ end
18
+ puts "finished."
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require "statistics2"
4
+ if $0 == __FILE__
5
+ if ARGV.empty?
6
+ puts "Example:"
7
+ puts " #$0 normaldist 0.01"
8
+ puts " #$0 pf_x 2 3 0.01"
9
+ exit
10
+ end
11
+ p Statistics2.send(ARGV[0], *ARGV[1..-1].map{|x| eval(x)})
12
+ end
@@ -0,0 +1,2 @@
1
+ require "mkmf"
2
+ create_makefile("statistics2")
@@ -0,0 +1,848 @@
1
+ /*
2
+ statistics2.c
3
+
4
+ distributions of statistics2
5
+ by Shin-ichiro HARA
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
+
14
+ #include "ruby.h"
15
+ #include <math.h>
16
+ #include <errno.h>
17
+
18
+ #ifndef RUBY_19
19
+ #ifndef RFLOAT_VALUE
20
+ #define RFLOAT_VALUE(v) (RFLOAT(v)->value)
21
+ #endif
22
+ #endif
23
+
24
+ #define PI 3.14159265358979324
25
+ #define Need_Float(x) (x) = rb_Float(x)
26
+
27
+ VALUE rb_mStatistics2;
28
+
29
+ /* normal distribution ([1]) */
30
+ /* P( (-\infty, z] ) */
31
+ static double p_nor(double z)
32
+ {
33
+ int i, e;
34
+ double z2, prev, p, t;
35
+
36
+ if (z < -12) {return 0.0;}
37
+ if (z > 12) {return 1.0;}
38
+ if (z == 0.0) {return 0.5;}
39
+
40
+ if (z > 0) {
41
+ e = 1;
42
+ } else if (z == 0) {
43
+ return 0.5;
44
+ } else {
45
+ e = 0;
46
+ z = -z;
47
+ }
48
+
49
+ z2 = z * z;
50
+ t = p = z * exp(-0.5 * z2) / sqrt(2 * PI);
51
+ for (i = 3; i < 200; i += 2) {
52
+ prev = p; t *= z2 / i; p += t;
53
+ if (p <= prev) return(e ? 0.5 + p : 0.5 - p);
54
+ }
55
+ return (e ? 1.0 : 0.0);
56
+ }
57
+
58
+ /* inverse of normal distribution ([2]) */
59
+ /* P( (-\infty, z] ) = qn -> z a*/
60
+ static double pnorm(double qn)
61
+ {
62
+ static double b[11] = {1.570796288, 0.03706987906, -0.8364353589e-3,
63
+ -0.2250947176e-3, 0.6841218299e-5, 0.5824238515e-5,
64
+ -0.104527497e-5, 0.8360937017e-7,-0.3231081277e-8,
65
+ 0.3657763036e-10,0.6936233982e-12};
66
+ double w1, w3;
67
+ int i;
68
+
69
+ if(qn < 0. || 1. < qn)
70
+ {
71
+ fprintf(stderr, "Error : qn <= 0 or qn >= 1 in pnorm()!\n");
72
+ return 0.;
73
+ }
74
+ if(qn == 0.5) return 0.;
75
+
76
+ w1 = qn;
77
+ if(qn > 0.5) w1 = 1. - w1;
78
+ w3 = -log(4. * w1 * (1. - w1));
79
+ w1 = b[0];
80
+ for(i = 1; i < 11; i++) w1 += (b[i] * pow(w3, (double)i));
81
+ if(qn > 0.5) return sqrt(w1 * w3);
82
+ return -sqrt(w1 * w3);
83
+ }
84
+
85
+
86
+ /* normal-distribution interface */
87
+ static double normaldist(z)
88
+ double z;
89
+ {
90
+ return p_nor(z);
91
+ }
92
+
93
+ static double pnormaldist(qn)
94
+ double qn;
95
+ {
96
+ return pnorm(qn);
97
+ }
98
+
99
+
100
+ /* chi-square distribution ([1]) */
101
+ /* [x, \infty) */
102
+ static double q_chi2(int df, double chi2)
103
+ {
104
+ int k;
105
+ double s, t, chi;
106
+
107
+ if (df & 1) {
108
+ chi = sqrt(chi2);
109
+ if (df == 1) return 2 * (1.0 - normaldist(chi));
110
+ s = t = chi * exp(-0.5 * chi2) / sqrt(2 * PI);
111
+ for (k = 3; k < df; k += 2) {
112
+ t *= chi2 / k; s += t;
113
+ }
114
+ return 2 * (1.0 - normaldist(chi) + s);
115
+ } else {
116
+ s = t = exp(-0.5 * chi2);
117
+ for (k = 2; k < df; k += 2) {
118
+ t *= chi2 / k; s += t;
119
+ }
120
+ return s;
121
+ }
122
+ }
123
+
124
+ /* inverse of chi-square distribution */
125
+ /*
126
+ static double chi2dens(n, x)
127
+ int n;
128
+ double x;
129
+ {
130
+ double n2 = ((double) n)/2.0;
131
+ return 1.0 / pow(2, n2) / gamma(n2) * pow(x,(n2 - 1.0)) * exp(-x/2.0);
132
+ }
133
+ */
134
+ /*
135
+ static double newton_chi(n, y, ini)
136
+ int n;
137
+ double y, ini;
138
+ {
139
+ double epsilon = 1.0e-6, x = ini, prev, df, f;
140
+ int limit = 30, i;
141
+ for (i = 0; i < 30; i++) {
142
+ prev = x;
143
+ f = q_chi2(n, prev);
144
+ df = - chi2dens(n, prev);
145
+ x = (y - f)/df + prev;
146
+ if (fabs(x - prev) < epsilon) return x;
147
+ }
148
+ fprintf(stderr, "Warning(newton approximation): over limit\n");
149
+ return x;
150
+ }
151
+ */
152
+
153
+ /* [x, \infty) */
154
+ static double pchi2(y, n)
155
+ int n;
156
+ double y;
157
+ {
158
+ double v, s, qe, eps, w;
159
+ if (n == 1) {
160
+ w = pnorm(1.0 - y/2);
161
+ return(w * w);
162
+ } else if (n == 2) {
163
+ /* v = (1.0 / y - 1.0) / 33.0;
164
+ return newton_chi(n, y, v); */
165
+ return(-2.0 * log(y));
166
+ }
167
+ else {
168
+ eps = 1.0e-5;
169
+ v = 0.0;
170
+ s = 10.0;
171
+ for (;;) {
172
+ v += s;
173
+ if (s <= eps) break;
174
+ if ((qe = q_chi2(n, v) - y) == 0.0) break;
175
+ if (qe < 0.0) {
176
+ v -= s;
177
+ s /= 10.0;
178
+ }
179
+ }
180
+ return v;
181
+ }
182
+ }
183
+
184
+ /* chi-square-distribution interface */
185
+
186
+ static double chi2dist(df, chi2)
187
+ int df;
188
+ double chi2;
189
+ {
190
+ return 1.0 - q_chi2(df, chi2);
191
+ }
192
+
193
+ static double pchi2dist(n, y)
194
+ double y;
195
+ int n;
196
+ {
197
+ return pchi2(1.0 - y, n);
198
+ }
199
+
200
+
201
+ /* t-distribution ([1]) */
202
+ /* (-\infty, x] */
203
+ double p_t(int df, double t)
204
+ {
205
+ int i;
206
+ double c2, p, s;
207
+
208
+ c2 = df / (df + t * t);
209
+ s = sqrt(1 - c2); if (t < 0) s = -s;
210
+ p = 0.0;
211
+ for (i = df % 2 + 2; i <= df; i += 2) {
212
+ p += s; s *= (i - 1) * c2 / i;
213
+ }
214
+ if (df & 1)
215
+ return 0.5+(p*sqrt(c2)+atan(t/sqrt(df)))/PI;
216
+ else
217
+ return (1.0 + p) / 2.0;
218
+ }
219
+
220
+
221
+ double ptsub(double q, int n)
222
+ {
223
+ double eps, qe, s, w;
224
+
225
+ if(n == 1 && 0.001 <= q && q < 0.01) eps = 1.e-4;
226
+ else if (n == 2 && q < 0.0001) eps = 1.e-4;
227
+ else if (n == 1 && q < 0.001) eps = 1.e-2;
228
+ else eps = 1.e-5;
229
+ s = 10000.;
230
+ w = 0.;
231
+ for(;;)
232
+ {
233
+ w += s;
234
+ if(s <= eps) return w;
235
+ if((qe = 2.0 - p_t(n, w)*2.0 - q) == 0.) return w;
236
+ if(qe < 0.)
237
+ {
238
+ w -= s;
239
+ s /= 10.;
240
+ }
241
+ }
242
+ }
243
+
244
+ /* inverse of t-distribution ([2]) */
245
+ /* (-\infty, -q/2] + [q/2, \infty) */
246
+ double pt(double q, int n)
247
+ {
248
+ double f, f1, f2, f3, f4, f5, u, u2, w, w0, w1, w2, w3, w4;
249
+
250
+ if(q < 1.e-5 || q > 1. || n < 1)
251
+ {
252
+ fprintf(stderr,"Error : Illigal parameter in pt()!\n");
253
+ return 0.;
254
+ }
255
+
256
+ if(n <= 5) return ptsub(q, n);
257
+
258
+ if(q <= 5.e-3 && n <= 13) return ptsub(q, n);
259
+
260
+ f1 = 4. * (f = (double)n);
261
+ f5 = (f4 = (f3 = (f2 = f * f) * f) * f) * f;
262
+ f2 *= 96.;
263
+ f3 *= 384.;
264
+ f4 *= 92160.;
265
+ f5 *= 368640.;
266
+ u = pnormaldist(1. - q / 2.);
267
+
268
+ w0 = (u2 = u * u) * u;
269
+ w1 = w0 * u2;
270
+ w2 = w1 * u2;
271
+ w3 = w2 * u2;
272
+ w4 = w3 * u2;
273
+ w = ((w0 + u) / f1);
274
+ w += ((5. * w1 + 16. * w0 + 3. * u) / f2);
275
+ w += ((3. * w2 + 19. * w1 + 17. * w0 - 15. * u) / f3);
276
+ w += ((79. * w3 + 776. * w2 + 1482. * w1 - 1920. * w0 - 945. * u) / f4);
277
+ w += ((27. * w4 + 339. * w3 + 930. * w2 - 1782. * w1 - 765. * w0
278
+ + 17955. * u) / f5);
279
+ return u + w;
280
+ }
281
+
282
+
283
+ /* t-distribution interface */
284
+ static double tdist(n, t)
285
+ int n;
286
+ double t;
287
+ {
288
+ return p_t(n, t);
289
+ }
290
+
291
+ static double ptdist(n, y)
292
+ double y;
293
+ int n;
294
+ {
295
+ return (y > 0.5 ? pt(2.0 - y*2.0, n) : -pt(y*2.0, n));
296
+ }
297
+
298
+
299
+ /* F-distribution ([1]) */
300
+ /* [x, \infty) */
301
+ double q_f(int df1, int df2, double f)
302
+ {
303
+ int i;
304
+ double cos2, sin2, prob, temp;
305
+
306
+ if (f <= 0) return 1;
307
+ if (df1 % 2 != 0 && df2 % 2 == 0)
308
+ return 1 - q_f(df2, df1, 1 / f);
309
+ cos2 = 1 / (1 + df1 * f / df2); sin2 = 1 - cos2;
310
+ if (df1 % 2 == 0) {
311
+ prob = pow(cos2, df2 / 2.0); temp = prob;
312
+ for (i = 2; i < df1; i += 2) {
313
+ temp *= (df2 + i - 2) * sin2 / i;
314
+ prob += temp;
315
+ }
316
+ return prob;
317
+ }
318
+ prob = atan(sqrt(df2 / (df1 * f)));
319
+ temp = sqrt(sin2 * cos2);
320
+ for (i = 3; i <= df1; i += 2) {
321
+ prob += temp; temp *= (i - 1) * sin2 / i;
322
+ }
323
+ temp *= df1;
324
+ for (i = 3; i <= df2; i += 2) {
325
+ prob -= temp;
326
+ temp *= (df1 + i - 2) * cos2 / i;
327
+ }
328
+ return prob * 2 / PI;
329
+ }
330
+
331
+ /* inverse of F-distribution ([2]) */
332
+ double pfsub(double x, double y, double z)
333
+ {
334
+ return (sqrt(z) - y) / x / 2.;
335
+ }
336
+
337
+ /* [x, \infty) */
338
+ double pf(double q, int n1, int n2)
339
+ {
340
+ double a, b, c, d, eps, fw, qe, qn, s, u, u2, w1, w2, w3, w4;
341
+
342
+ if(q < 0. || q > 1. || n1 < 1 || n2 < 1)
343
+ {
344
+ fprintf(stderr,"Error : Illegal parameter in pf()!\n");
345
+ return 0.;
346
+ }
347
+
348
+ if(n1 <= 240 || n2 <= 240)
349
+ {
350
+ eps = 1.e-5;
351
+ if(n2 == 1) eps = 1.e-4;
352
+ s = 1000.;
353
+ fw = 0.;
354
+ for(;;)
355
+ {
356
+ fw += s;
357
+ if(s <= eps) return fw;
358
+ if((qe = q_f(n1, n2, fw) - q) == 0.) return fw;
359
+ if(qe < 0.)
360
+ {
361
+ fw -= s;
362
+ s /= 10.;
363
+ }
364
+ }
365
+ }
366
+
367
+ eps = 1.e-6;
368
+ qn = q;
369
+ if(q < 0.5) qn = 1. - q;
370
+ u = pnormaldist(qn);
371
+ w1 = 2. / (double)n1 / 9.;
372
+ w2 = 2. / (double)n2 / 9.;
373
+ w3 = 1. - w1;
374
+ w4 = 1. - w2;
375
+ u2 = u * u;
376
+ a = w4 * w4 - u2 * w2;
377
+ b = -2. * w3 * w4;
378
+ c = w3 * w3 - u2 * w1;
379
+ d = b * b - 4 * a * c;
380
+ if(d < 0.) fw = pfsub(a, b, 0.);
381
+ else
382
+ {
383
+ if(fabs(a) > eps) fw = pfsub(a, b, d);
384
+ else
385
+ {
386
+ if(fabs(b) > eps) return -c / b;
387
+ fw = pfsub(a, b, 0.);
388
+ }
389
+ }
390
+ return fw * fw * fw;
391
+ }
392
+
393
+ /* F-distribution interface */
394
+ static double fdist(n1, n2, f)
395
+ int n1, n2;
396
+ double f;
397
+ {
398
+ return 1.0 - q_f(n1, n2, f);
399
+ }
400
+
401
+ static double pfdist(n1, n2, y)
402
+ int n1, n2;
403
+ double y;
404
+ {
405
+ return pf(1.0 - y, n1, n2);
406
+ }
407
+
408
+
409
+ /* discrete distributions */
410
+ static int perm(n, x)
411
+ int n, x;
412
+ {
413
+ int r = 1;
414
+ if (n < 0 || x < 0) rb_raise(rb_eRangeError, "parameters should be positive");
415
+ while (x >= 1) {
416
+ r *= n;
417
+ n -= 1;
418
+ x -= 1;
419
+ }
420
+ return r;
421
+ }
422
+
423
+ static int combi(n, x)
424
+ int n, x;
425
+ {
426
+ if (n < 0 || x < 0) rb_raise(rb_eRangeError, "parameters should be positive");
427
+ if (x*2 > n) x = n - x;
428
+ return perm(n, x) / perm(x, x);
429
+ }
430
+
431
+ static float bindens(n, p, x)
432
+ int n, x;
433
+ float p;
434
+ {
435
+ float q = 1.0 - p;
436
+ return combi(n, x) * pow(p, x) * pow(q, n - x);
437
+ }
438
+
439
+ static float bindist(n, p, x)
440
+ int n, x;
441
+ float p;
442
+ {
443
+ float s = 0.0;
444
+ int k;
445
+ for (k = 0; k <= x; k ++) {
446
+ s += bindens(n, p, k);
447
+ }
448
+ return s;
449
+ }
450
+
451
+ static float poissondens(m, x)
452
+ float m;
453
+ int x;
454
+ {
455
+ if (x < 0) return 0.0 ;
456
+ return pow(m, x) * exp(-m) / perm(x, x);
457
+ }
458
+
459
+ static float poissondist(m, x)
460
+ float m;
461
+ int x;
462
+ {
463
+ float s = 0.0;
464
+ int k;
465
+ for (k = 0; k <= x; k ++) {
466
+ s += poissondens(m, k);
467
+ }
468
+ return s;
469
+ }
470
+
471
+ /* normal-distribution */
472
+ static VALUE rb_normaldist(mod, x)
473
+ VALUE mod, x;
474
+ {
475
+ Need_Float(x);
476
+ return rb_float_new(normaldist(RFLOAT_VALUE(x)));
477
+ }
478
+
479
+ static VALUE rb_normalxXX_(mod, x)
480
+ VALUE mod, x;
481
+ {
482
+ Need_Float(x);
483
+ return rb_float_new(normaldist(RFLOAT_VALUE(x)));
484
+ }
485
+
486
+ static VALUE rb_normal__X_(mod, x)
487
+ VALUE mod, x;
488
+ {
489
+ Need_Float(x);
490
+ return rb_float_new(normaldist(RFLOAT_VALUE(x)) - 0.5);
491
+ }
492
+
493
+ static VALUE rb_normal___x(mod, x)
494
+ VALUE mod, x;
495
+ {
496
+ Need_Float(x);
497
+ return rb_float_new(1.0 - normaldist(RFLOAT_VALUE(x)));
498
+ }
499
+
500
+ static VALUE rb_normalx__x(mod, x)
501
+ VALUE mod, x;
502
+ {
503
+ Need_Float(x);
504
+ return rb_float_new(2.0 - normaldist(RFLOAT_VALUE(x)) * 2.0);
505
+ }
506
+
507
+ /* inverse of normal-distribution */
508
+ static VALUE rb_pnormaldist(mod, x)
509
+ VALUE mod, x;
510
+ {
511
+ Need_Float(x);
512
+ return rb_float_new(pnormaldist(RFLOAT_VALUE(x)));
513
+ }
514
+
515
+ static VALUE rb_pnormalxXX_(mod, x)
516
+ VALUE mod, x;
517
+ {
518
+ Need_Float(x);
519
+ return rb_float_new(pnormaldist(RFLOAT_VALUE(x)));
520
+ }
521
+
522
+ static VALUE rb_pnormal__X_(mod, x)
523
+ VALUE mod, x;
524
+ {
525
+ Need_Float(x);
526
+ return rb_float_new(pnormaldist(RFLOAT_VALUE(x) + 0.5));
527
+ }
528
+
529
+ static VALUE rb_pnormal___x(mod, x)
530
+ VALUE mod, x;
531
+ {
532
+ Need_Float(x);
533
+ return rb_float_new(pnormaldist(1.0 - RFLOAT_VALUE(x)));
534
+ }
535
+
536
+ static VALUE rb_pnormalx__x(mod, x)
537
+ VALUE mod, x;
538
+ {
539
+ Need_Float(x);
540
+ return rb_float_new(pnormaldist(1.0 - (RFLOAT_VALUE(x))/2.0));
541
+ }
542
+
543
+
544
+ /* chi-square-distribution */
545
+ static VALUE rb_chi2_x(mod, n, x)
546
+ VALUE mod, n, x;
547
+ {
548
+ Need_Float(x);
549
+ return rb_float_new(1.0 - chi2dist(FIX2INT(n), RFLOAT_VALUE(x)));
550
+ }
551
+
552
+ static VALUE rb_pchi2_x(mod, n, x)
553
+ VALUE mod, n, x;
554
+ {
555
+ Need_Float(x);
556
+ return rb_float_new(pchi2dist(FIX2INT(n), 1.0 - (RFLOAT_VALUE(x))));
557
+ }
558
+
559
+ static VALUE rb_chi2X_(mod, n, x)
560
+ VALUE mod, n, x;
561
+ {
562
+ Need_Float(x);
563
+ return rb_float_new(chi2dist(FIX2INT(n), RFLOAT_VALUE(x)));
564
+ }
565
+
566
+ static VALUE rb_pchi2X_(mod, n, x)
567
+ VALUE mod, n, x;
568
+ {
569
+ Need_Float(x);
570
+ return rb_float_new(pchi2dist(FIX2INT(n), RFLOAT_VALUE(x)));
571
+ }
572
+
573
+
574
+ /* inverse of chi-square-distribution */
575
+ static VALUE rb_chi2dist(mod, n, x)
576
+ VALUE mod, n, x;
577
+ {
578
+ Need_Float(x);
579
+ return rb_float_new(1.0 - (q_chi2(FIX2INT(n), RFLOAT_VALUE(x))));
580
+ }
581
+
582
+ static VALUE rb_pchi2dist(mod, n, x)
583
+ VALUE mod, n, x;
584
+ {
585
+ Need_Float(x);
586
+ return rb_float_new(pchi2(1.0 - (RFLOAT_VALUE(x)), FIX2INT(n)));
587
+ }
588
+
589
+
590
+ /* t-distribution */
591
+ static VALUE rb_tdist(mod, n, x)
592
+ VALUE mod, n, x;
593
+ {
594
+ Need_Float(x);
595
+ return rb_float_new(tdist(FIX2INT(n), RFLOAT_VALUE(x)));
596
+ }
597
+
598
+ static VALUE rb_tx__x(mod, n, x)
599
+ VALUE mod, n, x;
600
+ {
601
+ Need_Float(x);
602
+ return rb_float_new(2.0 - tdist(FIX2INT(n), RFLOAT_VALUE(x))*2.0);
603
+ }
604
+
605
+ static VALUE rb_txXX_(mod, n, x)
606
+ VALUE mod, n, x;
607
+ {
608
+ Need_Float(x);
609
+ return rb_float_new(tdist(FIX2INT(n), RFLOAT_VALUE(x)));
610
+ }
611
+
612
+ static VALUE rb_t__X_(mod, n, x)
613
+ VALUE mod, n, x;
614
+ {
615
+ Need_Float(x);
616
+ return rb_float_new(tdist(FIX2INT(n), RFLOAT_VALUE(x)) - 0.5);
617
+ }
618
+
619
+ static VALUE rb_t___x(mod, n, x)
620
+ VALUE mod, n, x;
621
+ {
622
+ Need_Float(x);
623
+ return rb_float_new(1.0 - tdist(FIX2INT(n), RFLOAT_VALUE(x)));
624
+ }
625
+
626
+ /* inverse of t-distribution */
627
+ static VALUE rb_ptdist(mod, n, x)
628
+ VALUE mod, n, x;
629
+ {
630
+ Need_Float(x);
631
+ return rb_float_new(ptdist(FIX2INT(n), RFLOAT_VALUE(x)));
632
+ }
633
+
634
+ static VALUE rb_ptx__x(mod, n, x)
635
+ VALUE mod, n, x;
636
+ {
637
+ Need_Float(x);
638
+ return rb_float_new(ptdist(FIX2INT(n), 1.0 - (RFLOAT_VALUE(x))/2.0));
639
+ }
640
+
641
+ static VALUE rb_ptxXX_(mod, n, x)
642
+ VALUE mod, n, x;
643
+ {
644
+ Need_Float(x);
645
+ return rb_float_new(ptdist(FIX2INT(n), RFLOAT_VALUE(x)));
646
+ }
647
+
648
+ static VALUE rb_pt__X_(mod, n, x)
649
+ VALUE mod, n, x;
650
+ {
651
+ Need_Float(x);
652
+ return rb_float_new(ptdist(FIX2INT(n), 0.5 + (RFLOAT_VALUE(x))));
653
+ }
654
+
655
+ static VALUE rb_pt___x(mod, n, x)
656
+ VALUE mod, n, x;
657
+ {
658
+ Need_Float(x);
659
+ return rb_float_new(ptdist(FIX2INT(n), 1.0 - (RFLOAT_VALUE(x))));
660
+ }
661
+
662
+ /* F-distribution */
663
+ static VALUE rb_fdist(mod, n1, n2, x)
664
+ VALUE mod, n1, n2, x;
665
+ {
666
+ Need_Float(x);
667
+ return rb_float_new(fdist(FIX2INT(n1), FIX2INT(n2), RFLOAT_VALUE(x)));
668
+ }
669
+
670
+
671
+ static VALUE rb_f_x(mod, n1, n2, x)
672
+ VALUE mod, n1, n2, x;
673
+ {
674
+ Need_Float(x);
675
+ return rb_float_new(1.0 - fdist(FIX2INT(n1), FIX2INT(n2), RFLOAT_VALUE(x)));
676
+ }
677
+
678
+ static VALUE rb_fX_(mod, n1, n2, x)
679
+ VALUE mod, n1, n2, x;
680
+ {
681
+ Need_Float(x);
682
+ return rb_float_new(fdist(FIX2INT(n1), FIX2INT(n2), RFLOAT_VALUE(x)));
683
+ }
684
+
685
+ /* inverse of F-distribution */
686
+ static VALUE rb_pfdist(mod, n1, n2, x)
687
+ VALUE mod, n1, n2, x;
688
+ {
689
+ Need_Float(x);
690
+ return rb_float_new(pfdist(FIX2INT(n1), FIX2INT(n2), RFLOAT_VALUE(x)));
691
+ }
692
+
693
+ static VALUE rb_pf_x(mod, n1, n2, x)
694
+ VALUE mod, n1, n2, x;
695
+ {
696
+ Need_Float(x);
697
+ return rb_float_new(pfdist(FIX2INT(n1), FIX2INT(n2), 1.0 - (RFLOAT_VALUE(x))));
698
+ }
699
+
700
+ static VALUE rb_pfX_(mod, n1, n2, x)
701
+ VALUE mod, n1, n2, x;
702
+ {
703
+ Need_Float(x);
704
+ return rb_float_new(pfdist(FIX2INT(n1), FIX2INT(n2), RFLOAT_VALUE(x)));
705
+ }
706
+
707
+ /* discrete distributions */
708
+
709
+ static VALUE rb_bindens(mod, n, p, x)
710
+ VALUE n, p, x;
711
+ {
712
+ Need_Float(p);
713
+ return rb_float_new(bindens(FIX2INT(n), RFLOAT_VALUE(p), FIX2INT(x)));
714
+ }
715
+
716
+ static VALUE rb_bindist(mod, n, p, x)
717
+ VALUE n, p, x;
718
+ {
719
+ Need_Float(p);
720
+ return rb_float_new(bindist(FIX2INT(n), RFLOAT_VALUE(p), FIX2INT(x)));
721
+ }
722
+
723
+ static VALUE rb_binX_(mod, n, p, x)
724
+ VALUE n, p, x;
725
+ {
726
+ Need_Float(p);
727
+ return rb_float_new(bindist(FIX2INT(n), RFLOAT_VALUE(p), FIX2INT(x)));
728
+ }
729
+
730
+ static VALUE rb_bin_x(mod, n, p, x)
731
+ VALUE n, p, x;
732
+ {
733
+ Need_Float(p);
734
+ return rb_float_new(bindist(FIX2INT(n), 1.0 - (RFLOAT_VALUE(p)), FIX2INT(n) - FIX2INT(x)));
735
+ }
736
+
737
+ static VALUE rb_poissondens(mod, m, x)
738
+ VALUE m, x;
739
+ {
740
+ Need_Float(m);
741
+ return rb_float_new(poissondens(RFLOAT_VALUE(m), FIX2INT(x)));
742
+ }
743
+
744
+ static VALUE rb_poissondist(mod, m, x)
745
+ VALUE m, x;
746
+ {
747
+ Need_Float(m);
748
+ return rb_float_new(poissondist(RFLOAT_VALUE(m), FIX2INT(x)));
749
+ }
750
+
751
+ static VALUE rb_poissonX_(mod, m, x)
752
+ VALUE m, x;
753
+ {
754
+ Need_Float(m);
755
+ return rb_float_new(poissondist(RFLOAT_VALUE(m), FIX2INT(x)));
756
+ }
757
+
758
+ /*
759
+ static VALUE rb_poisson_x(mod, m, x)
760
+ VALUE m, x;
761
+ {
762
+ Need_Float(m);
763
+ return rb_float_new(1.0 - poissondist((RFLOAT_VALUE(m)), FIX2INT(x) - 1));
764
+ }
765
+ */
766
+
767
+ /* ruby interface */
768
+
769
+ void
770
+ Init_statistics2(void)
771
+ {
772
+ int i;
773
+ char *checkMethods[] = { "normaldist", "normalxXX_", "normal__X_", "normal___x", "normalx__x",
774
+ "pnormaldist", "pnormalxXX_", "pnormal__X_", "pnormal___x", "pnormalx__x",
775
+ "chi2dist", "chi2X_", "chi2_x", "pchi2dist", "pchi2X_", "pchi2_x",
776
+ "tdist", "txXX_", "t__X_", "t___x", "tx__x", "ptdist", "ptxXX_", "pt__X_", "pt___x", "ptx__x",
777
+ "fdist", "fX_", "f_x", "pfdist", "pfX_", "pf_x",
778
+ "bindens", "bindist", "binX_", "bin_x",
779
+ "poissondens", "poissondist", "poissonX_", "poisson_x" };
780
+ VALUE methodDefined = rb_intern("private_method_defined?"),
781
+ removeMethod = rb_intern("remove_method");
782
+
783
+
784
+ rb_mStatistics2 = rb_define_module("Statistics2");
785
+ /* Remove any preexisting methods before adding the new ones */
786
+ for (i = 0; i < (sizeof(checkMethods) / sizeof(checkMethods[0])); i++) {
787
+ if (RTEST(rb_funcall(rb_mStatistics2, methodDefined, 1, rb_str_new2(checkMethods[i])))) {
788
+ /* Remove instance method */
789
+ rb_funcall(rb_mStatistics2, removeMethod, 1, rb_str_new2(checkMethods[i]));
790
+ /* Remove the singleton method */
791
+ rb_funcall(rb_singleton_class(rb_mStatistics2), removeMethod, 1, rb_str_new2(checkMethods[i]));
792
+ }
793
+ }
794
+
795
+ rb_define_module_function(rb_mStatistics2, "normaldist", rb_normaldist, 1);
796
+ rb_define_module_function(rb_mStatistics2, "normalxXX_", rb_normalxXX_ , 1);
797
+ rb_define_module_function(rb_mStatistics2, "normal__X_", rb_normal__X_, 1);
798
+ rb_define_module_function(rb_mStatistics2, "normal___x", rb_normal___x, 1);
799
+ rb_define_module_function(rb_mStatistics2, "normalx__x", rb_normalx__x, 1);
800
+
801
+ rb_define_module_function(rb_mStatistics2, "pnormaldist", rb_pnormaldist, 1);
802
+ rb_define_module_function(rb_mStatistics2, "pnormalxXX_", rb_pnormalxXX_, 1);
803
+ rb_define_module_function(rb_mStatistics2, "pnormal__X_", rb_pnormal__X_, 1);
804
+ rb_define_module_function(rb_mStatistics2, "pnormal___x", rb_pnormal___x, 1);
805
+ rb_define_module_function(rb_mStatistics2, "pnormalx__x", rb_pnormalx__x, 1);
806
+
807
+
808
+ rb_define_module_function(rb_mStatistics2, "chi2dist", rb_chi2dist, 2);
809
+ rb_define_module_function(rb_mStatistics2, "chi2X_", rb_chi2X_ , 2);
810
+ rb_define_module_function(rb_mStatistics2, "chi2_x", rb_chi2_x, 2);
811
+
812
+ rb_define_module_function(rb_mStatistics2, "pchi2dist", rb_pchi2dist, 2);
813
+ rb_define_module_function(rb_mStatistics2, "pchi2X_", rb_pchi2X_, 2);
814
+ rb_define_module_function(rb_mStatistics2, "pchi2_x", rb_pchi2_x, 2);
815
+
816
+
817
+ rb_define_module_function(rb_mStatistics2, "tdist", rb_tdist, 2);
818
+ rb_define_module_function(rb_mStatistics2, "txXX_", rb_txXX_ , 2);
819
+ rb_define_module_function(rb_mStatistics2, "t__X_", rb_t__X_, 2);
820
+ rb_define_module_function(rb_mStatistics2, "t___x", rb_t___x, 2);
821
+ rb_define_module_function(rb_mStatistics2, "tx__x", rb_tx__x, 2);
822
+
823
+ rb_define_module_function(rb_mStatistics2, "ptdist", rb_ptdist, 2);
824
+ rb_define_module_function(rb_mStatistics2, "ptxXX_", rb_ptxXX_, 2);
825
+ rb_define_module_function(rb_mStatistics2, "pt__X_", rb_pt__X_, 2);
826
+ rb_define_module_function(rb_mStatistics2, "pt___x", rb_pt___x, 2);
827
+ rb_define_module_function(rb_mStatistics2, "ptx__x", rb_ptx__x, 2);
828
+
829
+
830
+ rb_define_module_function(rb_mStatistics2, "fdist", rb_fdist, 3);
831
+ rb_define_module_function(rb_mStatistics2, "fX_", rb_fX_ , 3);
832
+ rb_define_module_function(rb_mStatistics2, "f_x", rb_f_x, 3);
833
+
834
+ rb_define_module_function(rb_mStatistics2, "pfdist", rb_pfdist, 3);
835
+ rb_define_module_function(rb_mStatistics2, "pfX_", rb_pfX_, 3);
836
+ rb_define_module_function(rb_mStatistics2, "pf_x", rb_pf_x, 3);
837
+
838
+
839
+ rb_define_module_function(rb_mStatistics2, "bindens", rb_bindens, 3);
840
+ rb_define_module_function(rb_mStatistics2, "bindist", rb_bindist, 3);
841
+ rb_define_module_function(rb_mStatistics2, "binX_", rb_binX_, 3);
842
+ rb_define_module_function(rb_mStatistics2, "bin_x", rb_bin_x, 3);
843
+
844
+ rb_define_module_function(rb_mStatistics2, "poissondens", rb_poissondens, 2);
845
+ rb_define_module_function(rb_mStatistics2, "poissondist", rb_poissondist, 2);
846
+ rb_define_module_function(rb_mStatistics2, "poissonX_", rb_poissonX_, 2);
847
+ rb_define_module_function(rb_mStatistics2, "poisson_x", rb_bin_x, 2);
848
+ }