apriori 0.2.1

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 (122) hide show
  1. data/History.txt +16 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +121 -0
  4. data/README.txt +149 -0
  5. data/Rakefile +15 -0
  6. data/TODO.txt +60 -0
  7. data/attic/c_ext_test1/MyTest/MyTest.c +23 -0
  8. data/attic/c_ext_test1/MyTest/extconf.rb +11 -0
  9. data/attic/c_ext_test1/mytest.rb +10 -0
  10. data/attic/test.c +12 -0
  11. data/config/hoe.rb +81 -0
  12. data/config/requirements.rb +29 -0
  13. data/examples/01_simple_example.rb +32 -0
  14. data/examples/02_small_file_example.rb +17 -0
  15. data/examples/03_large_file_example.rb +22 -0
  16. data/examples/test_data/market_basket_basic_test.dat +9 -0
  17. data/ext/Apriori.c +149 -0
  18. data/ext/Makefile +149 -0
  19. data/ext/apriori/doc/apriori.html +1301 -0
  20. data/ext/apriori/doc/arem.gp +68 -0
  21. data/ext/apriori/doc/c_rev.gp +89 -0
  22. data/ext/apriori/doc/chi2.tex +156 -0
  23. data/ext/apriori/doc/copying +504 -0
  24. data/ext/apriori/doc/line.gif +0 -0
  25. data/ext/apriori/doc/uparrow.gif +0 -0
  26. data/ext/apriori/ex/flg2set +15 -0
  27. data/ext/apriori/ex/hdr2set +13 -0
  28. data/ext/apriori/ex/readme +71 -0
  29. data/ext/apriori/ex/row2set +7 -0
  30. data/ext/apriori/ex/rulesort +24 -0
  31. data/ext/apriori/ex/tab2set +9 -0
  32. data/ext/apriori/ex/test.app +2 -0
  33. data/ext/apriori/ex/test.rul +9 -0
  34. data/ext/apriori/ex/test1.rul +43 -0
  35. data/ext/apriori/ex/test1.tab +10 -0
  36. data/ext/apriori/ex/test2.tab +10 -0
  37. data/ext/apriori/ex/test3.tab +30 -0
  38. data/ext/apriori/ex/test4.tab +11 -0
  39. data/ext/apriori/ex/test5.tab +39 -0
  40. data/ext/apriori/ex/tid2set +23 -0
  41. data/ext/apriori/ex/xhdr2set +33 -0
  42. data/ext/apriori/src/apriori.c +750 -0
  43. data/ext/apriori/src/apriori.dsp +120 -0
  44. data/ext/apriori/src/apriori.dsw +29 -0
  45. data/ext/apriori/src/apriori.mak +99 -0
  46. data/ext/apriori/src/istree.c +1411 -0
  47. data/ext/apriori/src/istree.h +160 -0
  48. data/ext/apriori/src/makefile +105 -0
  49. data/ext/apriori/src/tract.c +870 -0
  50. data/ext/apriori/src/tract.h +261 -0
  51. data/ext/apriori_wrapper.c +757 -0
  52. data/ext/apriori_wrapper.h +10 -0
  53. data/ext/extconf.rb +32 -0
  54. data/ext/math/doc/copying +504 -0
  55. data/ext/math/src/chi2.c +151 -0
  56. data/ext/math/src/chi2.h +27 -0
  57. data/ext/math/src/choose.c +71 -0
  58. data/ext/math/src/choose.h +16 -0
  59. data/ext/math/src/gamma.c +446 -0
  60. data/ext/math/src/gamma.h +39 -0
  61. data/ext/math/src/intexp.c +35 -0
  62. data/ext/math/src/intexp.h +15 -0
  63. data/ext/math/src/makefile +164 -0
  64. data/ext/math/src/math.mak +48 -0
  65. data/ext/math/src/normal.c +387 -0
  66. data/ext/math/src/normal.h +44 -0
  67. data/ext/math/src/radfn.c +113 -0
  68. data/ext/math/src/radfn.h +34 -0
  69. data/ext/math/src/zeta.c +49 -0
  70. data/ext/math/src/zeta.h +15 -0
  71. data/ext/pre-clean.rb +8 -0
  72. data/ext/pre-setup.rb +9 -0
  73. data/ext/util/doc/copying +504 -0
  74. data/ext/util/src/listops.c +76 -0
  75. data/ext/util/src/listops.h +26 -0
  76. data/ext/util/src/makefile +103 -0
  77. data/ext/util/src/memsys.c +84 -0
  78. data/ext/util/src/memsys.h +42 -0
  79. data/ext/util/src/nstats.c +288 -0
  80. data/ext/util/src/nstats.h +69 -0
  81. data/ext/util/src/params.c +86 -0
  82. data/ext/util/src/params.h +19 -0
  83. data/ext/util/src/parse.c +133 -0
  84. data/ext/util/src/parse.h +81 -0
  85. data/ext/util/src/scan.c +767 -0
  86. data/ext/util/src/scan.h +111 -0
  87. data/ext/util/src/symtab.c +443 -0
  88. data/ext/util/src/symtab.h +121 -0
  89. data/ext/util/src/tabscan.c +279 -0
  90. data/ext/util/src/tabscan.h +99 -0
  91. data/ext/util/src/util.mak +91 -0
  92. data/ext/util/src/vecops.c +317 -0
  93. data/ext/util/src/vecops.h +42 -0
  94. data/lib/apriori.rb +133 -0
  95. data/lib/apriori/adapter.rb +13 -0
  96. data/lib/apriori/association_rule.rb +89 -0
  97. data/lib/apriori/version.rb +9 -0
  98. data/script/console +10 -0
  99. data/script/destroy +14 -0
  100. data/script/generate +14 -0
  101. data/script/txt2html +82 -0
  102. data/setup.rb +1585 -0
  103. data/tasks/apriori.rake +20 -0
  104. data/tasks/attic.rake +28 -0
  105. data/tasks/deployment.rake +34 -0
  106. data/tasks/environment.rake +7 -0
  107. data/tasks/install.rake +13 -0
  108. data/tasks/website.rake +17 -0
  109. data/test/apriori_test.rb +13 -0
  110. data/test/fixtures/market_basket_results_test.txt +5 -0
  111. data/test/fixtures/market_basket_string_test.txt +7 -0
  112. data/test/fixtures/results.txt +2 -0
  113. data/test/fixtures/sample.txt +7 -0
  114. data/test/test_helper.rb +5 -0
  115. data/test/unit/test_apriori.rb +68 -0
  116. data/test/unit/test_itemsets_and_parsing.rb +82 -0
  117. data/website/index.html +248 -0
  118. data/website/index.txt +152 -0
  119. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  120. data/website/stylesheets/screen.css +142 -0
  121. data/website/template.html.erb +49 -0
  122. metadata +226 -0
