gsl_cdf__tdist.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /* cdf/tdist.c
  2. *
  3. * Copyright (C) 2002 Jason H. Stover.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. /*
  20. * Computes the Student's t cumulative distribution function using
  21. * the method detailed in
  22. *
  23. * W.J. Kennedy and J.E. Gentle, "Statistical Computing." 1980.
  24. * Marcel Dekker. ISBN 0-8247-6898-1.
  25. *
  26. * G.W. Hill and A.W. Davis. "Generalized asymptotic expansions
  27. * of Cornish-Fisher type." Annals of Mathematical Statistics,
  28. * vol. 39, 1264-1273. 1968.
  29. *
  30. * G.W. Hill. "Algorithm 395: Student's t-distribution," Communications
  31. * of the ACM, volume 13, number 10, page 617. October 1970.
  32. *
  33. * G.W. Hill, "Remark on algorithm 395: Student's t-distribution,"
  34. * Transactions on Mathematical Software, volume 7, number 2, page
  35. * 247. June 1982.
  36. */
  37. #include "gsl__config.h"
  38. #include "gsl_cdf.h"
  39. #include "gsl_sf_gamma.h"
  40. #include "gsl_math.h"
  41. #include "gsl_errno.h"
  42. #include "gsl_cdf__beta_inc.c"
  43. static double
  44. poly_eval (const double c[], unsigned int n, double x)
  45. {
  46. unsigned int i;
  47. double y = c[0] * x;
  48. for (i = 1; i < n; i++)
  49. {
  50. y = x * (y + c[i]);
  51. }
  52. y += c[n];
  53. return y;
  54. }
  55. /*
  56. * Use the Cornish-Fisher asymptotic expansion to find a point u such
  57. * that gsl_cdf_gauss(y) = tcdf(t).
  58. *
  59. */
  60. static double
  61. cornish_fisher (double t, double n)
  62. {
  63. const double coeffs6[10] = {
  64. 0.265974025974025974026,
  65. 5.449696969696969696970,
  66. 122.20294372294372294372,
  67. 2354.7298701298701298701,
  68. 37625.00902597402597403,
  69. 486996.1392857142857143,
  70. 4960870.65,
  71. 37978595.55,
  72. 201505390.875,
  73. 622437908.625
  74. };
  75. const double coeffs5[8] = {
  76. 0.2742857142857142857142,
  77. 4.499047619047619047619,
  78. 78.45142857142857142857,
  79. 1118.710714285714285714,
  80. 12387.6,
  81. 101024.55,
  82. 559494.0,
  83. 1764959.625
  84. };
  85. const double coeffs4[6] = {
  86. 0.3047619047619047619048,
  87. 3.752380952380952380952,
  88. 46.67142857142857142857,
  89. 427.5,
  90. 2587.5,
  91. 8518.5
  92. };
  93. const double coeffs3[4] = {
  94. 0.4,
  95. 3.3,
  96. 24.0,
  97. 85.5
  98. };
  99. double a = n - 0.5;
  100. double b = 48.0 * a * a;
  101. double z2 = a * log1p (t * t / n);
  102. double z = sqrt (z2);
  103. double p5 = z * poly_eval (coeffs6, 9, z2);
  104. double p4 = -z * poly_eval (coeffs5, 7, z2);
  105. double p3 = z * poly_eval (coeffs4, 5, z2);
  106. double p2 = -z * poly_eval (coeffs3, 3, z2);
  107. double p1 = z * (z2 + 3.0);
  108. double p0 = z;
  109. double y = p5;
  110. y = (y / b) + p4;
  111. y = (y / b) + p3;
  112. y = (y / b) + p2;
  113. y = (y / b) + p1;
  114. y = (y / b) + p0;
  115. if (t < 0)
  116. y *= -1;
  117. return y;
  118. }
  119. #if 0
  120. /*
  121. * Series approximation for t > 4.0. This needs to be fixed;
  122. * it shouldn't subtract the result from 1.0. A better way is
  123. * to use two different series expansions. Figuring this out
  124. * means rummaging through Fisher's paper in Metron, v5, 1926,
  125. * "Expansion of Student's integral in powers of n^{-1}."
  126. */
  127. #define MAXI 40
  128. static double
  129. normal_approx (const double x, const double nu)
  130. {
  131. double y;
  132. double num;
  133. double diff;
  134. double q;
  135. int i;
  136. double lg1, lg2;
  137. y = 1 / sqrt (1 + x * x / nu);
  138. num = 1.0;
  139. q = 0.0;
  140. diff = 2 * GSL_DBL_EPSILON;
  141. for (i = 2; (i < MAXI) && (diff > GSL_DBL_EPSILON); i += 2)
  142. {
  143. diff = q;
  144. num *= y * y * (i - 1) / i;
  145. q += num / (nu + i);
  146. diff = q - diff;
  147. }
  148. q += 1 / nu;
  149. lg1 = gsl_sf_lngamma (nu / 2.0);
  150. lg2 = gsl_sf_lngamma ((nu + 1.0) / 2.0);
  151. diff = lg2 - lg1;
  152. q *= pow (y, nu) * exp (diff) / sqrt (M_PI);
  153. return q;
  154. }
  155. #endif
  156. double
  157. gsl_cdf_tdist_P (const double x, const double nu)
  158. {
  159. double P;
  160. double x2 = x * x;
  161. if (nu > 30 && x2 < 10 * nu)
  162. {
  163. double u = cornish_fisher (x, nu);
  164. P = gsl_cdf_ugaussian_P (u);
  165. return P;
  166. }
  167. if (x2 < nu)
  168. {
  169. double u = x2 / nu;
  170. double eps = u / (1 + u);
  171. if (x >= 0)
  172. {
  173. P = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps);
  174. }
  175. else
  176. {
  177. P = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps);
  178. }
  179. }
  180. else
  181. {
  182. double v = nu / (x * x);
  183. double eps = v / (1 + v);
  184. if (x >= 0)
  185. {
  186. P = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps);
  187. }
  188. else
  189. {
  190. P = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps);
  191. }
  192. }
  193. return P;
  194. }
  195. double
  196. gsl_cdf_tdist_Q (const double x, const double nu)
  197. {
  198. double Q;
  199. double x2 = x * x;
  200. if (nu > 30 && x2 < 10 * nu)
  201. {
  202. double u = cornish_fisher (x, nu);
  203. Q = gsl_cdf_ugaussian_Q (u);
  204. return Q;
  205. }
  206. if (x2 < nu)
  207. {
  208. double u = x2 / nu;
  209. double eps = u / (1 + u);
  210. if (x >= 0)
  211. {
  212. Q = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps);
  213. }
  214. else
  215. {
  216. Q = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps);
  217. }
  218. }
  219. else
  220. {
  221. double v = nu / (x * x);
  222. double eps = v / (1 + v);
  223. if (x >= 0)
  224. {
  225. Q = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps);
  226. }
  227. else
  228. {
  229. Q = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps);
  230. }
  231. }
  232. return Q;
  233. }