gsl_cdf__beta_inc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* specfunc/beta_inc.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Author: G. Jungman */
  20. /* Modified for cdfs by Brian Gough, June 2003 */
  21. static double
  22. beta_cont_frac (const double a, const double b, const double x,
  23. const double epsabs)
  24. {
  25. const unsigned int max_iter = 512; /* control iterations */
  26. const double cutoff = 2.0 * GSL_DBL_MIN; /* control the zero cutoff */
  27. unsigned int iter_count = 0;
  28. double cf;
  29. /* standard initialization for continued fraction */
  30. double num_term = 1.0;
  31. double den_term = 1.0 - (a + b) * x / (a + 1.0);
  32. if (fabs (den_term) < cutoff)
  33. den_term = GSL_NAN;
  34. den_term = 1.0 / den_term;
  35. cf = den_term;
  36. while (iter_count < max_iter)
  37. {
  38. const int k = iter_count + 1;
  39. double coeff = k * (b - k) * x / (((a - 1.0) + 2 * k) * (a + 2 * k));
  40. double delta_frac;
  41. /* first step */
  42. den_term = 1.0 + coeff * den_term;
  43. num_term = 1.0 + coeff / num_term;
  44. if (fabs (den_term) < cutoff)
  45. den_term = GSL_NAN;
  46. if (fabs (num_term) < cutoff)
  47. num_term = GSL_NAN;
  48. den_term = 1.0 / den_term;
  49. delta_frac = den_term * num_term;
  50. cf *= delta_frac;
  51. coeff = -(a + k) * (a + b + k) * x / ((a + 2 * k) * (a + 2 * k + 1.0));
  52. /* second step */
  53. den_term = 1.0 + coeff * den_term;
  54. num_term = 1.0 + coeff / num_term;
  55. if (fabs (den_term) < cutoff)
  56. den_term = GSL_NAN;
  57. if (fabs (num_term) < cutoff)
  58. num_term = GSL_NAN;
  59. den_term = 1.0 / den_term;
  60. delta_frac = den_term * num_term;
  61. cf *= delta_frac;
  62. if (fabs (delta_frac - 1.0) < 2.0 * GSL_DBL_EPSILON)
  63. break;
  64. if (cf * fabs (delta_frac - 1.0) < epsabs)
  65. break;
  66. ++iter_count;
  67. }
  68. if (iter_count >= max_iter)
  69. return GSL_NAN;
  70. return cf;
  71. }
  72. /* The function beta_inc_AXPY(A,Y,a,b,x) computes A * beta_inc(a,b,x)
  73. + Y taking account of possible cancellations when using the
  74. hypergeometric transformation beta_inc(a,b,x)=1-beta_inc(b,a,1-x).
  75. It also adjusts the accuracy of beta_inc() to fit the overall
  76. absolute error when A*beta_inc is added to Y. (e.g. if Y >>
  77. A*beta_inc then the accuracy of beta_inc can be reduced) */
  78. static double
  79. beta_inc_AXPY (const double A, const double Y,
  80. const double a, const double b, const double x)
  81. {
  82. if (x == 0.0)
  83. {
  84. return A * 0 + Y;
  85. }
  86. else if (x == 1.0)
  87. {
  88. return A * 1 + Y;
  89. }
  90. else
  91. {
  92. double ln_beta = gsl_sf_lnbeta (a, b);
  93. double ln_pre = -ln_beta + a * log (x) + b * log1p (-x);
  94. double prefactor = exp (ln_pre);
  95. if (x < (a + 1.0) / (a + b + 2.0))
  96. {
  97. /* Apply continued fraction directly. */
  98. double epsabs = fabs (Y / (A * prefactor / a)) * GSL_DBL_EPSILON;
  99. double cf = beta_cont_frac (a, b, x, epsabs);
  100. return A * (prefactor * cf / a) + Y;
  101. }
  102. else
  103. {
  104. /* Apply continued fraction after hypergeometric transformation. */
  105. double epsabs =
  106. fabs ((A + Y) / (A * prefactor / b)) * GSL_DBL_EPSILON;
  107. double cf = beta_cont_frac (b, a, 1.0 - x, epsabs);
  108. double term = prefactor * cf / b;
  109. if (A == -Y)
  110. {
  111. return -A * term;
  112. }
  113. else
  114. {
  115. return A * (1 - term) + Y;
  116. }
  117. }
  118. }
  119. }
  120. /* Direct series evaluation for testing purposes only */
  121. #if 0
  122. static double
  123. beta_series (const double a, const double b, const double x,
  124. const double epsabs)
  125. {
  126. double f = x / (1 - x);
  127. double c = (b - 1) / (a + 1) * f;
  128. double s = 1;
  129. double n = 0;
  130. s += c;
  131. do
  132. {
  133. n++;
  134. c *= -f * (2 + n - b) / (2 + n + a);
  135. s += c;
  136. }
  137. while (n < 512 && fabs (c) > GSL_DBL_EPSILON * fabs (s) + epsabs);
  138. s /= (1 - x);
  139. return s;
  140. }
  141. #endif