@@ -0,0 +1,151 @@
1
+ /*----------------------------------------------------------------------
2
+ File : chi2.c
3
+ Contents: chi^2 distribution function
4
+ Author : Christian Borgelt
5
+ History : 2003.05.19 file created as quantile.c
6
+ 2008.03.14 main programs added
7
+ ----------------------------------------------------------------------*/
8
+ #if defined(CHI2PDF_MAIN) \
9
+ || defined(CHI2CDF_MAIN) \
10
+ || defined(CHI2QTL_MAIN)
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #endif
14
+ #ifdef CHI2QTL_MAIN
15
+ #ifndef CHI2QTL
16
+ #define CHI2QTL
17
+ #endif
18
+ #ifndef GAMMAQTL
19
+ #define GAMMAQTL
20
+ #endif
21
+ #endif
22
+ #include <assert.h>
23
+ #include <math.h>
24
+ #include "gamma.h"
25
+ #ifdef CHI2QTL
26
+ #include "normal.h"
27
+ #endif
28
+ #include "chi2.h"
29
+
30
+ /*----------------------------------------------------------------------
31
+ Functions
32
+ ----------------------------------------------------------------------*/
33
+
34
+ double chi2pdf (double x, double df)
35
+ { /* --- probability density function */
36
+ assert(df > 0); /* check the function arguments */
37
+ if (x <= 0) return 0; /* only non-zero for positive arg. */
38
+ if (df == 2) return 0.5 *exp(-0.5*x);
39
+ df *= 0.5; /* compute probability density */
40
+ return 0.5 *exp((df-1) *log(0.5*x) -0.5*x -logGamma(df));
41
+ } /* chi2pdf() */
42
+
43
+ /*--------------------------------------------------------------------*/
44
+
45
+ double chi2cdfP (double x, double df)
46
+ { /* --- cumulative distribution fn. */
47
+ assert(df > 0); /* check the function arguments */
48
+ return GammaP(0.5*df, 0.5*x); /* compute regularized Gamma function */
49
+ } /* chi2cdfP() */
50
+
51
+ /*--------------------------------------------------------------------*/
52
+
53
+ double chi2cdfQ (double x, double df)
54
+ { /* --- cumulative distribution fn. */
55
+ assert(df > 0); /* check the function arguments */
56
+ return GammaQ(0.5*df, 0.5*x); /* compute regularized Gamma function */
57
+ } /* chi2cdfQ() */
58
+
59
+ /*--------------------------------------------------------------------*/
60
+ #ifdef CHI2QTL
61
+
62
+ double chi2qtlP (double prob, double df)
63
+ { /* --- quantile of chi2 distribution */
64
+ return GammaqtlP(prob, 0.5*df, 2);
65
+ } /* chi2qtlP() */
66
+
67
+ /*--------------------------------------------------------------------*/
68
+
69
+ double chi2qtlQ (double prob, double df)
70
+ { /* --- quantile of chi2 distribution */
71
+ return GammaqtlQ(prob, 0.5*df, 2);
72
+ } /* chi2qtlQ() */
73
+
74
+ #endif
75
+ /*----------------------------------------------------------------------
76
+ Main Functions
77
+ ----------------------------------------------------------------------*/
78
+ #ifdef CHI2PDF_MAIN
79
+
80
+ int main (int argc, char *argv[])
81
+ { /* --- main function */
82
+ double df = 1; /* degrees of freedom */
83
+ double x; /* argument value */
84
+
85
+ if ((argc < 2) || (argc > 3)){/* if wrong number of arguments */
86
+ printf("usage: %s arg [df]\n", argv[0]);
87
+ printf("compute probability density function of the\n"
88
+ "chi^2 distribution with df degrees of freedom\n");
89
+ return 0; /* print a usage message */
90
+ } /* and abort the program */
91
+ x = atof(argv[1]); /* get the argument value */
92
+ if (argc > 2) df = atof(argv[2]);
93
+ if (df <= 0) { /* get the degrees of freedom */
94
+ printf("%s: invalid degrees of freedom\n", argv[0]); return -1; }
95
+ printf("chi^2: f(%.16g; %.16g) = %.16g\n", x, df, chi2pdf(x, df));
96
+ return 0; /* compute and print density */
97
+ } /* main() */
98
+
99
+ #endif
100
+ /*--------------------------------------------------------------------*/
101
+ #ifdef CHI2CDF_MAIN
102
+
103
+ int main (int argc, char *argv[])
104
+ { /* --- main function */
105
+ double df = 1; /* degrees of freedom */
106
+ double x; /* argument value */
107
+
108
+ if ((argc < 2) || (argc > 3)){/* if wrong number of arguments */
109
+ printf("usage: %s arg [df]\n", argv[0]);
110
+ printf("compute cumulative distribution function of the\n"
111
+ "chi^2 distribution with df degrees of freedom\n");
112
+ return 0; /* print a usage message */
113
+ } /* and abort the program */
114
+ x = atof(argv[1]); /* get the argument value */
115
+ if (argc > 2) df = atof(argv[2]);
116
+ if (df <= 0) { /* get the degrees of freedom */
117
+ printf("%s: invalid degrees of freedom\n", argv[0]); return -1; }
118
+ printf("chi^2: F(%.16g; %.16g) = %.16g\n", x, df, chi2cdfP(x, df));
119
+ printf(" 1 - F(%.16g; %.16g) = %.16g\n", x, df, chi2cdfQ(x, df));
120
+ return 0; /* compute and print probability */
121
+ } /* main() */
122
+
123
+ #endif
124
+ /*--------------------------------------------------------------------*/
125
+ #ifdef CHI2QTL_MAIN
126
+
127
+ int main (int argc, char *argv[])
128
+ { /* --- main function */
129
+ double df = 1; /* degrees of freedom */
130
+ double prob; /* probability */
131
+
132
+ if ((argc < 2) || (argc > 3)){/* if wrong number of arguments */
133
+ printf("usage: %s prob [df]\n", argv[0]);
134
+ printf("compute quantile of the chi^2 distribution "
135
+ "with df degrees of freedom\n");
136
+ return 0; /* print a usage message */
137
+ } /* and abort the program */
138
+ prob = atof(argv[1]); /* get the probability */
139
+ if ((prob < 0) || (prob > 1)) {
140
+ printf("%s: invalid probability\n", argv[0]); return -1; }
141
+ if (argc > 2) df = atof(argv[2]);
142
+ if (df <= 0) { /* get the degrees of freedom */
143
+ printf("%s: invalid degrees of freedom\n", argv[0]); return -1; }
144
+ printf("chi^2: F(%.16g; %.16g) = %.16g\n",
145
+ chi2qtlP(prob, df), df, prob);
146
+ printf(" 1 - F(%.16g; %.16g) = %.16g\n",
147
+ chi2qtlQ(prob, df), df, prob);
148
+ return 0; /* compute and print quantile */
149
+ } /* main() */
150
+
151
+ #endif
@@ -0,0 +1,27 @@
1
+ /*----------------------------------------------------------------------
2
+ File : chi2.h
3
+ Contents: chi^2 distribution functions
4
+ Author : Christian Borgelt
5
+ History : 2003.05.19 file created as quantile.h
6
+ ----------------------------------------------------------------------*/
7
+ #ifndef __CHI2__
8
+ #define __CHI2__
9
+
10
+ /*----------------------------------------------------------------------
11
+ Functions
12
+ ----------------------------------------------------------------------*/
13
+ extern double chi2pdf (double x, double df);
14
+ extern double chi2cdf (double x, double df);
15
+ extern double chi2cdfP (double x, double df);
16
+ extern double chi2cdfQ (double x, double df);
17
+ extern double chi2qtl (double prob, double df);
18
+ extern double chi2qtlP (double prob, double df);
19
+ extern double chi2qtlQ (double prob, double df);
20
+
21
+ /*----------------------------------------------------------------------
22
+ Preprocessor Definitions
23
+ ----------------------------------------------------------------------*/
24
+ #define chi2cdf(x,d) chi2cdfP(x,d)
25
+ #define chi2qtl(p,d) chi2qtlP(p,d)
26
+
27
+ #endif
@@ -0,0 +1,71 @@
1
+ /*----------------------------------------------------------------------
2
+ File : choose.c
3
+ Contents: compute n choose k
4
+ Author : Christian Borgelt
5
+ History : 1996.04.29 file created
6
+ 2003.05.17 (n-i+1) replaced by n--
7
+ 2008.03.14 main function added
8
+ ----------------------------------------------------------------------*/
9
+ #ifdef CHOOSE_MAIN
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #endif
13
+ #include <limits.h>
14
+ #include "choose.h"
15
+
16
+ /*----------------------------------------------------------------------
17
+ Functions
18
+ ----------------------------------------------------------------------*/
19
+
20
+ unsigned int choose (unsigned int n, unsigned int k)
21
+ { /* --- compute n choose k */
22
+ unsigned int i, t; /* loop variable, buffer */
23
+ unsigned int r = 1; /* result */
24
+
25
+ if (k > n) return 0; /* check range of k */
26
+ for (i = 1; i <= k; i++) { /* calculation loop */
27
+ t = n--; /* calculate next factor in numerator */
28
+ if (UINT_MAX /t < r) /* if result of multiplication */
29
+ return 0; /* is out of range, abort */
30
+ r = (r *t) /i; /* calculate \prod_{i=1}^k (n-i+1)/i */
31
+ }
32
+ return r; /* return result */
33
+ } /* choose() */
34
+
35
+ /*--------------------------------------------------------------------*/
36
+
37
+ double dchoose (unsigned int n, unsigned int k)
38
+ { /* --- compute n choose k */
39
+ unsigned int i; /* loop variable, buffer */
40
+ double r = 1.0; /* result */
41
+
42
+ if (k > n) return 0; /* check range of k */
43
+ for (i = 1; i <= k; i++) /* calculation loop */
44
+ r = (r *n--) /i; /* calculate \prod_{i=1}^k (n-i+1)/i */
45
+ return r; /* return result */
46
+ } /* dchoose() */
47
+
48
+ /*--------------------------------------------------------------------*/
49
+ #ifdef CHOOSE_MAIN
50
+
51
+ int main (int argc, char *argv[])
52
+ { /* --- main function */
53
+ int n, k; /* arguments */
54
+ unsigned int r; /* result */
55
+
56
+ if (argc != 3) { /* if number of arguments is wrong */
57
+ printf("usage: %s <n> <k>\n", argv[0]);
58
+ printf("calculate n choose k, i.e. n!/(k!(n-k)!)\n");
59
+ return 0; /* print a usage message */
60
+ } /* and abort the program */
61
+ n = atoi(argv[1]); /* get argument 1, i.e. n */
62
+ k = atoi(argv[2]); /* get argument 2, i.e. k */
63
+ if ((n < 0) || (k < 0)) { /* check range of n and k */
64
+ printf("%s: value out of range\n", argv[0]); return 1; }
65
+ r = choose(n, k); /* calculate n choose k */
66
+ if (r > 0) printf("%d choose %d: %d\n", n, k, r);
67
+ else printf("%d choose %d: %.0f\n", n, k, dchoose(n, k));
68
+ return 0; /* print result and terminate program */
69
+ } /* main() */
70
+
71
+ #endif
@@ -0,0 +1,16 @@
1
+ /*----------------------------------------------------------------------
2
+ File : choose.h
3
+ Contents: compute n choose k
4
+ Author : Christian Borgelt
5
+ History : 29.04.1996 file created
6
+ ----------------------------------------------------------------------*/
7
+ #ifndef __CHOOSE__
8
+ #define __CHOOSE__
9
+
10
+ /*----------------------------------------------------------------------
11
+ Functions
12
+ ----------------------------------------------------------------------*/
13
+ extern unsigned int choose (unsigned int n, unsigned int k);
14
+ extern double dchoose (unsigned int n, unsigned int k);
15
+
16
+ #endif
@@ -0,0 +1,446 @@
1
+ /*----------------------------------------------------------------------
2
+ File : gamma.c
3
+ Contents: computation of the (incomplete/regularized) gamma function
4
+ Author : Christian Borgelt
5
+ History : 2002.07.04 file created
6
+ 2003.05.19 incomplete Gamma function added
7
+ 2008.03.14 more incomplete Gamma functions added
8
+ 2008.03.15 table of factorials and logarithms added
9
+ 2008.03.17 gamma distribution functions added
10
+ ----------------------------------------------------------------------*/
11
+ #ifndef _ISOC99_SOURCE
12
+ #define _ISOC99_SOURCE
13
+ #endif /* needed for function log1p() */
14
+ #if defined(GAMMA_MAIN) \
15
+ || defined(GAMMAPDF_MAIN) \
16
+ || defined(GAMMACDF_MAIN) \
17
+ || defined(GAMMAQTL_MAIN)
18
+ #include <stdio.h>
19
+ #include <stdlib.h>
20
+ #endif
21
+ #if defined(GAMMAQTL_MAIN) && !defined(GAMMAQTL)
22
+ #define GAMMAQTL
23
+ #endif
24
+ #include <assert.h>
25
+ #include <float.h>
26
+ #include <math.h>
27
+ #ifdef GAMMAQTL
28
+ #include "normal.h"
29
+ #endif
30
+ #include "gamma.h"
31
+
32
+ /*----------------------------------------------------------------------
33
+ Preprocessor Definitions
34
+ ----------------------------------------------------------------------*/
35
+ #define LN_BASE 2.71828182845904523536028747135 /* e */
36
+ #define SQRT_PI 1.77245385090551602729816748334 /* \sqrt(\pi) */
37
+ #define LN_PI 1.14472988584940017414342735135 /* \ln(\pi) */
38
+ #define LN_SQRT_2PI 0.918938533204672741780329736406
39
+ /* \ln(\sqrt(2\pi)) */
40
+ #define EPSILON 2.2204460492503131e-16
41
+ #define EPS_QTL 1.4901161193847656e-08
42
+ #define MAXFACT 170
43
+ #define MAXITER 1024
44
+ #define TINY (EPSILON *EPSILON *EPSILON)
45
+
46
+ /*----------------------------------------------------------------------
47
+ Table of Factorials/Gamma Values
48
+ ----------------------------------------------------------------------*/
49
+ static double _facts[MAXFACT+1] = { 0 };
50
+ static double _logfs[MAXFACT+1];
51
+ static double _halfs[MAXFACT+1];
52
+ static double _loghs[MAXFACT+1];
53
+
54
+ /*----------------------------------------------------------------------
55
+ Functions
56
+ ----------------------------------------------------------------------*/
57
+
58
+ static void _init (void)
59
+ { /* --- init. factorial tables */
60
+ int i; /* loop variable */
61
+ double x = 1; /* factorial */
62
+
63
+ _facts[0] = _facts[1] = 1; /* store factorials for 0 and 1 */
64
+ _logfs[0] = _logfs[1] = 0; /* and their logarithms */
65
+ for (i = 1; ++i <= MAXFACT; ) {
66
+ _facts[i] = x *= i; /* initialize the factorial table */
67
+ _logfs[i] = log(x); /* and the table of their logarithms */
68
+ }
69
+ _halfs[0] = x = SQRT_PI; /* store Gamma(0.5) */
70
+ _loghs[0] = 0.5*LN_PI; /* and its logarithm */
71
+ for (i = 0; ++i < MAXFACT; ) {
72
+ _halfs[i] = x *= i-0.5; /* initialize the table for */
73
+ _loghs[i] = log(x); /* the Gamma function of half numbers */
74
+ } /* and the table of their logarithms */
75
+ } /* _init() */
76
+
77
+ /*--------------------------------------------------------------------*/
78
+ #if 0
79
+
80
+ double logGamma (double n)
81
+ { /* --- compute ln(Gamma(n)) */
82
+ double s; /* = ln((n-1)!), n \in IN */
83
+
84
+ assert(n > 0); /* check the function argument */
85
+ if (_facts[0] <= 0) _init(); /* initialize the tables */
86
+ if (n < MAXFACT +1 +4 *EPSILON) {
87
+ if (fabs( n -floor( n)) < 4 *EPSILON)
88
+ return _logfs[(int)floor(n)-1];
89
+ if (fabs(2*n -floor(2*n)) < 4 *EPSILON)
90
+ return _loghs[(int)floor(n)];
91
+ } /* try to get the value from a table */
92
+ s = 1.000000000190015 /* otherwise compute it */
93
+ + 76.18009172947146 /(n+1)
94
+ - 86.50532032941677 /(n+2)
95
+ + 24.01409824083091 /(n+3)
96
+ - 1.231739572450155 /(n+4)
97
+ + 0.1208650972866179e-2 /(n+5)
98
+ - 0.5395239384953e-5 /(n+6);
99
+ return (n+0.5) *log((n+5.5)/LN_BASE) +(LN_SQRT_2PI +log(s/n) -5.0);
100
+ } /* logGamma() */
101
+
102
+ #else /*--------------------------------------------------------------*/
103
+
104
+ double logGamma (double n)
105
+ { /* --- compute ln(Gamma(n)) */
106
+ double s; /* = ln((n-1)!), n \in IN */
107
+
108
+ assert(n > 0); /* check the function argument */
109
+ if (_facts[0] <= 0) _init(); /* initialize the tables */
110
+ if (n < MAXFACT +1 +4 *EPSILON) {
111
+ if (fabs( n -floor( n)) < 4 *EPSILON)
112
+ return _logfs[(int)floor(n)-1];
113
+ if (fabs(2*n -floor(2*n)) < 4 *EPSILON)
114
+ return _loghs[(int)floor(n)];
115
+ } /* try to get the value from a table */
116
+ s = 0.99999999999980993227684700473478 /* otherwise compute it */
117
+ + 676.520368121885098567009190444019 /(n+1)
118
+ - 1259.13921672240287047156078755283 /(n+2)
119
+ + 771.3234287776530788486528258894 /(n+3)
120
+ - 176.61502916214059906584551354 /(n+4)
121
+ + 12.507343278686904814458936853 /(n+5)
122
+ - 0.13857109526572011689554707 /(n+6)
123
+ + 9.984369578019570859563e-6 /(n+7)
124
+ + 1.50563273514931155834e-7 /(n+8);
125
+ return (n+0.5) *log((n+7.5)/LN_BASE) +(LN_SQRT_2PI +log(s/n) -7.0);
126
+ } /* logGamma() */
127
+
128
+ #endif
129
+ /*----------------------------------------------------------------------
130
+ Use Lanczos' approximation
131
+ \Gamma(n+1) = (n+\gamma+0.5)^(n+0.5)
132
+ * e^{-(n+\gamma+0.5)}
133
+ * \sqrt{2\pi}
134
+ * (c_0 +c_1/(n+1) +c_2/(n+2) +...+c_n/(n+k) +\epsilon)
135
+ and exploit the recursion \Gamma(n+1) = n *\Gamma(n) once,
136
+ i.e., compute \Gamma(n) as \Gamma(n+1) /n.
137
+
138
+ For the choices \gamma = 5, k = 6, and c_0 to c_6 as defined
139
+ in the first version, it is |\epsilon| < 2e-10 for all n > 0.
140
+
141
+ Source: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery
142
+ Numerical Recipes in C - The Art of Scientific Computing
143
+ Cambridge University Press, Cambridge, United Kingdom 1992
144
+ pp. 213-214
145
+
146
+ For the choices gamma = 7, k = 8, and c_0 to c_8 as defined
147
+ in the second version, the value is slightly more accurate.
148
+ ----------------------------------------------------------------------*/
149
+
150
+ double Gamma (double n)
151
+ { /* --- compute Gamma(n) = (n-1)! */
152
+ assert(n > 0); /* check the function argument */
153
+ if (_facts[0] <= 0) _init(); /* initialize the tables */
154
+ if (n < MAXFACT +1 +4 *EPSILON) {
155
+ if (fabs( n -floor( n)) < 4 *EPSILON)
156
+ return _facts[(int)floor(n)-1];
157
+ if (fabs(2*n -floor(2*n)) < 4 *EPSILON)
158
+ return _halfs[(int)floor(n)];
159
+ } /* try to get the value from a table */
160
+ return exp(logGamma(n)); /* compute through natural logarithm */
161
+ } /* Gamma() */
162
+
163
+ /*--------------------------------------------------------------------*/
164
+
165
+ static double _series (double n, double x)
166
+ { /* --- series approximation */
167
+ int i; /* loop variable */
168
+ double t, sum; /* buffers */
169
+
170
+ sum = t = 1/n; /* compute initial values */
171
+ for (i = MAXITER; --i >= 0; ) {
172
+ sum += t *= x/++n; /* add one term of the series */
173
+ if (fabs(t) < fabs(sum) *EPSILON) break;
174
+ } /* if term is small enough, abort */
175
+ return sum; /* return the computed factor */
176
+ } /* _series() */
177
+
178
+ /*----------------------------------------------------------------------
179
+ series approximation:
180
+ P(a,x) = \gamma(a,x)/\Gamma(a)
181
+ \gamma(a,x) = e^-x x^a \sum_{n=0}^\infty (\Gamma(a)/\Gamma(a+1+n)) x^n
182
+
183
+ Source: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery
184
+ Numerical Recipes in C - The Art of Scientific Computing
185
+ Cambridge University Press, Cambridge, United Kingdom 1992
186
+ formula: pp. 216-219
187
+
188
+ The factor exp(n *log(x) -x) is added in the functions below.
189
+ ----------------------------------------------------------------------*/
190
+
191
+ static double _cfrac (double n, double x)
192
+ { /* --- continued fraction approx. */
193
+ int i; /* loop variable */
194
+ double a, b, c, d, e, f; /* buffers */
195
+
196
+ b = x+1-n; c = 1/TINY; f = d = 1/b;
197
+ for (i = 1; i < MAXITER; i++) {
198
+ a = i*(n-i); /* use Lentz's algorithm to compute */
199
+ d = a *d +(b += 2); /* consecutive approximations */
200
+ if (fabs(d) < TINY) d = TINY;
201
+ c = b +a/c;
202
+ if (fabs(c) < TINY) c = TINY;
203
+ d = 1/d; f *= e = d *c;
204
+ if (fabs(e-1) < EPSILON) break;
205
+ } /* if factor is small enough, abort */
206
+ return f; /* return the computed factor */
207
+ } /* _cfrac() */
208
+
209
+ /*----------------------------------------------------------------------
210
+ continued fraction approximation:
211
+ P(a,x) = 1 -\Gamma(a,x)/\Gamma(a)
212
+ \Gamma(a,x) = e^-x x^a (1/(x+1-a- 1(1-a)/(x+3-a- 2*(2-a)/(x+5-a- ...))))
213
+
214
+ Source: W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. Flannery
215
+ Numerical Recipes in C - The Art of Scientific Computing
216
+ Cambridge University Press, Cambridge, United Kingdom 1992
217
+ formula: pp. 216-219
218
+ Lentz's algorithm: p. 171
219
+
220
+ The factor exp(n *log(x) -x) is added in the functions below.
221
+ ----------------------------------------------------------------------*/
222
+
223
+ double lowerGamma (double n, double x)
224
+ { /* --- lower incomplete Gamma fn. */
225
+ assert((n > 0) && (x > 0)); /* check the function arguments */
226
+ return _series(n, x) *exp(n *log(x) -x);
227
+ } /* lowerGamma() */
228
+
229
+ /*--------------------------------------------------------------------*/
230
+
231
+ double upperGamma (double n, double x)
232
+ { /* --- upper incomplete Gamma fn. */
233
+ assert((n > 0) && (x > 0)); /* check the function arguments */
234
+ return _cfrac(n, x) *exp(n *log(x) -x);
235
+ } /* upperGamma() */
236
+
237
+ /*--------------------------------------------------------------------*/
238
+
239
+ double GammaP (double n, double x)
240
+ { /* --- regularized Gamma function P */
241
+ assert((n > 0) && (x >= 0)); /* check the function arguments */
242
+ if (x <= 0) return 0; /* treat x = 0 as a special case */
243
+ if (x < n+1) return _series(n, x) *exp(n *log(x) -x -logGamma(n));
244
+ return 1 -_cfrac(n, x) *exp(n *log(x) -x -logGamma(n));
245
+ } /* GammaP() */
246
+
247
+ /*--------------------------------------------------------------------*/
248
+
249
+ double GammaQ (double n, double x)
250
+ { /* --- regularized Gamma function Q */
251
+ assert((n > 0) && (x >= 0)); /* check the function arguments */
252
+ if (x <= 0) return 1; /* treat x = 0 as a special case */
253
+ if (x < n+1) return 1 -_series(n, x) *exp(n *log(x) -x -logGamma(n));
254
+ return _cfrac(n, x) *exp(n *log(x) -x -logGamma(n));
255
+ } /* GammaQ() */
256
+
257
+ /*----------------------------------------------------------------------
258
+ P(a,x) is also called the regularized gamma function, Q(a,x) = 1-P(a,x).
259
+ P(k/2,x/2), where k is a natural number, is the cumulative distribution
260
+ function (cdf) of a chi^2 distribution with k degrees of freedom.
261
+ ----------------------------------------------------------------------*/
262
+
263
+ double Gammapdf (double x, double k, double theta)
264
+ { /* --- probability density function */
265
+ assert((k > 0) && (theta > 0));
266
+ if (x < 0) return 0; /* support is non-negative x */
267
+ if (x <= 0) return (k == 1) ? 1/theta : 0;
268
+ if (k == 1) return exp(-x/theta) /theta;
269
+ return exp ((k-1) *log(x/theta) -x/theta -logGamma(k)) /theta;
270
+ } /* Gammapdf() */
271
+
272
+ /*--------------------------------------------------------------------*/
273
+ #ifdef GAMMAQTL
274
+
275
+ double GammaqtlP (double prob, double k, double theta)
276
+ { /* --- quantile of Gamma distribution */
277
+ int n = 0; /* loop variable */
278
+ double x, f, a, d, dx, dp; /* buffers */
279
+
280
+ assert((k > 0) && (theta > 0) /* check the function arguments */
281
+ && (prob >= 0) && (prob <= 1));
282
+ if (prob >= 1.0) return DBL_MAX;
283
+ if (prob <= 0.0) return 0; /* handle limiting values */
284
+ if (prob < 0.05) x = exp(logGamma(k) +log(prob) /k);
285
+ else if (prob > 0.95) x = logGamma(k) -log1p(-prob);
286
+ else { /* distinguish three prob. ranges */
287
+ f = unitqtlP(prob); a = sqrt(k);
288
+ x = (f >= -a) ? a *f +k : k;
289
+ } /* compute initial approximation */
290
+ do { /* Lagrange's interpolation */
291
+ dp = prob -GammacdfP(x, k, 1);
292
+ if ((dp == 0) || (++n > 33)) break;
293
+ f = Gammapdf(x, k, 1);
294
+ a = 2 *fabs(dp/x);
295
+ a = dx = dp /((a > f) ? a : f);
296
+ d = -0.25 *((k-1)/x -1) *a*a;
297
+ if (fabs(d) < fabs(a)) dx += d;
298
+ if (x +dx > 0) x += dx;
299
+ else x /= 2;
300
+ } while (fabs(a) > 1e-10 *x);
301
+ if (fabs(dp) > EPS_QTL *prob) return -1;
302
+ return x *theta; /* check for convergence and */
303
+ } /* GammaqtlP() */ /* return the computed quantile */
304
+
305
+ /*--------------------------------------------------------------------*/
306
+
307
+ double GammaqtlQ (double prob, double k, double theta)
308
+ { /* --- quantile of Gamma distribution */
309
+ int n = 0; /* loop variable */
310
+ double x, f, a, d, dx, dp; /* buffers */
311
+
312
+ assert((k > 0) && (theta > 0) /* check the function arguments */
313
+ && (prob >= 0) && (prob <= 1));
314
+ if (prob <= 0.0) return DBL_MAX;
315
+ if (prob >= 1.0) return 0; /* handle limiting values */
316
+ if (prob < 0.05) x = logGamma(k) -log(prob);
317
+ else if (prob > 0.95) x = exp(logGamma(k) +log1p(-prob) /k);
318
+ else { /* distinguish three prob. ranges */
319
+ f = unitqtlQ(prob); a = sqrt(k);
320
+ x = (f >= -a) ? a *f +k : k;
321
+ } /* compute initial approximation */
322
+ do { /* Lagrange's interpolation */
323
+ dp = prob -GammacdfQ(x, k, 1);
324
+ if ((dp == 0) || (++n > 33)) break;
325
+ f = Gammapdf(x, k, 1);
326
+ a = 2 *fabs(dp/x);
327
+ a = dx = -dp /((a > f) ? a : f);
328
+ d = -0.25 *((k-1)/x -1) *a*a;
329
+ if (fabs(d) < fabs(a)) dx += d;
330
+ if (x +dx > 0) x += dx;
331
+ else x /= 2;
332
+ } while (fabs(a) > 1e-10 *x);
333
+ if (fabs(dp) > EPS_QTL *prob) return -1;
334
+ return x *theta; /* check for convergence and */
335
+ } /* GammaqtlQ() */ /* return the computed quantile */
336
+
337
+ #endif
338
+ /*--------------------------------------------------------------------*/
339
+ #ifdef GAMMA_MAIN
340
+
341
+ int main (int argc, char *argv[])
342
+ { /* --- main function */
343
+ double x; /* argument */
344
+
345
+ if (argc != 2) { /* if wrong number of arguments given */
346
+ printf("usage: %s x\n", argv[0]);
347
+ printf("compute (logarithm of) Gamma function\n");
348
+ return 0; /* print a usage message */
349
+ } /* and abort the program */
350
+ x = atof(argv[1]); /* get argument */
351
+ if (x <= 0) { printf("%s: x must be > 0\n", argv[0]); return -1; }
352
+ printf(" Gamma(%.16g) = % .20g\n", x, Gamma(x));
353
+ printf("ln(Gamma(%.16g)) = % .20g\n", x, logGamma(x));
354
+ return 0; /* compute and print Gamma function */
355
+ } /* main() */
356
+
357
+ #endif
358
+ /*--------------------------------------------------------------------*/
359
+ #ifdef GAMMAPDF_MAIN
360
+
361
+ int main (int argc, char *argv[])
362
+ { /* --- main function */
363
+ double shape = 1; /* shape parameter */
364
+ double scale = 1; /* scale parameter */
365
+ double x; /* argument value */
366
+
367
+ if ((argc < 2) || (argc > 4)){/* if wrong number of arguments */
368
+ printf("usage: %s arg [shape scale]\n", argv[0]);
369
+ printf("compute probability density function "
370
+ "of the gamma distribution\n");
371
+ return 0; /* print a usage message */
372
+ } /* and abort the program */
373
+ x = atof(argv[1]); /* get the argument value */
374
+ if (argc > 2) shape = atof(argv[2]);
375
+ if (shape <= 0) { /* get the parameters */
376
+ printf("%s: invalid shape parameter\n", argv[0]); return -1; }
377
+ if (argc > 3) scale = atof(argv[3]);
378
+ if (scale <= 0) { /* get the parameters */
379
+ printf("%s: invalid scale parameter\n", argv[0]); return -1; }
380
+ printf("gamma: f(%.16g; %.16g, %.16g) = %.16g\n",
381
+ x, shape, scale, Gammapdf(x, shape, scale));
382
+ return 0; /* compute and print density */
383
+ } /* main() */
384
+
385
+ #endif
386
+ /*--------------------------------------------------------------------*/
387
+ #ifdef GAMMACDF_MAIN
388
+
389
+ int main (int argc, char *argv[])
390
+ { /* --- main function */
391
+ double shape = 1; /* shape parameter */
392
+ double scale = 1; /* scale parameter */
393
+ double x; /* argument value */
394
+
395
+ if ((argc < 2) || (argc > 4)){/* if wrong number of arguments */
396
+ printf("usage: %s arg [shape scale]\n", argv[0]);
397
+ printf("compute cumulative distribution function "
398
+ "of the gamma distribution\n");
399
+ return 0; /* print a usage message */
400
+ } /* and abort the program */
401
+ x = atof(argv[1]); /* get the argument value */
402
+ if (argc > 2) shape = atof(argv[2]);
403
+ if (shape <= 0) { /* get the parameters */
404
+ printf("%s: invalid shape parameter\n", argv[0]); return -1; }
405
+ if (argc > 3) scale = atof(argv[3]);
406
+ if (scale <= 0) { /* get the parameters */
407
+ printf("%s: invalid scale parameter\n", argv[0]); return -1; }
408
+ printf("gamma: F(% .16g; %.16g, %.16g) = %.16g\n",
409
+ x, shape, scale, GammacdfP(x, shape, scale));
410
+ printf(" 1 - F(% .16g; %.16g, %.16g) = %.16g\n",
411
+ x, shape, scale, GammacdfQ(x, shape, scale));
412
+ return 0; /* compute and print probability */
413
+ } /* main() */
414
+
415
+ #endif
416
+ /*--------------------------------------------------------------------*/
417
+ #ifdef GAMMAQTL_MAIN
418
+
419
+ int main (int argc, char *argv[])
420
+ { /* --- main function */
421
+ double shape = 1; /* shape parameter */
422
+ double scale = 1; /* scale parameter */
423
+ double prob; /* argument value */
424
+
425
+ if ((argc < 2) || (argc > 4)){/* if wrong number of arguments */
426
+ printf("usage: %s prob [shape scale]\n", argv[0]);
427
+ printf("compute quantile of the gamma distribution\n");
428
+ return 0; /* print a usage message */
429
+ } /* and abort the program */
430
+ prob = atof(argv[1]); /* get the probability */
431
+ if ((prob < 0) || (prob > 1)){/* and check it */
432
+ printf("%s: invalid probability\n", argv[0]); return -1; }
433
+ if (argc > 2) shape = atof(argv[2]);
434
+ if (shape <= 0) { /* get the parameters */
435
+ printf("%s: invalid shape parameter\n", argv[0]); return -1; }
436
+ if (argc > 3) scale = atof(argv[3]);
437
+ if (scale <= 0) { /* get the parameters */
438
+ printf("%s: invalid scale parameter\n", argv[0]); return -1; }
439
+ printf("gamma: F(% .16g; %.16g, %.16g) = %.16g\n",
440
+ GammaqtlP(prob, shape, scale), shape, scale, prob);
441
+ printf(" 1 - F(% .16g; %.16g, %.16g) = %.16g\n",
442
+ GammaqtlQ(prob, shape, scale), shape, scale, prob);
443
+ return 0; /* compute and print probability */
444
+ } /* main() */
445
+
446
+ #endif