incbetl.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /* incbetl.c
  2. *
  3. * Incomplete beta integral
  4. *
  5. *
  6. * SYNOPSIS:
  7. *
  8. * long double a, b, x, y, incbetl();
  9. *
  10. * y = incbetl( 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 random points (a,b,x) with x between 0 and 1.
  39. * arithmetic domain # trials peak rms
  40. * IEEE 0,5 20000 4.5e-18 2.4e-19
  41. * IEEE 0,100 100000 3.9e-17 1.0e-17
  42. * Half-integer a, b:
  43. * IEEE .5,10000 100000 3.9e-14 4.4e-15
  44. * Outputs smaller than the IEEE gradual underflow threshold
  45. * were excluded from these statistics.
  46. *
  47. * ERROR MESSAGES:
  48. *
  49. * message condition value returned
  50. * incbetl domain x<0, x>1 0.0
  51. */
  52. /*
  53. Cephes Math Library, Release 2.3: January, 1995
  54. Copyright 1984, 1995 by Stephen L. Moshier
  55. */
  56. #include <math.h>
  57. #define MAXGAML 1755.455L
  58. static long double big = 9.223372036854775808e18L;
  59. static long double biginv = 1.084202172485504434007e-19L;
  60. extern long double MACHEPL, MINLOGL, MAXLOGL;
  61. #ifdef ANSIPROT
  62. extern long double gammal ( long double );
  63. extern long double lgaml ( long double );
  64. extern long double expl ( long double );
  65. extern long double logl ( long double );
  66. extern long double fabsl ( long double );
  67. extern long double powl ( long double, long double );
  68. static long double incbcfl( long double, long double, long double );
  69. static long double incbdl( long double, long double, long double );
  70. static long double pseriesl( long double, long double, long double );
  71. #else
  72. long double gammal(), lgaml(), expl(), logl(), fabsl(), powl();
  73. static long double incbcfl(), incbdl(), pseriesl();
  74. #endif
  75. long double incbetl( aa, bb, xx )
  76. long double aa, bb, xx;
  77. {
  78. long double a, b, t, x, w, xc, y;
  79. int flag;
  80. if( aa <= 0.0L || bb <= 0.0L )
  81. goto domerr;
  82. if( (xx <= 0.0L) || ( xx >= 1.0L) )
  83. {
  84. if( xx == 0.0L )
  85. return( 0.0L );
  86. if( xx == 1.0L )
  87. return( 1.0L );
  88. domerr:
  89. mtherr( "incbetl", DOMAIN );
  90. return( 0.0L );
  91. }
  92. flag = 0;
  93. if( (bb * xx) <= 1.0L && xx <= 0.95L)
  94. {
  95. t = pseriesl(aa, bb, xx);
  96. goto done;
  97. }
  98. w = 1.0L - xx;
  99. /* Reverse a and b if x is greater than the mean. */
  100. if( xx > (aa/(aa+bb)) )
  101. {
  102. flag = 1;
  103. a = bb;
  104. b = aa;
  105. xc = xx;
  106. x = w;
  107. }
  108. else
  109. {
  110. a = aa;
  111. b = bb;
  112. xc = w;
  113. x = xx;
  114. }
  115. if( flag == 1 && (b * x) <= 1.0L && x <= 0.95L)
  116. {
  117. t = pseriesl(a, b, x);
  118. goto done;
  119. }
  120. /* Choose expansion for optimal convergence */
  121. y = x * (a+b-2.0L) - (a-1.0L);
  122. if( y < 0.0L )
  123. w = incbcfl( a, b, x );
  124. else
  125. w = incbdl( a, b, x ) / xc;
  126. /* Multiply w by the factor
  127. a b _ _ _
  128. x (1-x) | (a+b) / ( a | (a) | (b) ) . */
  129. y = a * logl(x);
  130. t = b * logl(xc);
  131. if( (a+b) < MAXGAML && fabsl(y) < MAXLOGL && fabsl(t) < MAXLOGL )
  132. {
  133. t = powl(xc,b);
  134. t *= powl(x,a);
  135. t /= a;
  136. t *= w;
  137. t *= gammal(a+b) / (gammal(a) * gammal(b));
  138. goto done;
  139. }
  140. else
  141. {
  142. /* Resort to logarithms. */
  143. y += t + lgaml(a+b) - lgaml(a) - lgaml(b);
  144. y += logl(w/a);
  145. if( y < MINLOGL )
  146. t = 0.0L;
  147. else
  148. t = expl(y);
  149. }
  150. done:
  151. if( flag == 1 )
  152. {
  153. if( t <= MACHEPL )
  154. t = 1.0L - MACHEPL;
  155. else
  156. t = 1.0L - t;
  157. }
  158. return( t );
  159. }
  160. /* Continued fraction expansion #1
  161. * for incomplete beta integral
  162. */
  163. static long double incbcfl( a, b, x )
  164. long double a, b, x;
  165. {
  166. long double xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
  167. long double k1, k2, k3, k4, k5, k6, k7, k8;
  168. long double r, t, ans, thresh;
  169. int n;
  170. k1 = a;
  171. k2 = a + b;
  172. k3 = a;
  173. k4 = a + 1.0L;
  174. k5 = 1.0L;
  175. k6 = b - 1.0L;
  176. k7 = k4;
  177. k8 = a + 2.0L;
  178. pkm2 = 0.0L;
  179. qkm2 = 1.0L;
  180. pkm1 = 1.0L;
  181. qkm1 = 1.0L;
  182. ans = 1.0L;
  183. r = 1.0L;
  184. n = 0;
  185. thresh = 3.0L * MACHEPL;
  186. do
  187. {
  188. xk = -( x * k1 * k2 )/( k3 * k4 );
  189. pk = pkm1 + pkm2 * xk;
  190. qk = qkm1 + qkm2 * xk;
  191. pkm2 = pkm1;
  192. pkm1 = pk;
  193. qkm2 = qkm1;
  194. qkm1 = qk;
  195. xk = ( x * k5 * k6 )/( k7 * k8 );
  196. pk = pkm1 + pkm2 * xk;
  197. qk = qkm1 + qkm2 * xk;
  198. pkm2 = pkm1;
  199. pkm1 = pk;
  200. qkm2 = qkm1;
  201. qkm1 = qk;
  202. if( qk != 0.0L )
  203. r = pk/qk;
  204. if( r != 0.0L )
  205. {
  206. t = fabsl( (ans - r)/r );
  207. ans = r;
  208. }
  209. else
  210. t = 1.0L;
  211. if( t < thresh )
  212. goto cdone;
  213. k1 += 1.0L;
  214. k2 += 1.0L;
  215. k3 += 2.0L;
  216. k4 += 2.0L;
  217. k5 += 1.0L;
  218. k6 -= 1.0L;
  219. k7 += 2.0L;
  220. k8 += 2.0L;
  221. if( (fabsl(qk) + fabsl(pk)) > big )
  222. {
  223. pkm2 *= biginv;
  224. pkm1 *= biginv;
  225. qkm2 *= biginv;
  226. qkm1 *= biginv;
  227. }
  228. if( (fabsl(qk) < biginv) || (fabsl(pk) < biginv) )
  229. {
  230. pkm2 *= big;
  231. pkm1 *= big;
  232. qkm2 *= big;
  233. qkm1 *= big;
  234. }
  235. }
  236. while( ++n < 400 );
  237. mtherr( "incbetl", PLOSS );
  238. cdone:
  239. return(ans);
  240. }
  241. /* Continued fraction expansion #2
  242. * for incomplete beta integral
  243. */
  244. static long double incbdl( a, b, x )
  245. long double a, b, x;
  246. {
  247. long double xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
  248. long double k1, k2, k3, k4, k5, k6, k7, k8;
  249. long double r, t, ans, z, thresh;
  250. int n;
  251. k1 = a;
  252. k2 = b - 1.0L;
  253. k3 = a;
  254. k4 = a + 1.0L;
  255. k5 = 1.0L;
  256. k6 = a + b;
  257. k7 = a + 1.0L;
  258. k8 = a + 2.0L;
  259. pkm2 = 0.0L;
  260. qkm2 = 1.0L;
  261. pkm1 = 1.0L;
  262. qkm1 = 1.0L;
  263. z = x / (1.0L-x);
  264. ans = 1.0L;
  265. r = 1.0L;
  266. n = 0;
  267. thresh = 3.0L * MACHEPL;
  268. do
  269. {
  270. xk = -( z * k1 * k2 )/( k3 * k4 );
  271. pk = pkm1 + pkm2 * xk;
  272. qk = qkm1 + qkm2 * xk;
  273. pkm2 = pkm1;
  274. pkm1 = pk;
  275. qkm2 = qkm1;
  276. qkm1 = qk;
  277. xk = ( z * k5 * k6 )/( k7 * k8 );
  278. pk = pkm1 + pkm2 * xk;
  279. qk = qkm1 + qkm2 * xk;
  280. pkm2 = pkm1;
  281. pkm1 = pk;
  282. qkm2 = qkm1;
  283. qkm1 = qk;
  284. if( qk != 0.0L )
  285. r = pk/qk;
  286. if( r != 0.0L )
  287. {
  288. t = fabsl( (ans - r)/r );
  289. ans = r;
  290. }
  291. else
  292. t = 1.0L;
  293. if( t < thresh )
  294. goto cdone;
  295. k1 += 1.0L;
  296. k2 -= 1.0L;
  297. k3 += 2.0L;
  298. k4 += 2.0L;
  299. k5 += 1.0L;
  300. k6 += 1.0L;
  301. k7 += 2.0L;
  302. k8 += 2.0L;
  303. if( (fabsl(qk) + fabsl(pk)) > big )
  304. {
  305. pkm2 *= biginv;
  306. pkm1 *= biginv;
  307. qkm2 *= biginv;
  308. qkm1 *= biginv;
  309. }
  310. if( (fabsl(qk) < biginv) || (fabsl(pk) < biginv) )
  311. {
  312. pkm2 *= big;
  313. pkm1 *= big;
  314. qkm2 *= big;
  315. qkm1 *= big;
  316. }
  317. }
  318. while( ++n < 400 );
  319. mtherr( "incbetl", PLOSS );
  320. cdone:
  321. return(ans);
  322. }
  323. /* Power series for incomplete gamma integral.
  324. Use when b*x is small. */
  325. static long double pseriesl( a, b, x )
  326. long double a, b, x;
  327. {
  328. long double s, t, u, v, n, t1, z, ai;
  329. ai = 1.0L / a;
  330. u = (1.0L - b) * x;
  331. v = u / (a + 1.0L);
  332. t1 = v;
  333. t = u;
  334. n = 2.0L;
  335. s = 0.0L;
  336. z = MACHEPL * ai;
  337. while( fabsl(v) > z )
  338. {
  339. u = (n - b) * x / n;
  340. t *= u;
  341. v = t / (a + n);
  342. s += v;
  343. n += 1.0L;
  344. }
  345. s += t1;
  346. s += ai;
  347. u = a * logl(x);
  348. if( (a+b) < MAXGAML && fabsl(u) < MAXLOGL )
  349. {
  350. t = gammal(a+b)/(gammal(a)*gammal(b));
  351. s = s * t * powl(x,a);
  352. }
  353. else
  354. {
  355. t = lgaml(a+b) - lgaml(a) - lgaml(b) + u + logl(s);
  356. if( t < MINLOGL )
  357. s = 0.0L;
  358. else
  359. s = expl(t);
  360. }
  361. return(s);
  362. }