annotate DEPENDENCIES/generic/include/boost/math/distributions/detail/hypergeometric_quantile.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2008 John Maddock
Chris@16 2 //
Chris@16 3 // Use, modification and distribution are subject to the
Chris@16 4 // Boost Software License, Version 1.0.
Chris@16 5 // (See accompanying file LICENSE_1_0.txt
Chris@16 6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP
Chris@16 9 #define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP
Chris@16 10
Chris@16 11 #include <boost/math/policies/error_handling.hpp>
Chris@16 12 #include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
Chris@16 13
Chris@16 14 namespace boost{ namespace math{ namespace detail{
Chris@16 15
Chris@16 16 template <class T>
Chris@16 17 inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_down>&)
Chris@16 18 {
Chris@16 19 if((p < cum * fudge_factor) && (x != lbound))
Chris@16 20 {
Chris@16 21 BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
Chris@16 22 return --x;
Chris@16 23 }
Chris@16 24 return x;
Chris@16 25 }
Chris@16 26
Chris@16 27 template <class T>
Chris@16 28 inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile<policies::integer_round_up>&)
Chris@16 29 {
Chris@16 30 if((cum < p * fudge_factor) && (x != ubound))
Chris@16 31 {
Chris@16 32 BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
Chris@16 33 return ++x;
Chris@16 34 }
Chris@16 35 return x;
Chris@16 36 }
Chris@16 37
Chris@16 38 template <class T>
Chris@16 39 inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_inwards>&)
Chris@16 40 {
Chris@16 41 if(p >= 0.5)
Chris@16 42 return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
Chris@16 43 return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
Chris@16 44 }
Chris@16 45
Chris@16 46 template <class T>
Chris@16 47 inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_outwards>&)
Chris@16 48 {
Chris@16 49 if(p >= 0.5)
Chris@16 50 return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
Chris@16 51 return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
Chris@16 52 }
Chris@16 53
Chris@16 54 template <class T>
Chris@16 55 inline unsigned round_x_from_p(unsigned x, T /*p*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_nearest>&)
Chris@16 56 {
Chris@16 57 return x;
Chris@16 58 }
Chris@16 59
Chris@16 60 template <class T>
Chris@16 61 inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_down>&)
Chris@16 62 {
Chris@16 63 if((q * fudge_factor > cum) && (x != lbound))
Chris@16 64 {
Chris@16 65 BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
Chris@16 66 return --x;
Chris@16 67 }
Chris@16 68 return x;
Chris@16 69 }
Chris@16 70
Chris@16 71 template <class T>
Chris@16 72 inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile<policies::integer_round_up>&)
Chris@16 73 {
Chris@16 74 if((q < cum * fudge_factor) && (x != ubound))
Chris@16 75 {
Chris@16 76 BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
Chris@16 77 return ++x;
Chris@16 78 }
Chris@16 79 return x;
Chris@16 80 }
Chris@16 81
Chris@16 82 template <class T>
Chris@16 83 inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_inwards>&)
Chris@16 84 {
Chris@16 85 if(q < 0.5)
Chris@16 86 return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
Chris@16 87 return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
Chris@16 88 }
Chris@16 89
Chris@16 90 template <class T>
Chris@16 91 inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile<policies::integer_round_outwards>&)
Chris@16 92 {
Chris@16 93 if(q >= 0.5)
Chris@16 94 return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
Chris@16 95 return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
Chris@16 96 }
Chris@16 97
Chris@16 98 template <class T>
Chris@16 99 inline unsigned round_x_from_q(unsigned x, T /*q*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile<policies::integer_round_nearest>&)
Chris@16 100 {
Chris@16 101 return x;
Chris@16 102 }
Chris@16 103
Chris@16 104 template <class T, class Policy>
Chris@16 105 unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned N, const Policy& pol)
Chris@16 106 {
Chris@16 107 #ifdef BOOST_MSVC
Chris@16 108 # pragma warning(push)
Chris@16 109 # pragma warning(disable:4267)
Chris@16 110 #endif
Chris@16 111 typedef typename Policy::discrete_quantile_type discrete_quantile_type;
Chris@16 112 BOOST_MATH_STD_USING
Chris@16 113 BOOST_FPU_EXCEPTION_GUARD
Chris@16 114 T result;
Chris@16 115 T fudge_factor = 1 + tools::epsilon<T>() * ((N <= boost::math::prime(boost::math::max_prime - 1)) ? 50 : 2 * N);
Chris@16 116 unsigned base = static_cast<unsigned>((std::max)(0, (int)(n + r) - (int)(N)));
Chris@16 117 unsigned lim = (std::min)(r, n);
Chris@16 118
Chris@16 119 BOOST_MATH_INSTRUMENT_VARIABLE(p);
Chris@16 120 BOOST_MATH_INSTRUMENT_VARIABLE(q);
Chris@16 121 BOOST_MATH_INSTRUMENT_VARIABLE(r);
Chris@16 122 BOOST_MATH_INSTRUMENT_VARIABLE(n);
Chris@16 123 BOOST_MATH_INSTRUMENT_VARIABLE(N);
Chris@16 124 BOOST_MATH_INSTRUMENT_VARIABLE(fudge_factor);
Chris@16 125 BOOST_MATH_INSTRUMENT_VARIABLE(base);
Chris@16 126 BOOST_MATH_INSTRUMENT_VARIABLE(lim);
Chris@16 127
Chris@16 128 if(p <= 0.5)
Chris@16 129 {
Chris@16 130 unsigned x = base;
Chris@16 131 result = hypergeometric_pdf<T>(x, r, n, N, pol);
Chris@16 132 T diff = result;
Chris@16 133 while(result < p)
Chris@16 134 {
Chris@16 135 diff = (diff > tools::min_value<T>() * 8)
Chris@16 136 ? T(n - x) * T(r - x) * diff / (T(x + 1) * T(N + x + 1 - n - r))
Chris@16 137 : hypergeometric_pdf<T>(x + 1, r, n, N, pol);
Chris@16 138 if(result + diff / 2 > p)
Chris@16 139 break;
Chris@16 140 ++x;
Chris@16 141 result += diff;
Chris@16 142 #ifdef BOOST_MATH_INSTRUMENT
Chris@16 143 if(diff != 0)
Chris@16 144 {
Chris@16 145 BOOST_MATH_INSTRUMENT_VARIABLE(x);
Chris@16 146 BOOST_MATH_INSTRUMENT_VARIABLE(diff);
Chris@16 147 BOOST_MATH_INSTRUMENT_VARIABLE(result);
Chris@16 148 }
Chris@16 149 #endif
Chris@16 150 }
Chris@16 151 return round_x_from_p(x, p, result, fudge_factor, base, lim, discrete_quantile_type());
Chris@16 152 }
Chris@16 153 else
Chris@16 154 {
Chris@16 155 unsigned x = lim;
Chris@16 156 result = 0;
Chris@16 157 T diff = hypergeometric_pdf<T>(x, r, n, N, pol);
Chris@16 158 while(result + diff / 2 < q)
Chris@16 159 {
Chris@16 160 result += diff;
Chris@16 161 diff = (diff > tools::min_value<T>() * 8)
Chris@16 162 ? x * T(N + x - n - r) * diff / (T(1 + n - x) * T(1 + r - x))
Chris@16 163 : hypergeometric_pdf<T>(x - 1, r, n, N, pol);
Chris@16 164 --x;
Chris@16 165 #ifdef BOOST_MATH_INSTRUMENT
Chris@16 166 if(diff != 0)
Chris@16 167 {
Chris@16 168 BOOST_MATH_INSTRUMENT_VARIABLE(x);
Chris@16 169 BOOST_MATH_INSTRUMENT_VARIABLE(diff);
Chris@16 170 BOOST_MATH_INSTRUMENT_VARIABLE(result);
Chris@16 171 }
Chris@16 172 #endif
Chris@16 173 }
Chris@16 174 return round_x_from_q(x, q, result, fudge_factor, base, lim, discrete_quantile_type());
Chris@16 175 }
Chris@16 176 #ifdef BOOST_MSVC
Chris@16 177 # pragma warning(pop)
Chris@16 178 #endif
Chris@16 179 }
Chris@16 180
Chris@16 181 template <class T, class Policy>
Chris@16 182 inline unsigned hypergeometric_quantile(T p, T q, unsigned r, unsigned n, unsigned N, const Policy&)
Chris@16 183 {
Chris@16 184 BOOST_FPU_EXCEPTION_GUARD
Chris@16 185 typedef typename tools::promote_args<T>::type result_type;
Chris@16 186 typedef typename policies::evaluation<result_type, Policy>::type value_type;
Chris@16 187 typedef typename policies::normalise<
Chris@16 188 Policy,
Chris@16 189 policies::promote_float<false>,
Chris@16 190 policies::promote_double<false>,
Chris@16 191 policies::assert_undefined<> >::type forwarding_policy;
Chris@16 192
Chris@16 193 return detail::hypergeometric_quantile_imp<value_type>(p, q, r, n, N, forwarding_policy());
Chris@16 194 }
Chris@16 195
Chris@16 196 }}} // namespaces
Chris@16 197
Chris@16 198 #endif
Chris@16 199