ibeta_inv.qbk 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. [section:ibeta_inv_function The Incomplete Beta Function Inverses]
  2. ``
  3. #include <boost/math/special_functions/beta.hpp>
  4. ``
  5. namespace boost{ namespace math{
  6. template <class T1, class T2, class T3>
  7. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p);
  8. template <class T1, class T2, class T3, class ``__Policy``>
  9. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, const ``__Policy``&);
  10. template <class T1, class T2, class T3, class T4>
  11. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, T4* py);
  12. template <class T1, class T2, class T3, class T4, class ``__Policy``>
  13. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, T4* py, const ``__Policy``&);
  14. template <class T1, class T2, class T3>
  15. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q);
  16. template <class T1, class T2, class T3, class ``__Policy``>
  17. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, const ``__Policy``&);
  18. template <class T1, class T2, class T3, class T4>
  19. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, T4* py);
  20. template <class T1, class T2, class T3, class T4, class ``__Policy``>
  21. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, T4* py, const ``__Policy``&);
  22. template <class T1, class T2, class T3>
  23. ``__sf_result`` ibeta_inva(T1 b, T2 x, T3 p);
  24. template <class T1, class T2, class T3, class ``__Policy``>
  25. ``__sf_result`` ibeta_inva(T1 b, T2 x, T3 p, const ``__Policy``&);
  26. template <class T1, class T2, class T3>
  27. ``__sf_result`` ibetac_inva(T1 b, T2 x, T3 q);
  28. template <class T1, class T2, class T3, class ``__Policy``>
  29. ``__sf_result`` ibetac_inva(T1 b, T2 x, T3 q, const ``__Policy``&);
  30. template <class T1, class T2, class T3>
  31. ``__sf_result`` ibeta_invb(T1 a, T2 x, T3 p);
  32. template <class T1, class T2, class T3, class ``__Policy``>
  33. ``__sf_result`` ibeta_invb(T1 a, T2 x, T3 p, const ``__Policy``&);
  34. template <class T1, class T2, class T3>
  35. ``__sf_result`` ibetac_invb(T1 a, T2 x, T3 q);
  36. template <class T1, class T2, class T3, class ``__Policy``>
  37. ``__sf_result`` ibetac_invb(T1 a, T2 x, T3 q, const ``__Policy``&);
  38. }} // namespaces
  39. [h4 Description]
  40. There are six [@http://functions.wolfram.com/GammaBetaErf/ incomplete beta function inverses]
  41. which allow you solve for
  42. any of the three parameters to the incomplete beta, starting from either
  43. the result of the incomplete beta (p) or its complement (q).
  44. [optional_policy]
  45. [tip When people normally talk about the inverse of the incomplete
  46. beta function, they are talking about inverting on parameter /x/.
  47. These are implemented here as `ibeta_inv` and `ibetac_inv`, and are by
  48. far the most efficient of the inverses presented here.
  49. The inverses on the /a/ and /b/ parameters find use in some statistical
  50. applications, but have to be computed by rather brute force numerical
  51. techniques and are consequently several times slower.
  52. These are implemented here as `ibeta_inva` and `ibeta_invb`,
  53. and complement versions `ibetac_inva` and `ibetac_invb`.]
  54. The return type of these functions is computed using the __arg_promotion_rules
  55. when called with arguments T1...TN of different types.
  56. template <class T1, class T2, class T3>
  57. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p);
  58. template <class T1, class T2, class T3, class ``__Policy``>
  59. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, const ``__Policy``&);
  60. template <class T1, class T2, class T3, class T4>
  61. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, T4* py);
  62. template <class T1, class T2, class T3, class T4, class ``__Policy``>
  63. ``__sf_result`` ibeta_inv(T1 a, T2 b, T3 p, T4* py, const ``__Policy``&);
  64. Returns a value /x/ such that: `p = ibeta(a, b, x);`
  65. and sets `*py = 1 - x` when the `py` parameter is provided and is non-null.
  66. Note that internally this function computes whichever is the smaller of
  67. `x` and `1-x`, and therefore the value assigned to `*py` is free from
  68. cancellation errors. That means that even if the function returns `1`, the
  69. value stored in `*py` may be non-zero, albeit very small.
  70. Requires: /a,b > 0/ and /0 <= p <= 1/.
  71. [optional_policy]
  72. template <class T1, class T2, class T3>
  73. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q);
  74. template <class T1, class T2, class T3, class ``__Policy``>
  75. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, const ``__Policy``&);
  76. template <class T1, class T2, class T3, class T4>
  77. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, T4* py);
  78. template <class T1, class T2, class T3, class T4, class ``__Policy``>
  79. ``__sf_result`` ibetac_inv(T1 a, T2 b, T3 q, T4* py, const ``__Policy``&);
  80. Returns a value /x/ such that: `q = ibetac(a, b, x);`
  81. and sets `*py = 1 - x` when the `py` parameter is provided and is non-null.
  82. Note that internally this function computes whichever is the smaller of
  83. `x` and `1-x`, and therefore the value assigned to `*py` is free from
  84. cancellation errors. That means that even if the function returns `1`, the
  85. value stored in `*py` may be non-zero, albeit very small.
  86. Requires: /a,b > 0/ and /0 <= q <= 1/.
  87. [optional_policy]
  88. template <class T1, class T2, class T3>
  89. ``__sf_result`` ibeta_inva(T1 b, T2 x, T3 p);
  90. template <class T1, class T2, class T3, class ``__Policy``>
  91. ``__sf_result`` ibeta_inva(T1 b, T2 x, T3 p, const ``__Policy``&);
  92. Returns a value /a/ such that: `p = ibeta(a, b, x);`
  93. Requires: /b > 0/, /0 < x < 1/ and /0 <= p <= 1/.
  94. [optional_policy]
  95. template <class T1, class T2, class T3>
  96. ``__sf_result`` ibetac_inva(T1 b, T2 x, T3 p);
  97. template <class T1, class T2, class T3, class ``__Policy``>
  98. ``__sf_result`` ibetac_inva(T1 b, T2 x, T3 p, const ``__Policy``&);
  99. Returns a value /a/ such that: `q = ibetac(a, b, x);`
  100. Requires: /b > 0/, /0 < x < 1/ and /0 <= q <= 1/.
  101. [optional_policy]
  102. template <class T1, class T2, class T3>
  103. ``__sf_result`` ibeta_invb(T1 b, T2 x, T3 p);
  104. template <class T1, class T2, class T3, class ``__Policy``>
  105. ``__sf_result`` ibeta_invb(T1 b, T2 x, T3 p, const ``__Policy``&);
  106. Returns a value /b/ such that: `p = ibeta(a, b, x);`
  107. Requires: /a > 0/, /0 < x < 1/ and /0 <= p <= 1/.
  108. [optional_policy]
  109. template <class T1, class T2, class T3>
  110. ``__sf_result`` ibetac_invb(T1 b, T2 x, T3 p);
  111. template <class T1, class T2, class T3, class ``__Policy``>
  112. ``__sf_result`` ibetac_invb(T1 b, T2 x, T3 p, const ``__Policy``&);
  113. Returns a value /b/ such that: `q = ibetac(a, b, x);`
  114. Requires: /a > 0/, /0 < x < 1/ and /0 <= q <= 1/.
  115. [optional_policy]
  116. [h4 Accuracy]
  117. The accuracy of these functions should closely follow that
  118. of the regular forward incomplete beta functions. However,
  119. note that in some parts of their domain, these functions can
  120. be extremely sensitive to changes in input, particularly when
  121. the argument /p/ (or it's complement /q/) is very close to `0` or `1`.
  122. Comparisons to other libraries are shown below, note that our test data
  123. exercises some rather extreme cases in the incomplete beta function
  124. which many other libraries fail to handle:
  125. [table_ibeta_inv]
  126. [table_ibetac_inv]
  127. [table_ibeta_inva]
  128. [table_ibetac_inva]
  129. [table_ibeta_invb]
  130. [table_ibetac_invb]
  131. [h4 Testing]
  132. There are two sets of tests:
  133. * Basic sanity checks attempt to "round-trip" from
  134. /a, b/ and /x/ to /p/ or /q/ and back again. These tests have quite
  135. generous tolerances: in general both the incomplete beta and its
  136. inverses change so rapidly, that round tripping to more than a couple
  137. of significant digits isn't possible. This is especially true when
  138. /p/ or /q/ is very near one: in this case there isn't enough
  139. "information content" in the input to the inverse function to get
  140. back where you started.
  141. * Accuracy checks using high precision test values. These measure
  142. the accuracy of the result, given exact input values.
  143. [h4 Implementation of ibeta_inv and ibetac_inv]
  144. These two functions share a common implementation.
  145. First an initial approximation to x is computed then the
  146. last few bits are cleaned up using
  147. [@http://en.wikipedia.org/wiki/Simple_rational_approximation Halley iteration].
  148. The iteration limit is set to 1/2 of the number of bits in T, which by experiment is
  149. sufficient to ensure that the inverses are at least as accurate as the normal
  150. incomplete beta functions. Up to 5 iterations may be
  151. required in extreme cases, although normally only one or two are required.
  152. Further, the number of iterations required decreases with increasing /a/ and
  153. /b/ (which generally form the more important use cases).
  154. The initial guesses used for iteration are obtained as follows:
  155. Firstly recall that:
  156. [equation ibeta_inv5]
  157. We may wish to start from either p or q, and to calculate either x or y.
  158. In addition at
  159. any stage we can exchange a for b, p for q, and x for y if it results in a
  160. more manageable problem.
  161. For `a+b >= 5` the initial guess is computed using the methods described in:
  162. Asymptotic Inversion of the Incomplete Beta Function,
  163. by N. M. [@http://homepages.cwi.nl/~nicot/ Temme].
  164. Journal of Computational and Applied Mathematics 41 (1992) 145-157.
  165. The nearly symmetrical case (section 2 of the paper) is used for
  166. [equation ibeta_inv2]
  167. and involves solving the inverse error function first. The method is accurate
  168. to at least 2 decimal digits when [^a = 5] rising to at least 8 digits when
  169. [^a = 10[super 5]].
  170. The general error function case (section 3 of the paper) is used for
  171. [equation ibeta_inv3]
  172. and again expresses the inverse incomplete beta in terms of the
  173. inverse of the error function. The method is accurate to at least
  174. 2 decimal digits when [^a+b = 5] rising to 11 digits when [^a+b = 10[super 5]].
  175. However, when the result is expected to be very small, and when a+b is
  176. also small, then its accuracy tails off, in this case when p[super 1/a] < 0.0025
  177. then it is better to use the following as an initial estimate:
  178. [equation ibeta_inv4]
  179. Finally the for all other cases where `a+b > 5` the method of section
  180. 4 of the paper is used. This expresses the inverse incomplete beta in terms
  181. of the inverse of the incomplete gamma function, and is therefore significantly
  182. more expensive to compute than the other cases. However the method is accurate
  183. to at least 3 decimal digits when [^a = 5] rising to at least 10 digits when
  184. [^a = 10[super 5]]. This method is limited to a > b, and therefore we need to perform
  185. an exchange a for b, p for q and x for y when this is not the case. In addition
  186. when p is close to 1 the method is inaccurate should we actually want y rather
  187. than x as output. Therefore when q is small ([^q[super 1/p] < 10[super -3]]) we use:
  188. [equation ibeta_inv6]
  189. which is both cheaper to compute than the full method, and a more accurate
  190. estimate on q.
  191. When a and b are both small there is a distinct lack of information in the
  192. literature on how to proceed. I am extremely grateful to Prof Nico Temme
  193. who provided the following information with a great deal of patience and
  194. explanation on his part. Any errors that follow are entirely my own, and not
  195. Prof Temme's.
  196. When a and b are both less than 1, then there is a point of inflection in
  197. the incomplete beta at point `xs = (1 - a) / (2 - a - b)`. Therefore if
  198. [^p > I[sub x](a,b)] we swap a for b, p for q and x for y, so that now we always
  199. look for a point x below the point of inflection `xs`, and on a convex curve.
  200. An initial estimate for x is made with:
  201. [equation ibeta_inv7]
  202. which is provably below the true value for x:
  203. [@http://en.wikipedia.org/wiki/Newton%27s_method Newton iteration] will
  204. therefore smoothly converge on x without problems caused by overshooting etc.
  205. When a and b are both greater than 1, but a+b is too small to use the other
  206. methods mentioned above, we proceed as follows. Observe that there is a point
  207. of inflection in the incomplete beta at `xs = (1 - a) / (2 - a - b)`. Therefore
  208. if [^p > I[sub x](a,b)] we swap a for b, p for q and x for y, so that now we always
  209. look for a point x below the point of inflection `xs`, and on a concave curve.
  210. An initial estimate for x is made with:
  211. [equation ibeta_inv4]
  212. which can be improved somewhat to:
  213. [equation ibeta_inv1]
  214. when b and x are both small (I've used b < a and x < 0.2). This
  215. actually under-estimates x, which drops us on the wrong side of x for Newton
  216. iteration to converge monotonically. However, use of higher derivatives
  217. and Halley iteration keeps everything under control.
  218. The final case to be considered if when one of a and b is less than or equal
  219. to 1, and the other greater that 1. Here, if b < a we swap a for b, p for q
  220. and x for y. Now the curve of the incomplete beta is convex with no points
  221. of inflection in [0,1]. For small p, x can be estimated using
  222. [equation ibeta_inv4]
  223. which under-estimates x, and drops us on the right side of the true value
  224. for Newton iteration to converge monotonically. However, when p is large
  225. this can quite badly underestimate x. This is especially an issue when we
  226. really want to find y, in which case this method can be an arbitrary number
  227. of order of magnitudes out, leading to very poor convergence during iteration.
  228. Things can be improved by considering the incomplete beta as a distorted
  229. quarter circle, and estimating y from:
  230. [equation ibeta_inv8]
  231. This doesn't guarantee that we will drop in on the right side of x for
  232. monotonic convergence, but it does get us close enough that Halley iteration
  233. rapidly converges on the true value.
  234. [h4 Implementation of inverses on the a and b parameters]
  235. These four functions share a common implementation.
  236. First an initial approximation is computed for /a/ or /b/:
  237. where possible this uses a Cornish-Fisher expansion for the
  238. negative binomial distribution to get within around 1 of the
  239. result. However, when /a/ or /b/ are very small the Cornish Fisher
  240. expansion is not usable, in this case the initial approximation
  241. is chosen so that
  242. I[sub x](a, b) is near the middle of the range [0,1].
  243. This initial guess is then
  244. used as a starting value for a generic root finding algorithm. The
  245. algorithm converges rapidly on the root once it has been
  246. bracketed, but bracketing the root may take several iterations.
  247. A better initial approximation for /a/ or /b/ would improve these
  248. functions quite substantially: currently 10-20 incomplete beta
  249. function invocations are required to find the root.
  250. [endsect][/section:ibeta_inv_function The Incomplete Beta Function Inverses]
  251. [/
  252. Copyright 2006 John Maddock and Paul A. Bristow.
  253. Distributed under the Boost Software License, Version 1.0.
  254. (See accompanying file LICENSE_1_0.txt or copy at
  255. http://www.boost.org/LICENSE_1_0.txt).
  256. ]