1 // boost\math\special_functions\negative_binomial.hpp
2 
3 // Copyright Paul A. Bristow 2007.
4 // Copyright John Maddock 2007.
5 
6 // Use, modification and distribution are subject to the
7 // Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE_1_0.txt
9 // or copy at http://www.boost.org/LICENSE_1_0.txt)
10 
11 // http://en.wikipedia.org/wiki/negative_binomial_distribution
12 // http://mathworld.wolfram.com/NegativeBinomialDistribution.html
13 // http://documents.wolfram.com/teachersedition/Teacher/Statistics/DiscreteDistributions.html
14 
15 // The negative binomial distribution NegativeBinomialDistribution[n, p]
16 // is the distribution of the number (k) of failures that occur in a sequence of trials before
17 // r successes have occurred, where the probability of success in each trial is p.
18 
19 // In a sequence of Bernoulli trials or events
20 // (independent, yes or no, succeed or fail) with success_fraction probability p,
21 // negative_binomial is the probability that k or fewer failures
22 // preceed the r th trial's success.
23 // random variable k is the number of failures (NOT the probability).
24 
25 // Negative_binomial distribution is a discrete probability distribution.
26 // But note that the negative binomial distribution
27 // (like others including the binomial, Poisson & Bernoulli)
28 // is strictly defined as a discrete function: only integral values of k are envisaged.
29 // However because of the method of calculation using a continuous gamma function,
30 // it is convenient to treat it as if a continous function,
31 // and permit non-integral values of k.
32 
33 // However, by default the policy is to use discrete_quantile_policy.
34 
35 // To enforce the strict mathematical model, users should use conversion
36 // on k outside this function to ensure that k is integral.
37 
38 // MATHCAD cumulative negative binomial pnbinom(k, n, p)
39 
40 // Implementation note: much greater speed, and perhaps greater accuracy,
41 // might be achieved for extreme values by using a normal approximation.
42 // This is NOT been tested or implemented.
43 
44 #ifndef BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
45 #define BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
46 
47 #include <boost/math/distributions/fwd.hpp>
48 #include <boost/math/special_functions/beta.hpp> // for ibeta(a, b, x) == Ix(a, b).
49 #include <boost/math/distributions/complement.hpp> // complement.
50 #include <boost/math/distributions/detail/common_error_handling.hpp> // error checks domain_error & logic_error.
51 #include <boost/math/special_functions/fpclassify.hpp> // isnan.
52 #include <boost/math/tools/roots.hpp> // for root finding.
53 #include <boost/math/distributions/detail/inv_discrete_quantile.hpp>
54 
55 #include <boost/type_traits/is_floating_point.hpp>
56 #include <boost/type_traits/is_integral.hpp>
57 #include <boost/type_traits/is_same.hpp>
58 #include <boost/mpl/if.hpp>
59 
60 #include <limits> // using std::numeric_limits;
61 #include <utility>
62 
63 #if defined (BOOST_MSVC)
64 #  pragma warning(push)
65 // This believed not now necessary, so commented out.
66 //#  pragma warning(disable: 4702) // unreachable code.
67 // in domain_error_imp in error_handling.
68 #endif
69 
70 namespace boost
71 {
72   namespace math
73   {
74     namespace negative_binomial_detail
75     {
76       // Common error checking routines for negative binomial distribution functions:
77       template <class RealType, class Policy>
check_successes(const char * function,const RealType & r,RealType * result,const Policy & pol)78       inline bool check_successes(const char* function, const RealType& r, RealType* result, const Policy& pol)
79       {
80         if( !(boost::math::isfinite)(r) || (r <= 0) )
81         {
82           *result = policies::raise_domain_error<RealType>(
83             function,
84             "Number of successes argument is %1%, but must be > 0 !", r, pol);
85           return false;
86         }
87         return true;
88       }
89       template <class RealType, class Policy>
check_success_fraction(const char * function,const RealType & p,RealType * result,const Policy & pol)90       inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol)
91       {
92         if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) )
93         {
94           *result = policies::raise_domain_error<RealType>(
95             function,
96             "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
97           return false;
98         }
99         return true;
100       }
101       template <class RealType, class Policy>
check_dist(const char * function,const RealType & r,const RealType & p,RealType * result,const Policy & pol)102       inline bool check_dist(const char* function, const RealType& r, const RealType& p, RealType* result, const Policy& pol)
103       {
104         return check_success_fraction(function, p, result, pol)
105           && check_successes(function, r, result, pol);
106       }
107       template <class RealType, class Policy>
check_dist_and_k(const char * function,const RealType & r,const RealType & p,RealType k,RealType * result,const Policy & pol)108       inline bool check_dist_and_k(const char* function, const RealType& r, const RealType& p, RealType k, RealType* result, const Policy& pol)
109       {
110         if(check_dist(function, r, p, result, pol) == false)
111         {
112           return false;
113         }
114         if( !(boost::math::isfinite)(k) || (k < 0) )
115         { // Check k failures.
116           *result = policies::raise_domain_error<RealType>(
117             function,
118             "Number of failures argument is %1%, but must be >= 0 !", k, pol);
119           return false;
120         }
121         return true;
122       } // Check_dist_and_k
123 
124       template <class RealType, class Policy>
check_dist_and_prob(const char * function,const RealType & r,RealType p,RealType prob,RealType * result,const Policy & pol)125       inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol)
126       {
127         if((check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false)
128         {
129           return false;
130         }
131         return true;
132       } // check_dist_and_prob
133     } //  namespace negative_binomial_detail
134 
135     template <class RealType = double, class Policy = policies::policy<> >
136     class negative_binomial_distribution
137     {
138     public:
139       typedef RealType value_type;
140       typedef Policy policy_type;
141 
negative_binomial_distribution(RealType r,RealType p)142       negative_binomial_distribution(RealType r, RealType p) : m_r(r), m_p(p)
143       { // Constructor.
144         RealType result;
145         negative_binomial_detail::check_dist(
146           "negative_binomial_distribution<%1%>::negative_binomial_distribution",
147           m_r, // Check successes r > 0.
148           m_p, // Check success_fraction 0 <= p <= 1.
149           &result, Policy());
150       } // negative_binomial_distribution constructor.
151 
152       // Private data getter class member functions.
success_fraction() const153       RealType success_fraction() const
154       { // Probability of success as fraction in range 0 to 1.
155         return m_p;
156       }
successes() const157       RealType successes() const
158       { // Total number of successes r.
159         return m_r;
160       }
161 
find_lower_bound_on_p(RealType trials,RealType successes,RealType alpha)162       static RealType find_lower_bound_on_p(
163         RealType trials,
164         RealType successes,
165         RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
166       {
167         static const char* function = "boost::math::negative_binomial<%1%>::find_lower_bound_on_p";
168         RealType result = 0;  // of error checks.
169         RealType failures = trials - successes;
170         if(false == detail::check_probability(function, alpha, &result, Policy())
171           && negative_binomial_detail::check_dist_and_k(
172           function, successes, RealType(0), failures, &result, Policy()))
173         {
174           return result;
175         }
176         // Use complement ibeta_inv function for lower bound.
177         // This is adapted from the corresponding binomial formula
178         // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
179         // This is a Clopper-Pearson interval, and may be overly conservative,
180         // see also "A Simple Improved Inferential Method for Some
181         // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
182         // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
183         //
184         return ibeta_inv(successes, failures + 1, alpha, static_cast<RealType*>(0), Policy());
185       } // find_lower_bound_on_p
186 
find_upper_bound_on_p(RealType trials,RealType successes,RealType alpha)187       static RealType find_upper_bound_on_p(
188         RealType trials,
189         RealType successes,
190         RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test.
191       {
192         static const char* function = "boost::math::negative_binomial<%1%>::find_upper_bound_on_p";
193         RealType result = 0;  // of error checks.
194         RealType failures = trials - successes;
195         if(false == negative_binomial_detail::check_dist_and_k(
196           function, successes, RealType(0), failures, &result, Policy())
197           && detail::check_probability(function, alpha, &result, Policy()))
198         {
199           return result;
200         }
201         if(failures == 0)
202            return 1;
203         // Use complement ibetac_inv function for upper bound.
204         // Note adjusted failures value: *not* failures+1 as usual.
205         // This is adapted from the corresponding binomial formula
206         // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm
207         // This is a Clopper-Pearson interval, and may be overly conservative,
208         // see also "A Simple Improved Inferential Method for Some
209         // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY
210         // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf
211         //
212         return ibetac_inv(successes, failures, alpha, static_cast<RealType*>(0), Policy());
213       } // find_upper_bound_on_p
214 
215       // Estimate number of trials :
216       // "How many trials do I need to be P% sure of seeing k or fewer failures?"
217 
find_minimum_number_of_trials(RealType k,RealType p,RealType alpha)218       static RealType find_minimum_number_of_trials(
219         RealType k,     // number of failures (k >= 0).
220         RealType p,     // success fraction 0 <= p <= 1.
221         RealType alpha) // risk level threshold 0 <= alpha <= 1.
222       {
223         static const char* function = "boost::math::negative_binomial<%1%>::find_minimum_number_of_trials";
224         // Error checks:
225         RealType result = 0;
226         if(false == negative_binomial_detail::check_dist_and_k(
227           function, RealType(1), p, k, &result, Policy())
228           && detail::check_probability(function, alpha, &result, Policy()))
229         { return result; }
230 
231         result = ibeta_inva(k + 1, p, alpha, Policy());  // returns n - k
232         return result + k;
233       } // RealType find_number_of_failures
234 
find_maximum_number_of_trials(RealType k,RealType p,RealType alpha)235       static RealType find_maximum_number_of_trials(
236         RealType k,     // number of failures (k >= 0).
237         RealType p,     // success fraction 0 <= p <= 1.
238         RealType alpha) // risk level threshold 0 <= alpha <= 1.
239       {
240         static const char* function = "boost::math::negative_binomial<%1%>::find_maximum_number_of_trials";
241         // Error checks:
242         RealType result = 0;
243         if(false == negative_binomial_detail::check_dist_and_k(
244           function, RealType(1), p, k, &result, Policy())
245           &&  detail::check_probability(function, alpha, &result, Policy()))
246         { return result; }
247 
248         result = ibetac_inva(k + 1, p, alpha, Policy());  // returns n - k
249         return result + k;
250       } // RealType find_number_of_trials complemented
251 
252     private:
253       RealType m_r; // successes.
254       RealType m_p; // success_fraction
255     }; // template <class RealType, class Policy> class negative_binomial_distribution
256 
257     typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
258 
259     template <class RealType, class Policy>
range(const negative_binomial_distribution<RealType,Policy> &)260     inline const std::pair<RealType, RealType> range(const negative_binomial_distribution<RealType, Policy>& /* dist */)
261     { // Range of permissible values for random variable k.
262        using boost::math::tools::max_value;
263        return std::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // max_integer?
264     }
265 
266     template <class RealType, class Policy>
support(const negative_binomial_distribution<RealType,Policy> &)267     inline const std::pair<RealType, RealType> support(const negative_binomial_distribution<RealType, Policy>& /* dist */)
268     { // Range of supported values for random variable k.
269        // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero.
270        using boost::math::tools::max_value;
271        return std::pair<RealType, RealType>(static_cast<RealType>(0),  max_value<RealType>()); // max_integer?
272     }
273 
274     template <class RealType, class Policy>
mean(const negative_binomial_distribution<RealType,Policy> & dist)275     inline RealType mean(const negative_binomial_distribution<RealType, Policy>& dist)
276     { // Mean of Negative Binomial distribution = r(1-p)/p.
277       return dist.successes() * (1 - dist.success_fraction() ) / dist.success_fraction();
278     } // mean
279 
280     //template <class RealType, class Policy>
281     //inline RealType median(const negative_binomial_distribution<RealType, Policy>& dist)
282     //{ // Median of negative_binomial_distribution is not defined.
283     //  return policies::raise_domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
284     //} // median
285     // Now implemented via quantile(half) in derived accessors.
286 
287     template <class RealType, class Policy>
mode(const negative_binomial_distribution<RealType,Policy> & dist)288     inline RealType mode(const negative_binomial_distribution<RealType, Policy>& dist)
289     { // Mode of Negative Binomial distribution = floor[(r-1) * (1 - p)/p]
290       BOOST_MATH_STD_USING // ADL of std functions.
291       return floor((dist.successes() -1) * (1 - dist.success_fraction()) / dist.success_fraction());
292     } // mode
293 
294     template <class RealType, class Policy>
skewness(const negative_binomial_distribution<RealType,Policy> & dist)295     inline RealType skewness(const negative_binomial_distribution<RealType, Policy>& dist)
296     { // skewness of Negative Binomial distribution = 2-p / (sqrt(r(1-p))
297       BOOST_MATH_STD_USING // ADL of std functions.
298       RealType p = dist.success_fraction();
299       RealType r = dist.successes();
300 
301       return (2 - p) /
302         sqrt(r * (1 - p));
303     } // skewness
304 
305     template <class RealType, class Policy>
kurtosis(const negative_binomial_distribution<RealType,Policy> & dist)306     inline RealType kurtosis(const negative_binomial_distribution<RealType, Policy>& dist)
307     { // kurtosis of Negative Binomial distribution
308       // http://en.wikipedia.org/wiki/Negative_binomial is kurtosis_excess so add 3
309       RealType p = dist.success_fraction();
310       RealType r = dist.successes();
311       return 3 + (6 / r) + ((p * p) / (r * (1 - p)));
312     } // kurtosis
313 
314      template <class RealType, class Policy>
kurtosis_excess(const negative_binomial_distribution<RealType,Policy> & dist)315     inline RealType kurtosis_excess(const negative_binomial_distribution<RealType, Policy>& dist)
316     { // kurtosis excess of Negative Binomial distribution
317       // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess
318       RealType p = dist.success_fraction();
319       RealType r = dist.successes();
320       return (6 - p * (6-p)) / (r * (1-p));
321     } // kurtosis_excess
322 
323     template <class RealType, class Policy>
variance(const negative_binomial_distribution<RealType,Policy> & dist)324     inline RealType variance(const negative_binomial_distribution<RealType, Policy>& dist)
325     { // Variance of Binomial distribution = r (1-p) / p^2.
326       return  dist.successes() * (1 - dist.success_fraction())
327         / (dist.success_fraction() * dist.success_fraction());
328     } // variance
329 
330     // RealType standard_deviation(const negative_binomial_distribution<RealType, Policy>& dist)
331     // standard_deviation provided by derived accessors.
332     // RealType hazard(const negative_binomial_distribution<RealType, Policy>& dist)
333     // hazard of Negative Binomial distribution provided by derived accessors.
334     // RealType chf(const negative_binomial_distribution<RealType, Policy>& dist)
335     // chf of Negative Binomial distribution provided by derived accessors.
336 
337     template <class RealType, class Policy>
pdf(const negative_binomial_distribution<RealType,Policy> & dist,const RealType & k)338     inline RealType pdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
339     { // Probability Density/Mass Function.
340       BOOST_FPU_EXCEPTION_GUARD
341 
342       static const char* function = "boost::math::pdf(const negative_binomial_distribution<%1%>&, %1%)";
343 
344       RealType r = dist.successes();
345       RealType p = dist.success_fraction();
346       RealType result = 0;
347       if(false == negative_binomial_detail::check_dist_and_k(
348         function,
349         r,
350         dist.success_fraction(),
351         k,
352         &result, Policy()))
353       {
354         return result;
355       }
356 
357       result = (p/(r + k)) * ibeta_derivative(r, static_cast<RealType>(k+1), p, Policy());
358       // Equivalent to:
359       // return exp(lgamma(r + k) - lgamma(r) - lgamma(k+1)) * pow(p, r) * pow((1-p), k);
360       return result;
361     } // negative_binomial_pdf
362 
363     template <class RealType, class Policy>
cdf(const negative_binomial_distribution<RealType,Policy> & dist,const RealType & k)364     inline RealType cdf(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& k)
365     { // Cumulative Distribution Function of Negative Binomial.
366       static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
367       using boost::math::ibeta; // Regularized incomplete beta function.
368       // k argument may be integral, signed, or unsigned, or floating point.
369       // If necessary, it has already been promoted from an integral type.
370       RealType p = dist.success_fraction();
371       RealType r = dist.successes();
372       // Error check:
373       RealType result = 0;
374       if(false == negative_binomial_detail::check_dist_and_k(
375         function,
376         r,
377         dist.success_fraction(),
378         k,
379         &result, Policy()))
380       {
381         return result;
382       }
383 
384       RealType probability = ibeta(r, static_cast<RealType>(k+1), p, Policy());
385       // Ip(r, k+1) = ibeta(r, k+1, p)
386       return probability;
387     } // cdf Cumulative Distribution Function Negative Binomial.
388 
389       template <class RealType, class Policy>
cdf(const complemented2_type<negative_binomial_distribution<RealType,Policy>,RealType> & c)390       inline RealType cdf(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
391       { // Complemented Cumulative Distribution Function Negative Binomial.
392 
393       static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)";
394       using boost::math::ibetac; // Regularized incomplete beta function complement.
395       // k argument may be integral, signed, or unsigned, or floating point.
396       // If necessary, it has already been promoted from an integral type.
397       RealType const& k = c.param;
398       negative_binomial_distribution<RealType, Policy> const& dist = c.dist;
399       RealType p = dist.success_fraction();
400       RealType r = dist.successes();
401       // Error check:
402       RealType result = 0;
403       if(false == negative_binomial_detail::check_dist_and_k(
404         function,
405         r,
406         p,
407         k,
408         &result, Policy()))
409       {
410         return result;
411       }
412       // Calculate cdf negative binomial using the incomplete beta function.
413       // Use of ibeta here prevents cancellation errors in calculating
414       // 1-p if p is very small, perhaps smaller than machine epsilon.
415       // Ip(k+1, r) = ibetac(r, k+1, p)
416       // constrain_probability here?
417      RealType probability = ibetac(r, static_cast<RealType>(k+1), p, Policy());
418       // Numerical errors might cause probability to be slightly outside the range < 0 or > 1.
419       // This might cause trouble downstream, so warn, possibly throw exception, but constrain to the limits.
420       return probability;
421     } // cdf Cumulative Distribution Function Negative Binomial.
422 
423     template <class RealType, class Policy>
quantile(const negative_binomial_distribution<RealType,Policy> & dist,const RealType & P)424     inline RealType quantile(const negative_binomial_distribution<RealType, Policy>& dist, const RealType& P)
425     { // Quantile, percentile/100 or Percent Point Negative Binomial function.
426       // Return the number of expected failures k for a given probability p.
427 
428       // Inverse cumulative Distribution Function or Quantile (percentile / 100) of negative_binomial Probability.
429       // MAthCAD pnbinom return smallest k such that negative_binomial(k, n, p) >= probability.
430       // k argument may be integral, signed, or unsigned, or floating point.
431       // BUT Cephes/CodeCogs says: finds argument p (0 to 1) such that cdf(k, n, p) = y
432       static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
433       BOOST_MATH_STD_USING // ADL of std functions.
434 
435       RealType p = dist.success_fraction();
436       RealType r = dist.successes();
437       // Check dist and P.
438       RealType result = 0;
439       if(false == negative_binomial_detail::check_dist_and_prob
440         (function, r, p, P, &result, Policy()))
441       {
442         return result;
443       }
444 
445       // Special cases.
446       if (P == 1)
447       {  // Would need +infinity failures for total confidence.
448         result = policies::raise_overflow_error<RealType>(
449             function,
450             "Probability argument is 1, which implies infinite failures !", Policy());
451         return result;
452        // usually means return +std::numeric_limits<RealType>::infinity();
453        // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
454       }
455       if (P == 0)
456       { // No failures are expected if P = 0.
457         return 0; // Total trials will be just dist.successes.
458       }
459       if (P <= pow(dist.success_fraction(), dist.successes()))
460       { // p <= pdf(dist, 0) == cdf(dist, 0)
461         return 0;
462       }
463       if(p == 0)
464       {  // Would need +infinity failures for total confidence.
465          result = policies::raise_overflow_error<RealType>(
466             function,
467             "Success fraction is 0, which implies infinite failures !", Policy());
468          return result;
469          // usually means return +std::numeric_limits<RealType>::infinity();
470          // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
471       }
472       /*
473       // Calculate quantile of negative_binomial using the inverse incomplete beta function.
474       using boost::math::ibeta_invb;
475       return ibeta_invb(r, p, P, Policy()) - 1; //
476       */
477       RealType guess = 0;
478       RealType factor = 5;
479       if(r * r * r * P * p > 0.005)
480          guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), P, RealType(1-P), Policy());
481 
482       if(guess < 10)
483       {
484          //
485          // Cornish-Fisher Negative binomial approximation not accurate in this area:
486          //
487          guess = (std::min)(RealType(r * 2), RealType(10));
488       }
489       else
490          factor = (1-P < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
491       BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
492       //
493       // Max iterations permitted:
494       //
495       boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
496       typedef typename Policy::discrete_quantile_type discrete_type;
497       return detail::inverse_discrete_quantile(
498          dist,
499          P,
500          false,
501          guess,
502          factor,
503          RealType(1),
504          discrete_type(),
505          max_iter);
506     } // RealType quantile(const negative_binomial_distribution dist, p)
507 
508     template <class RealType, class Policy>
quantile(const complemented2_type<negative_binomial_distribution<RealType,Policy>,RealType> & c)509     inline RealType quantile(const complemented2_type<negative_binomial_distribution<RealType, Policy>, RealType>& c)
510     {  // Quantile or Percent Point Binomial function.
511        // Return the number of expected failures k for a given
512        // complement of the probability Q = 1 - P.
513        static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)";
514        BOOST_MATH_STD_USING
515 
516        // Error checks:
517        RealType Q = c.param;
518        const negative_binomial_distribution<RealType, Policy>& dist = c.dist;
519        RealType p = dist.success_fraction();
520        RealType r = dist.successes();
521        RealType result = 0;
522        if(false == negative_binomial_detail::check_dist_and_prob(
523           function,
524           r,
525           p,
526           Q,
527           &result, Policy()))
528        {
529           return result;
530        }
531 
532        // Special cases:
533        //
534        if(Q == 1)
535        {  // There may actually be no answer to this question,
536           // since the probability of zero failures may be non-zero,
537           return 0; // but zero is the best we can do:
538        }
539        if(Q == 0)
540        {  // Probability 1 - Q  == 1 so infinite failures to achieve certainty.
541           // Would need +infinity failures for total confidence.
542           result = policies::raise_overflow_error<RealType>(
543              function,
544              "Probability argument complement is 0, which implies infinite failures !", Policy());
545           return result;
546           // usually means return +std::numeric_limits<RealType>::infinity();
547           // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
548        }
549        if (-Q <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy()))
550        {  // q <= cdf(complement(dist, 0)) == pdf(dist, 0)
551           return 0; //
552        }
553        if(p == 0)
554        {  // Success fraction is 0 so infinite failures to achieve certainty.
555           // Would need +infinity failures for total confidence.
556           result = policies::raise_overflow_error<RealType>(
557              function,
558              "Success fraction is 0, which implies infinite failures !", Policy());
559           return result;
560           // usually means return +std::numeric_limits<RealType>::infinity();
561           // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR
562        }
563        //return ibetac_invb(r, p, Q, Policy()) -1;
564        RealType guess = 0;
565        RealType factor = 5;
566        if(r * r * r * (1-Q) * p > 0.005)
567           guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), RealType(1-Q), Q, Policy());
568 
569        if(guess < 10)
570        {
571           //
572           // Cornish-Fisher Negative binomial approximation not accurate in this area:
573           //
574           guess = (std::min)(RealType(r * 2), RealType(10));
575        }
576        else
577           factor = (Q < sqrt(tools::epsilon<RealType>())) ? 2 : (guess < 20 ? 1.2f : 1.1f);
578        BOOST_MATH_INSTRUMENT_CODE("guess = " << guess);
579        //
580        // Max iterations permitted:
581        //
582        boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
583        typedef typename Policy::discrete_quantile_type discrete_type;
584        return detail::inverse_discrete_quantile(
585           dist,
586           Q,
587           true,
588           guess,
589           factor,
590           RealType(1),
591           discrete_type(),
592           max_iter);
593     } // quantile complement
594 
595  } // namespace math
596 } // namespace boost
597 
598 // This include must be at the end, *after* the accessors
599 // for this distribution have been defined, in order to
600 // keep compilers that support two-phase lookup happy.
601 #include <boost/math/distributions/detail/derived_accessors.hpp>
602 
603 #if defined (BOOST_MSVC)
604 # pragma warning(pop)
605 #endif
606 
607 #endif // BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP
608