incbet.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /* incbet.c
  2. *
  3. * Incomplete beta integral
  4. *
  5. *
  6. * SYNOPSIS:
  7. *
  8. * double a, b, x, y, incbet();
  9. *
  10. * y = incbet( a, b, x );
  11. *
  12. *
  13. * DESCRIPTION:
  14. *
  15. * Returns incomplete beta integral of the arguments, evaluated
  16. * from zero to x. The function is defined as
  17. *
  18. * x
  19. * - -
  20. * | (a+b) | | a-1 b-1
  21. * ----------- | t (1-t) dt.
  22. * - - | |
  23. * | (a) | (b) -
  24. * 0
  25. *
  26. * The domain of definition is 0 <= x <= 1. In this
  27. * implementation a and b are restricted to positive values.
  28. * The integral from x to 1 may be obtained by the symmetry
  29. * relation
  30. *
  31. * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ).
  32. *
  33. * The integral is evaluated by a continued fraction expansion
  34. * or, when b*x is small, by a power series.
  35. *
  36. * ACCURACY:
  37. *
  38. * Tested at uniformly distributed random points (a,b,x) with a and b
  39. * in "domain" and x between 0 and 1.
  40. * Relative error
  41. * arithmetic domain # trials peak rms
  42. * IEEE 0,5 10000 6.9e-15 4.5e-16
  43. * IEEE 0,85 250000 2.2e-13 1.7e-14
  44. * IEEE 0,1000 30000 5.3e-12 6.3e-13
  45. * IEEE 0,10000 250000 9.3e-11 7.1e-12
  46. * IEEE 0,100000 10000 8.7e-10 4.8e-11
  47. * Outputs smaller than the IEEE gradual underflow threshold
  48. * were excluded from these statistics.
  49. *
  50. * ERROR MESSAGES:
  51. * message condition value returned
  52. * incbet domain x<0, x>1 0.0
  53. * incbet underflow 0.0
  54. */
  55. /*
  56. Cephes Math Library, Release 2.8: June, 2000
  57. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  58. */
  59. #include <math.h>
  60. #ifdef DEC
  61. #define MAXGAM 34.84425627277176174
  62. #else
  63. #define MAXGAM 171.624376956302725
  64. #endif
  65. extern double MACHEP, MINLOG, MAXLOG;
  66. #ifdef ANSIPROT
  67. extern double gamma ( double );
  68. extern double lgam ( double );
  69. extern double exp ( double );
  70. extern double log ( double );
  71. extern double pow ( double, double );
  72. extern double fabs ( double );
  73. static double incbcf(double, double, double);
  74. static double incbd(double, double, double);
  75. static double pseries(double, double, double);
  76. #else
  77. double gamma(), lgam(), exp(), log(), pow(), fabs();
  78. static double incbcf(), incbd(), pseries();
  79. #endif
  80. static double big = 4.503599627370496e15;
  81. static double biginv = 2.22044604925031308085e-16;
  82. double incbet( aa, bb, xx )
  83. double aa, bb, xx;
  84. {
  85. double a, b, t, x, xc, w, y;
  86. int flag;
  87. if( aa <= 0.0 || bb <= 0.0 )
  88. goto domerr;
  89. if( (xx <= 0.0) || ( xx >= 1.0) )
  90. {
  91. if( xx == 0.0 )
  92. return(0.0);
  93. if( xx == 1.0 )
  94. return( 1.0 );
  95. domerr:
  96. mtherr( "incbet", DOMAIN );
  97. return( 0.0 );
  98. }
  99. flag = 0;
  100. if( (bb * xx) <= 1.0 && xx <= 0.95)
  101. {
  102. t = pseries(aa, bb, xx);
  103. goto done;
  104. }
  105. w = 1.0 - xx;
  106. /* Reverse a and b if x is greater than the mean. */
  107. if( xx > (aa/(aa+bb)) )
  108. {
  109. flag = 1;
  110. a = bb;
  111. b = aa;
  112. xc = xx;
  113. x = w;
  114. }
  115. else
  116. {
  117. a = aa;
  118. b = bb;
  119. xc = w;
  120. x = xx;
  121. }
  122. if( flag == 1 && (b * x) <= 1.0 && x <= 0.95)
  123. {
  124. t = pseries(a, b, x);
  125. goto done;
  126. }
  127. /* Choose expansion for better convergence. */
  128. y = x * (a+b-2.0) - (a-1.0);
  129. if( y < 0.0 )
  130. w = incbcf( a, b, x );
  131. else
  132. w = incbd( a, b, x ) / xc;
  133. /* Multiply w by the factor
  134. a b _ _ _
  135. x (1-x) | (a+b) / ( a | (a) | (b) ) . */
  136. y = a * log(x);
  137. t = b * log(xc);
  138. if( (a+b) < MAXGAM && fabs(y) < MAXLOG && fabs(t) < MAXLOG )
  139. {
  140. t = pow(xc,b);
  141. t *= pow(x,a);
  142. t /= a;
  143. t *= w;
  144. t *= gamma(a+b) / (gamma(a) * gamma(b));
  145. goto done;
  146. }
  147. /* Resort to logarithms. */
  148. y += t + lgam(a+b) - lgam(a) - lgam(b);
  149. y += log(w/a);
  150. if( y < MINLOG )
  151. t = 0.0;
  152. else
  153. t = exp(y);
  154. done:
  155. if( flag == 1 )
  156. {
  157. if( t <= MACHEP )
  158. t = 1.0 - MACHEP;
  159. else
  160. t = 1.0 - t;
  161. }
  162. return( t );
  163. }
  164. /* Continued fraction expansion #1
  165. * for incomplete beta integral
  166. */
  167. static double incbcf( a, b, x )
  168. double a, b, x;
  169. {
  170. double xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
  171. double k1, k2, k3, k4, k5, k6, k7, k8;
  172. double r, t, ans, thresh;
  173. int n;
  174. k1 = a;
  175. k2 = a + b;
  176. k3 = a;
  177. k4 = a + 1.0;
  178. k5 = 1.0;
  179. k6 = b - 1.0;
  180. k7 = k4;
  181. k8 = a + 2.0;
  182. pkm2 = 0.0;
  183. qkm2 = 1.0;
  184. pkm1 = 1.0;
  185. qkm1 = 1.0;
  186. ans = 1.0;
  187. r = 1.0;
  188. n = 0;
  189. thresh = 3.0 * MACHEP;
  190. do
  191. {
  192. xk = -( x * k1 * k2 )/( k3 * k4 );
  193. pk = pkm1 + pkm2 * xk;
  194. qk = qkm1 + qkm2 * xk;
  195. pkm2 = pkm1;
  196. pkm1 = pk;
  197. qkm2 = qkm1;
  198. qkm1 = qk;
  199. xk = ( x * k5 * k6 )/( k7 * k8 );
  200. pk = pkm1 + pkm2 * xk;
  201. qk = qkm1 + qkm2 * xk;
  202. pkm2 = pkm1;
  203. pkm1 = pk;
  204. qkm2 = qkm1;
  205. qkm1 = qk;
  206. if( qk != 0 )
  207. r = pk/qk;
  208. if( r != 0 )
  209. {
  210. t = fabs( (ans - r)/r );
  211. ans = r;
  212. }
  213. else
  214. t = 1.0;
  215. if( t < thresh )
  216. goto cdone;
  217. k1 += 1.0;
  218. k2 += 1.0;
  219. k3 += 2.0;
  220. k4 += 2.0;
  221. k5 += 1.0;
  222. k6 -= 1.0;
  223. k7 += 2.0;
  224. k8 += 2.0;
  225. if( (fabs(qk) + fabs(pk)) > big )
  226. {
  227. pkm2 *= biginv;
  228. pkm1 *= biginv;
  229. qkm2 *= biginv;
  230. qkm1 *= biginv;
  231. }
  232. if( (fabs(qk) < biginv) || (fabs(pk) < biginv) )
  233. {
  234. pkm2 *= big;
  235. pkm1 *= big;
  236. qkm2 *= big;
  237. qkm1 *= big;
  238. }
  239. }
  240. while( ++n < 300 );
  241. cdone:
  242. return(ans);
  243. }
  244. /* Continued fraction expansion #2
  245. * for incomplete beta integral
  246. */
  247. static double incbd( a, b, x )
  248. double a, b, x;
  249. {
  250. double xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
  251. double k1, k2, k3, k4, k5, k6, k7, k8;
  252. double r, t, ans, z, thresh;
  253. int n;
  254. k1 = a;
  255. k2 = b - 1.0;
  256. k3 = a;
  257. k4 = a + 1.0;
  258. k5 = 1.0;
  259. k6 = a + b;
  260. k7 = a + 1.0;;
  261. k8 = a + 2.0;
  262. pkm2 = 0.0;
  263. qkm2 = 1.0;
  264. pkm1 = 1.0;
  265. qkm1 = 1.0;
  266. z = x / (1.0-x);
  267. ans = 1.0;
  268. r = 1.0;
  269. n = 0;
  270. thresh = 3.0 * MACHEP;
  271. do
  272. {
  273. xk = -( z * k1 * k2 )/( k3 * k4 );
  274. pk = pkm1 + pkm2 * xk;
  275. qk = qkm1 + qkm2 * xk;
  276. pkm2 = pkm1;
  277. pkm1 = pk;
  278. qkm2 = qkm1;
  279. qkm1 = qk;
  280. xk = ( z * k5 * k6 )/( k7 * k8 );
  281. pk = pkm1 + pkm2 * xk;
  282. qk = qkm1 + qkm2 * xk;
  283. pkm2 = pkm1;
  284. pkm1 = pk;
  285. qkm2 = qkm1;
  286. qkm1 = qk;
  287. if( qk != 0 )
  288. r = pk/qk;
  289. if( r != 0 )
  290. {
  291. t = fabs( (ans - r)/r );
  292. ans = r;
  293. }
  294. else
  295. t = 1.0;
  296. if( t < thresh )
  297. goto cdone;
  298. k1 += 1.0;
  299. k2 -= 1.0;
  300. k3 += 2.0;
  301. k4 += 2.0;
  302. k5 += 1.0;
  303. k6 += 1.0;
  304. k7 += 2.0;
  305. k8 += 2.0;
  306. if( (fabs(qk) + fabs(pk)) > big )
  307. {
  308. pkm2 *= biginv;
  309. pkm1 *= biginv;
  310. qkm2 *= biginv;
  311. qkm1 *= biginv;
  312. }
  313. if( (fabs(qk) < biginv) || (fabs(pk) < biginv) )
  314. {
  315. pkm2 *= big;
  316. pkm1 *= big;
  317. qkm2 *= big;
  318. qkm1 *= big;
  319. }
  320. }
  321. while( ++n < 300 );
  322. cdone:
  323. return(ans);
  324. }
  325. /* Power series for incomplete beta integral.
  326. Use when b*x is small and x not too close to 1. */
  327. static double pseries( a, b, x )
  328. double a, b, x;
  329. {
  330. double s, t, u, v, n, t1, z, ai;
  331. ai = 1.0 / a;
  332. u = (1.0 - b) * x;
  333. v = u / (a + 1.0);
  334. t1 = v;
  335. t = u;
  336. n = 2.0;
  337. s = 0.0;
  338. z = MACHEP * ai;
  339. while( fabs(v) > z )
  340. {
  341. u = (n - b) * x / n;
  342. t *= u;
  343. v = t / (a + n);
  344. s += v;
  345. n += 1.0;
  346. }
  347. s += t1;
  348. s += ai;
  349. u = a * log(x);
  350. if( (a+b) < MAXGAM && fabs(u) < MAXLOG )
  351. {
  352. t = gamma(a+b)/(gamma(a)*gamma(b));
  353. s = s * t * pow(x,a);
  354. }
  355. else
  356. {
  357. t = lgam(a+b) - lgam(a) - lgam(b) + u + log(s);
  358. if( t < MINLOG )
  359. s = 0.0;
  360. else
  361. s = exp(t);
  362. }
  363. return(s);
  364. }