incbif.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* incbif()
  2. *
  3. * Inverse of imcomplete beta integral
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float a, b, x, y, incbif();
  10. *
  11. * x = incbif( a, b, y );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Given y, the function finds x such that
  18. *
  19. * incbet( a, b, x ) = y.
  20. *
  21. * the routine performs up to 10 Newton iterations to find the
  22. * root of incbet(a,b,x) - y = 0.
  23. *
  24. *
  25. * ACCURACY:
  26. *
  27. * Relative error:
  28. * x a,b
  29. * arithmetic domain domain # trials peak rms
  30. * IEEE 0,1 0,100 5000 2.8e-4 8.3e-6
  31. *
  32. * Overflow and larger errors may occur for one of a or b near zero
  33. * and the other large.
  34. */
  35. /*
  36. Cephes Math Library Release 2.2: July, 1992
  37. Copyright 1984, 1987, 1992 by Stephen L. Moshier
  38. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  39. */
  40. #include <math.h>
  41. extern float MACHEPF, MINLOGF;
  42. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  43. #ifdef ANSIC
  44. float incbetf(float, float, float);
  45. float ndtrif(float), expf(float), logf(float), sqrtf(float), lgamf(float);
  46. #else
  47. float incbetf();
  48. float ndtrif(), expf(), logf(), sqrtf(), lgamf();
  49. #endif
  50. float incbif( float aaa, float bbb, float yyy0 )
  51. {
  52. float aa, bb, yy0, a, b, y0;
  53. float d, y, x, x0, x1, lgm, yp, di;
  54. int i, rflg;
  55. aa = aaa;
  56. bb = bbb;
  57. yy0 = yyy0;
  58. if( yy0 <= 0 )
  59. return(0.0);
  60. if( yy0 >= 1.0 )
  61. return(1.0);
  62. /* approximation to inverse function */
  63. yp = -ndtrif(yy0);
  64. if( yy0 > 0.5 )
  65. {
  66. rflg = 1;
  67. a = bb;
  68. b = aa;
  69. y0 = 1.0 - yy0;
  70. yp = -yp;
  71. }
  72. else
  73. {
  74. rflg = 0;
  75. a = aa;
  76. b = bb;
  77. y0 = yy0;
  78. }
  79. if( (aa <= 1.0) || (bb <= 1.0) )
  80. {
  81. y = 0.5 * yp * yp;
  82. }
  83. else
  84. {
  85. lgm = (yp * yp - 3.0)* 0.16666666666666667;
  86. x0 = 2.0/( 1.0/(2.0*a-1.0) + 1.0/(2.0*b-1.0) );
  87. y = yp * sqrtf( x0 + lgm ) / x0
  88. - ( 1.0/(2.0*b-1.0) - 1.0/(2.0*a-1.0) )
  89. * (lgm + 0.833333333333333333 - 2.0/(3.0*x0));
  90. y = 2.0 * y;
  91. if( y < MINLOGF )
  92. {
  93. x0 = 1.0;
  94. goto under;
  95. }
  96. }
  97. x = a/( a + b * expf(y) );
  98. y = incbetf( a, b, x );
  99. yp = (y - y0)/y0;
  100. if( fabsf(yp) < 0.1 )
  101. goto newt;
  102. /* Resort to interval halving if not close enough */
  103. x0 = 0.0;
  104. x1 = 1.0;
  105. di = 0.5;
  106. for( i=0; i<20; i++ )
  107. {
  108. if( i != 0 )
  109. {
  110. x = di * x1 + (1.0-di) * x0;
  111. y = incbetf( a, b, x );
  112. yp = (y - y0)/y0;
  113. if( fabsf(yp) < 1.0e-3 )
  114. goto newt;
  115. }
  116. if( y < y0 )
  117. {
  118. x0 = x;
  119. di = 0.5;
  120. }
  121. else
  122. {
  123. x1 = x;
  124. di *= di;
  125. if( di == 0.0 )
  126. di = 0.5;
  127. }
  128. }
  129. if( x0 == 0.0 )
  130. {
  131. under:
  132. mtherr( "incbif", UNDERFLOW );
  133. goto done;
  134. }
  135. newt:
  136. x0 = x;
  137. lgm = lgamf(a+b) - lgamf(a) - lgamf(b);
  138. for( i=0; i<10; i++ )
  139. {
  140. /* compute the function at this point */
  141. if( i != 0 )
  142. y = incbetf(a,b,x0);
  143. /* compute the derivative of the function at this point */
  144. d = (a - 1.0) * logf(x0) + (b - 1.0) * logf(1.0-x0) + lgm;
  145. if( d < MINLOGF )
  146. {
  147. x0 = 0.0;
  148. goto under;
  149. }
  150. d = expf(d);
  151. /* compute the step to the next approximation of x */
  152. d = (y - y0)/d;
  153. x = x0;
  154. x0 = x0 - d;
  155. if( x0 <= 0.0 )
  156. {
  157. x0 = 0.0;
  158. goto under;
  159. }
  160. if( x0 >= 1.0 )
  161. {
  162. x0 = 1.0;
  163. goto under;
  164. }
  165. if( i < 2 )
  166. continue;
  167. if( fabsf(d/x0) < 256.0 * MACHEPF )
  168. goto done;
  169. }
  170. done:
  171. if( rflg )
  172. x0 = 1.0 - x0;
  173. return( x0 );
  174. }