statistics3 0.0.1

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