Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:42

0001 // boost\math\special_functions\negative_binomial.hpp
0002 
0003 // Copyright Paul A. Bristow 2007.
0004 // Copyright John Maddock 2007.
0005 
0006 // Use, modification and distribution are subject to the
0007 // Boost Software License, Version 1.0.
0008 // (See accompanying file LICENSE_1_0.txt
0009 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 // http://en.wikipedia.org/wiki/negative_binomial_distribution
0012 // http://mathworld.wolfram.com/NegativeBinomialDistribution.html
0013 // http://documents.wolfram.com/teachersedition/Teacher/Statistics/DiscreteDistributions.html
0014 
0015 // The negative binomial distribution NegativeBinomialDistribution[n, p]
0016 // is the distribution of the number (k) of failures that occur in a sequence of trials before
0017 // r successes have occurred, where the probability of success in each trial is p.
0018 
0019 // In a sequence of Bernoulli trials or events
0020 // (independent, yes or no, succeed or fail) with success_fraction probability p,
0021 // negative_binomial is the probability that k or fewer failures
0022 // precede the r th trial's success.
0023 // random variable k is the number of failures (NOT the probability).
0024 
0025 // Negative_binomial distribution is a discrete probability distribution.
0026 // But note that the negative binomial distribution
0027 // (like others including the binomial, Poisson & Bernoulli)
0028 // is strictly defined as a discrete function: only integral values of k are envisaged.
0029 // However because of the method of calculation using a continuous gamma function,
0030 // it is convenient to treat it as if a continuous function,
0031 // and permit non-integral values of k.
0032 
0033 // However, by default the policy is to use discrete_quantile_policy.
0034 
0035 // To enforce the strict mathematical model, users should use conversion
0036 // on k outside this function to ensure that k is integral.
0037 
0038 // MATHCAD cumulative negative binomial pnbinom(k, n, p)
0039 
0040 // Implementation note: much greater speed, and perhaps greater accuracy,
0041 // might be achieved for extreme values by using a normal approximation.
0042 // This is NOT been tested or implemented.
0043 
0044 #ifndef BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
0045 #define BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
0046 
0047 #include <boost/math/distributions/fwd.hpp>
0048 #include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x) == Ix(a, b).
0049 #include <boost/math/distributions/complement.hpp> // complement.
0050 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks domain_error & logic_error.
0051 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
0052 #include <boost/math/tools/roots.hpp> // for root finding.
0053 #include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
0054 
0055 #include <limits> // using std::numeric_limits;
0056 #include <utility>
0057 
0058 #if defined (BOOST_MSVC)
0059 #  pragma warning(push)
0060 // This believed not now necessary, so commented out.
0061 //#  pragma warning(disable: 4702) // unreachable code.
0062 // in domain_error_imp in error_handling.
0063 #endif
0064 
0065 namespace boost
0066 {
0067   namespace math
0068   {
0069     namespace negative_binomial_detail
0070     {
0071       // Common error checking routines for negative binomial distribution functions:
0072       template <class RealType, class Policy>
0073       inline bool check_successes(const char* function, const RealType& r, RealType* result, const Policy& pol)
0074       {
0075         if( !(boost::math::isfinite)(r) || (r <= 0) )
0076         {
0077           *result = policies::raise_domain_error<RealType>(
0078             function,
0079             "Number of successes argument is %1%, but must be > 0 !", r, pol);
0080           return false;
0081         }
0082         return true;
0083       }
0084       template <class RealType, class Policy>
0085       inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol)
0086       {
0087         if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) )
0088         {
0089           *result = policies::raise_domain_error<RealType>(
0090             function,
0091             "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
0092           return false;
0093         }
0094         return true;
0095       }
0096       template <class RealType, class Policy>
0097       inline bool check_dist(const char* function, const RealType& r, const RealType& p, RealType* result, const Policy& pol)
0098       {
0099         return check_success_fraction(function, p, result, pol)
0100           && check_successes(function, r, result, pol);
0101       }
0102       template <class RealType, class Policy>
0103       inline bool check_dist_and_k(const char* function, const RealType& r, const RealType& p, RealType k, RealType* result, const Policy& pol)
0104       {
0105         if(check_dist(function, r, p, result, pol) == false)
0106         {
0107           return false;
0108         }
0109         if( !(boost::math::isfinite)(k) || (k < 0) )
0110         { // Check k failures.
0111           *result = policies::raise_domain_error<RealType>(
0112             function,
0113             "Number of failures argument is %1%, but must be >= 0 !", k, pol);
0114           return false;
0115         }
0116         return true;
0117       } // Check_dist_and_k
0118 
0119       template <class RealType, class Policy>
0120       inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol)
0121       {
0122         if((check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false)
0123         {
0124           return false;
0125         }
0126         return true;
0127       } // check_dist_and_prob
0128     } //  namespace negative_binomial_detail
0129 
0130     template <class RealType = double, class Policy = policies::policy<> >
0131     class negative_binomial_distribution
0132     {
0133     public:
0134       typedef RealType value_type;
0135       typedef Policy policy_type;
0136 
0137       negative_binomial_distribution(RealType r, RealType p) : m_r(r), m_p(p)
0138       { // Constructor.
0139         RealType result;
0140         negative_binomial_detail::check_dist(
0141           "negative_binomial_distribution<%1%>::negative_binomial_distribution",
0142           m_r, // Check successes r > 0.
0143           m_p, // Check success_fraction 0 <= p <= 1.
0144           &result, Policy());
0145       } // negative_binomial_distribution constructor.
0146 
0147       // Private data getter class member functions.
0148       RealType success_fraction() const
0149       { // Probability of success as fraction in range 0 to 1.
0150         return m_p;
0151       }
0152       RealType successes() const
0153       { // Total number of successes r.
0154         return m_r;
0155       }
0156 
0157       static RealType find_lower_bound_on_p(
0158         RealType trials,
0159         RealType successes,
0160         RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
0161       {
0162         static const char* function = "boost::math::negative_binomial<%1%>::find_lower_bound_on_p";
0163         RealType result = 0;  // of error checks.
0164         RealType failures = trials - successes;
0165         if(false == detail::check_probability(function, alpha, &result, Policy())
0166           && negative_binomial_detail::check_dist_and_k(
0167           function, successes, RealType(0), failures, &result, Policy()))
0168         {
0169           return result;
0170         }
0171         // Use complement ibeta_inv function for lower bound.
0172         // This is adapted from the corresponding binomial formula
0173         // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
0174         // This is a Clopper-Pearson interval, and may be overly conservative,
0175         // see also "A Simple Improved Inferential Method for Some
0176         // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
0177         // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
0178         //
0179         return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(nullptr), Policy());
0180       } // find_lower_bound_on_p
0181 
0182       static RealType find_upper_bound_on_p(
0183         RealType trials,
0184         RealType successes,
0185         RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
0186       {
0187         static const char* function = "boost::math::negative_binomial<%1%>::find_upper_bound_on_p";
0188         RealType result = 0;  // of error checks.
0189         RealType failures = trials - successes;
0190         if(false == negative_binomial_detail::check_dist_and_k(
0191           function, successes, RealType(0), failures, &result, Policy())
0192           && detail::check_probability(function, alpha, &result, Policy()))
0193         {
0194           return result;
0195         }
0196         if(failures == 0)
0197            return 1;
0198         // Use complement ibetac_inv function for upper bound.
0199         // Note adjusted failures value: *not* failures+1 as usual.
0200         // This is adapted from the corresponding binomial formula
0201         // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
0202         // This is a Clopper-Pearson interval, and may be overly conservative,
0203         // see also "A Simple Improved Inferential Method for Some
0204         // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
0205         // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
0206         //
0207         return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(nullptr), Policy());
0208       } // find_upper_bound_on_p
0209 
0210       // Estimate number of trials :
0211       // "How many trials do I need to be P% sure of seeing k or fewer failures?"
0212 
0213       static RealType find_minimum_number_of_trials(
0214         RealType k,     // number of failures (k >= 0).
0215         RealType p,     // success fraction 0 <= p <= 1.
0216         RealType alpha) // risk level threshold 0 <= alpha <= 1.
0217       {
0218         static const char* function = "boost::math::negative_binomial<%1%>::find_minimum_number_of_trials";
0219         // Error checks:
0220         RealType result = 0;
0221         if(false == negative_binomial_detail::check_dist_and_k(
0222           function, RealType(1), p, k, &result, Policy())
0223           && detail::check_probability(function, alpha, &result, Policy()))
0224         { return result; }
0225 
0226         result = ibeta_inva(k + 1, p, alpha, Policy());  // returns n - k
0227         return result + k;
0228       } // RealType find_number_of_failures
0229 
0230       static RealType find_maximum_number_of_trials(
0231         RealType k,     // number of failures (k >= 0).
0232         RealType p,     // success fraction 0 <= p <= 1.
0233         RealType alpha) // risk level threshold 0 <= alpha <= 1.
0234       {
0235         static const char* function = "boost::math::negative_binomial<%1%>::find_maximum_number_of_trials";
0236         // Error checks:
0237         RealType result = 0;
0238         if(false == negative_binomial_detail::check_dist_and_k(
0239           function, RealType(1), p, k, &result, Policy())
0240           &&  detail::check_probability(function, alpha, &result, Policy()))
0241         { return result; }
0242 
0243         result = ibetac_inva(k + 1, p, alpha, Policy());  // returns n - k
0244         return result + k;
0245       } // RealType find_number_of_trials complemented
0246 
0247     private:
0248       RealType m_r; // successes.
0249       RealType m_p; // success_fraction
0250     }; // template <class RealType, class Policy> class negative_binomial_distribution
0251 
0252     typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
0253 
0254     #ifdef __cpp_deduction_guides
0255     template <class RealType>
0256     negative_binomial_distribution(RealType,RealType)->negative_binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
0257     #endif
0258 
0259     template <class RealType, class Policy>
0260     inline const std::pair<RealType, RealType> range(const negative_binomial_distribution<RealType, Policy>& /* dist */)
0261     { // Range of permissible values for random variable k.
0262        using boost::math::tools::max_value;
0263        return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
0264     }
0265 
0266     template <class RealType, class Policy>
0267     inline const std::pair<RealType, RealType> support(const negative_binomial_distribution<RealType, Policy>& /* dist */)
0268     { // Range of supported values for random variable k.
0269        // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
0270        using boost::math::tools::max_value;
0271        return std::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>()); // max_integer?
0272     }
0273 
0274     template <class RealType, class Policy>
0275     inline RealType mean(const negative_binomial_distribution<RealType, Policy>& dist)
0276     { // Mean of Negative Binomial distribution = r(1-p)/p.
0277       return dist.successes() * (1 - dist.success_fraction() ) / dist.success_fraction();
0278     } // mean
0279 
0280     //template <class RealType, class Policy>
0281     //inline RealType median(const negative_binomial_distribution<RealType, Policy>& dist)
0282     //{ // Median of negative_binomial_distribution is not defined.
0283     //  return policies::raise_domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
0284     //} // median
0285     // Now implemented via quantile(half) in derived accessors.
0286 
0287     template <class RealType, class Policy>
0288     inline RealType mode(const negative_binomial_distribution<RealType, Policy>& dist)
0289     { // Mode of Negative Binomial distribution = floor[(r-1) * (1 - p)/p]
0290       BOOST_MATH_STD_USING // ADL of std functions.
0291       return floor((dist.successes() -1) * (1 - dist.success_fraction()) / dist.success_fraction());
0292     } // mode
0293 
0294     template <class RealType, class Policy>
0295     inline RealType skewness(const negative_binomial_distribution<RealType, Policy>& dist)
0296     { // skewness of Negative Binomial distribution = 2-p / (sqrt(r(1-p))
0297       BOOST_MATH_STD_USING // ADL of std functions.
0298       RealType p = dist.success_fraction();
0299       RealType r = dist.successes();
0300 
0301       return (2 - p) /
0302         sqrt(r * (1 - p));
0303     } // skewness
0304 
0305     template <class RealType, class Policy>
0306     inline RealType kurtosis(const negative_binomial_distribution<RealType, Policy>& dist)
0307     { // kurtosis of Negative Binomial distribution
0308       // http://en.wikipedia.org/wiki/Negative_binomial is kurtosis_excess so add 3
0309       RealType p = dist.success_fraction();
0310       RealType r = dist.successes();
0311       return 3 + (6 / r) + ((p * p) / (r * (1 - p)));
0312     } // kurtosis
0313 
0314      template <class RealType, class Policy>
0315     inline RealType kurtosis_excess(const negative_binomial_distribution<RealType, Policy>& dist)
0316     { // kurtosis excess of Negative Binomial distribution
0317       // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess
0318       RealType p = dist.success_fraction();
0319       RealType r = dist.successes();
0320       return (6 - p * (6-p)) / (r * (1-p));
0321     } // kurtosis_excess
0322 
0323     template <class RealType, class Policy>
0324     inline RealType variance(const negative_binomial_distribution<RealType, Policy>& dist)
0325     { // Variance of Binomial distribution = r (1-p) / p^2.
0326       return  dist.successes() * (1 - dist.success_fraction())
0327         / (dist.success_fraction() * dist.success_fraction());
0328     } // variance
0329 
0330     // RealType standard_deviation(const negative_binomial_distribution<RealType, Policy>& dist)
0331     // standard_deviation provided by derived accessors.
0332     // RealType hazard(const negative_binomial_distribution<RealType, Policy>& dist)
0333     // hazard of Negative Binomial distribution provided by derived accessors.
0334     // RealType chf(const negative_binomial_distribution<RealType, Policy>& dist)
0335     // chf of Negative Binomial distribution provided by derived accessors.
0336 
0337     template <class RealType, class Policy>
0338     inline RealType pdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
0339     { // Probability Density/Mass Function.
0340       BOOST_FPU_EXCEPTION_GUARD
0341 
0342       static const char* function = "boost::math::pdf(const negative_binomial_distribution<%1%>&, %1%)";
0343 
0344       RealType r = dist.successes();
0345       RealType p = dist.success_fraction();
0346       RealType result = 0;
0347       if(false == negative_binomial_detail::check_dist_and_k(
0348         function,
0349         r,
0350         dist.success_fraction(),
0351         k,
0352         &result, Policy()))
0353       {
0354         return result;
0355       }
0356 
0357       result = (p/(r + k)) * ibeta_derivative(r, static_cast<RealType>(k+1), p, Policy());
0358       // Equivalent to:
0359       // return exp(lgamma(r + k) - lgamma(r) - lgamma(k+1)) * pow(p, r) * pow((1-p), k);
0360       return result;
0361     } // negative_binomial_pdf
0362 
0363     template <class RealType, class Policy>
0364     inline RealType cdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
0365     { // Cumulative Distribution Function of Negative Binomial.
0366       static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
0367       using boost::math::ibeta; // Regularized incomplete beta function.
0368       // k argument may be integral, signed, or unsigned, or floating point.
0369       // If necessary, it has already been promoted from an integral type.
0370       RealType p = dist.success_fraction();
0371       RealType r = dist.successes();
0372       // Error check:
0373       RealType result = 0;
0374       if(false == negative_binomial_detail::check_dist_and_k(
0375         function,
0376         r,
0377         dist.success_fraction(),
0378         k,
0379         &result, Policy()))
0380       {
0381         return result;
0382       }
0383 
0384       RealType probability = ibeta(r, static_cast<RealType>(k+1), p, Policy());
0385       // Ip(r, k+1) = ibeta(r, k+1, p)
0386       return probability;
0387     } // cdf Cumulative Distribution Function Negative Binomial.
0388 
0389       template <class RealType, class Policy>
0390       inline RealType cdf(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
0391       { // Complemented Cumulative Distribution Function Negative Binomial.
0392 
0393       static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
0394       using boost::math::ibetac; // Regularized incomplete beta function complement.
0395       // k argument may be integral, signed, or unsigned, or floating point.
0396       // If necessary, it has already been promoted from an integral type.
0397       RealType const& k = c.param;
0398       negative_binomial_distribution<RealType, Policy> const& dist = c.dist;
0399       RealType p = dist.success_fraction();
0400       RealType r = dist.successes();
0401       // Error check:
0402       RealType result = 0;
0403       if(false == negative_binomial_detail::check_dist_and_k(
0404         function,
0405         r,
0406         p,
0407         k,
0408         &result, Policy()))
0409       {
0410         return result;
0411       }
0412       // Calculate cdf negative binomial using the incomplete beta function.
0413       // Use of ibeta here prevents cancellation errors in calculating
0414       // 1-p if p is very small, perhaps smaller than machine epsilon.
0415       // Ip(k+1, r) = ibetac(r, k+1, p)
0416       // constrain_probability here?
0417      RealType probability = ibetac(r, static_cast<RealType>(k+1), p, Policy());
0418       // Numerical errors might cause probability to be slightly outside the range < 0 or > 1.
0419       // This might cause trouble downstream, so warn, possibly throw exception, but constrain to the limits.
0420       return probability;
0421     } // cdf Cumulative Distribution Function Negative Binomial.
0422 
0423     template <class RealType, class Policy>
0424     inline RealType quantile(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& P)
0425     { // Quantile, percentile/100 or Percent Point Negative Binomial function.
0426       // Return the number of expected failures k for a given probability p.
0427 
0428       // Inverse cumulative Distribution Function or Quantile (percentile / 100) of negative_binomial Probability.
0429       // MAthCAD pnbinom return smallest k such that negative_binomial(k, n, p) >= probability.
0430       // k argument may be integral, signed, or unsigned, or floating point.
0431       // BUT Cephes/CodeCogs says: finds argument p (0 to 1) such that cdf(k, n, p) = y
0432       static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
0433       BOOST_MATH_STD_USING // ADL of std functions.
0434 
0435       RealType p = dist.success_fraction();
0436       RealType r = dist.successes();
0437       // Check dist and P.
0438       RealType result = 0;
0439       if(false == negative_binomial_detail::check_dist_and_prob
0440         (function, r, p, P, &result, Policy()))
0441       {
0442         return result;
0443       }
0444 
0445       // Special cases.
0446       if (P == 1)
0447       {  // Would need +infinity failures for total confidence.
0448         result = policies::raise_overflow_error<RealType>(
0449             function,
0450             "Probability argument is 1, which implies infinite failures !", Policy());
0451         return result;
0452        // usually means return +std::numeric_limits<RealType>::infinity();
0453        // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
0454       }
0455       if (P == 0)
0456       { // No failures are expected if P = 0.
0457         return 0; // Total trials will be just dist.successes.
0458       }
0459       if (P <= pow(dist.success_fraction(), dist.successes()))
0460       { // p <= pdf(dist, 0) == cdf(dist, 0)
0461         return 0;
0462       }
0463       if(p == 0)
0464       {  // Would need +infinity failures for total confidence.
0465          result = policies::raise_overflow_error<RealType>(
0466             function,
0467             "Success fraction is 0, which implies infinite failures !", Policy());
0468          return result;
0469          // usually means return +std::numeric_limits<RealType>::infinity();
0470          // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
0471       }
0472       /*
0473       // Calculate quantile of negative_binomial using the inverse incomplete beta function.
0474       using boost::math::ibeta_invb;
0475       return ibeta_invb(r, p, P, Policy()) - 1; //
0476       */
0477       RealType guess = 0;
0478       RealType factor = 5;
0479       if(r * r * r * P * p > 0.005)
0480          guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), P, RealType(1-P), Policy());
0481 
0482       if(guess < 10)
0483       {
0484          //
0485          // Cornish-Fisher Negative binomial approximation not accurate in this area:
0486          //
0487          guess = (std::min)(RealType(r * 2), RealType(10));
0488       }
0489       else
0490          factor = (1-P < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
0491       BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
0492       //
0493       // Max iterations permitted:
0494       //
0495       std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
0496       typedef typename Policy::discrete_quantile_type discrete_type;
0497       return detail::inverse_discrete_quantile(
0498          dist,
0499          P,
0500          false,
0501          guess,
0502          factor,
0503          RealType(1),
0504          discrete_type(),
0505          max_iter);
0506     } // RealType quantile(const negative_binomial_distribution dist, p)
0507 
0508     template <class RealType, class Policy>
0509     inline RealType quantile(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
0510     {  // Quantile or Percent Point Binomial function.
0511        // Return the number of expected failures k for a given
0512        // complement of the probability Q = 1 - P.
0513        static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
0514        BOOST_MATH_STD_USING
0515 
0516        // Error checks:
0517        RealType Q = c.param;
0518        const negative_binomial_distribution<RealType, Policy>& dist = c.dist;
0519        RealType p = dist.success_fraction();
0520        RealType r = dist.successes();
0521        RealType result = 0;
0522        if(false == negative_binomial_detail::check_dist_and_prob(
0523           function,
0524           r,
0525           p,
0526           Q,
0527           &result, Policy()))
0528        {
0529           return result;
0530        }
0531 
0532        // Special cases:
0533        //
0534        if(Q == 1)
0535        {  // There may actually be no answer to this question,
0536           // since the probability of zero failures may be non-zero,
0537           return 0; // but zero is the best we can do:
0538        }
0539        if(Q == 0)
0540        {  // Probability 1 - Q  == 1 so infinite failures to achieve certainty.
0541           // Would need +infinity failures for total confidence.
0542           result = policies::raise_overflow_error<RealType>(
0543              function,
0544              "Probability argument complement is 0, which implies infinite failures !", Policy());
0545           return result;
0546           // usually means return +std::numeric_limits<RealType>::infinity();
0547           // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
0548        }
0549        if (-Q <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy()))
0550        {  // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
0551           return 0; //
0552        }
0553        if(p == 0)
0554        {  // Success fraction is 0 so infinite failures to achieve certainty.
0555           // Would need +infinity failures for total confidence.
0556           result = policies::raise_overflow_error<RealType>(
0557              function,
0558              "Success fraction is 0, which implies infinite failures !", Policy());
0559           return result;
0560           // usually means return +std::numeric_limits<RealType>::infinity();
0561           // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
0562        }
0563        //return ibetac_invb(r, p, Q, Policy()) -1;
0564        RealType guess = 0;
0565        RealType factor = 5;
0566        if(r * r * r * (1-Q) * p > 0.005)
0567           guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), RealType(1-Q), Q, Policy());
0568 
0569        if(guess < 10)
0570        {
0571           //
0572           // Cornish-Fisher Negative binomial approximation not accurate in this area:
0573           //
0574           guess = (std::min)(RealType(r * 2), RealType(10));
0575        }
0576        else
0577           factor = (Q < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
0578        BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
0579        //
0580        // Max iterations permitted:
0581        //
0582        std::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
0583        typedef typename Policy::discrete_quantile_type discrete_type;
0584        return detail::inverse_discrete_quantile(
0585           dist,
0586           Q,
0587           true,
0588           guess,
0589           factor,
0590           RealType(1),
0591           discrete_type(),
0592           max_iter);
0593     } // quantile complement
0594 
0595  } // namespace math
0596 } // namespace boost
0597 
0598 // This include must be at the end, *after* the accessors
0599 // for this distribution have been defined, in order to
0600 // keep compilers that support two-phase lookup happy.
0601 #include <boost/math/distributions/detail/derived_accessors.hpp>
0602 
0603 #if defined (BOOST_MSVC)
0604 # pragma warning(pop)
0605 #endif
0606 
0607 #endif // BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP