bdtr.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /* bdtr.c
  2. *
  3. * Binomial distribution
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * int k, n;
  10. * double p, y, bdtr();
  11. *
  12. * y = bdtr( k, n, p );
  13. *
  14. * DESCRIPTION:
  15. *
  16. * Returns the sum of the terms 0 through k of the Binomial
  17. * probability density:
  18. *
  19. * k
  20. * -- ( n ) j n-j
  21. * > ( ) p (1-p)
  22. * -- ( j )
  23. * j=0
  24. *
  25. * The terms are not summed directly; instead the incomplete
  26. * beta integral is employed, according to the formula
  27. *
  28. * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ).
  29. *
  30. * The arguments must be positive, with p ranging from 0 to 1.
  31. *
  32. * ACCURACY:
  33. *
  34. * Tested at random points (a,b,p), with p between 0 and 1.
  35. *
  36. * a,b Relative error:
  37. * arithmetic domain # trials peak rms
  38. * For p between 0.001 and 1:
  39. * IEEE 0,100 100000 4.3e-15 2.6e-16
  40. * See also incbet.c.
  41. *
  42. * ERROR MESSAGES:
  43. *
  44. * message condition value returned
  45. * bdtr domain k < 0 0.0
  46. * n < k
  47. * x < 0, x > 1
  48. */
  49. /* bdtrc()
  50. *
  51. * Complemented binomial distribution
  52. *
  53. *
  54. *
  55. * SYNOPSIS:
  56. *
  57. * int k, n;
  58. * double p, y, bdtrc();
  59. *
  60. * y = bdtrc( k, n, p );
  61. *
  62. * DESCRIPTION:
  63. *
  64. * Returns the sum of the terms k+1 through n of the Binomial
  65. * probability density:
  66. *
  67. * n
  68. * -- ( n ) j n-j
  69. * > ( ) p (1-p)
  70. * -- ( j )
  71. * j=k+1
  72. *
  73. * The terms are not summed directly; instead the incomplete
  74. * beta integral is employed, according to the formula
  75. *
  76. * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ).
  77. *
  78. * The arguments must be positive, with p ranging from 0 to 1.
  79. *
  80. * ACCURACY:
  81. *
  82. * Tested at random points (a,b,p).
  83. *
  84. * a,b Relative error:
  85. * arithmetic domain # trials peak rms
  86. * For p between 0.001 and 1:
  87. * IEEE 0,100 100000 6.7e-15 8.2e-16
  88. * For p between 0 and .001:
  89. * IEEE 0,100 100000 1.5e-13 2.7e-15
  90. *
  91. * ERROR MESSAGES:
  92. *
  93. * message condition value returned
  94. * bdtrc domain x<0, x>1, n<k 0.0
  95. */
  96. /* bdtri()
  97. *
  98. * Inverse binomial distribution
  99. *
  100. *
  101. *
  102. * SYNOPSIS:
  103. *
  104. * int k, n;
  105. * double p, y, bdtri();
  106. *
  107. * p = bdtr( k, n, y );
  108. *
  109. * DESCRIPTION:
  110. *
  111. * Finds the event probability p such that the sum of the
  112. * terms 0 through k of the Binomial probability density
  113. * is equal to the given cumulative probability y.
  114. *
  115. * This is accomplished using the inverse beta integral
  116. * function and the relation
  117. *
  118. * 1 - p = incbi( n-k, k+1, y ).
  119. *
  120. * ACCURACY:
  121. *
  122. * Tested at random points (a,b,p).
  123. *
  124. * a,b Relative error:
  125. * arithmetic domain # trials peak rms
  126. * For p between 0.001 and 1:
  127. * IEEE 0,100 100000 2.3e-14 6.4e-16
  128. * IEEE 0,10000 100000 6.6e-12 1.2e-13
  129. * For p between 10^-6 and 0.001:
  130. * IEEE 0,100 100000 2.0e-12 1.3e-14
  131. * IEEE 0,10000 100000 1.5e-12 3.2e-14
  132. * See also incbi.c.
  133. *
  134. * ERROR MESSAGES:
  135. *
  136. * message condition value returned
  137. * bdtri domain k < 0, n <= k 0.0
  138. * x < 0, x > 1
  139. */
  140. /* bdtr() */
  141. /*
  142. Cephes Math Library Release 2.8: June, 2000
  143. Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier
  144. */
  145. #include <math.h>
  146. #ifdef ANSIPROT
  147. extern double incbet ( double, double, double );
  148. extern double incbi ( double, double, double );
  149. extern double pow ( double, double );
  150. extern double log1p ( double );
  151. extern double expm1 ( double );
  152. #else
  153. double incbet(), incbi(), pow(), log1p(), expm1();
  154. #endif
  155. double bdtrc( k, n, p )
  156. int k, n;
  157. double p;
  158. {
  159. double dk, dn;
  160. if( (p < 0.0) || (p > 1.0) )
  161. goto domerr;
  162. if( k < 0 )
  163. return( 1.0 );
  164. if( n < k )
  165. {
  166. domerr:
  167. mtherr( "bdtrc", DOMAIN );
  168. return( 0.0 );
  169. }
  170. if( k == n )
  171. return( 0.0 );
  172. dn = n - k;
  173. if( k == 0 )
  174. {
  175. if( p < .01 )
  176. dk = -expm1( dn * log1p(-p) );
  177. else
  178. dk = 1.0 - pow( 1.0-p, dn );
  179. }
  180. else
  181. {
  182. dk = k + 1;
  183. dk = incbet( dk, dn, p );
  184. }
  185. return( dk );
  186. }
  187. double bdtr( k, n, p )
  188. int k, n;
  189. double p;
  190. {
  191. double dk, dn;
  192. if( (p < 0.0) || (p > 1.0) )
  193. goto domerr;
  194. if( (k < 0) || (n < k) )
  195. {
  196. domerr:
  197. mtherr( "bdtr", DOMAIN );
  198. return( 0.0 );
  199. }
  200. if( k == n )
  201. return( 1.0 );
  202. dn = n - k;
  203. if( k == 0 )
  204. {
  205. dk = pow( 1.0-p, dn );
  206. }
  207. else
  208. {
  209. dk = k + 1;
  210. dk = incbet( dn, dk, 1.0 - p );
  211. }
  212. return( dk );
  213. }
  214. double bdtri( k, n, y )
  215. int k, n;
  216. double y;
  217. {
  218. double dk, dn, p;
  219. if( (y < 0.0) || (y > 1.0) )
  220. goto domerr;
  221. if( (k < 0) || (n <= k) )
  222. {
  223. domerr:
  224. mtherr( "bdtri", DOMAIN );
  225. return( 0.0 );
  226. }
  227. dn = n - k;
  228. if( k == 0 )
  229. {
  230. if( y > 0.8 )
  231. p = -expm1( log1p(y-1.0) / dn );
  232. else
  233. p = 1.0 - pow( y, 1.0/dn );
  234. }
  235. else
  236. {
  237. dk = k + 1;
  238. p = incbet( dn, dk, 0.5 );
  239. if( p > 0.5 )
  240. p = incbi( dk, dn, 1.0-y );
  241. else
  242. p = 1.0 - incbi( dn, dk, y );
  243. }
  244. return( p );
  245. }