statistics2 0.54

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }