]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/math/example/negative_binomial_example1.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / math / example / negative_binomial_example1.cpp
CommitLineData
7c673cae
FG
1// negative_binomial_example1.cpp
2
3// Copyright Paul A. Bristow 2007, 2010.
4
5// Use, modification and distribution are subject to the
6// Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt
8// or copy at http://www.boost.org/LICENSE_1_0.txt)
9
10// Example 1 of using negative_binomial distribution.
11
12//[negative_binomial_eg1_1
13
14/*`
15Based on [@http://en.wikipedia.org/wiki/Negative_binomial_distribution
16a problem by Dr. Diane Evans,
17Professor of Mathematics at Rose-Hulman Institute of Technology].
18
19Pat is required to sell candy bars to raise money for the 6th grade field trip.
20There are thirty houses in the neighborhood,
21and Pat is not supposed to return home until five candy bars have been sold.
22So the child goes door to door, selling candy bars.
23At each house, there is a 0.4 probability (40%) of selling one candy bar
24and a 0.6 probability (60%) of selling nothing.
25
26What is the probability mass (density) function (pdf) for selling the last (fifth)
27candy bar at the nth house?
28
29The Negative Binomial(r, p) distribution describes the probability of k failures
30and r successes in k+r Bernoulli(p) trials with success on the last trial.
31(A [@http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli trial]
32is one with only two possible outcomes, success of failure,
33and p is the probability of success).
34See also [@ http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli distribution]
35and [@http://www.math.uah.edu/stat/bernoulli/Introduction.xhtml Bernoulli applications].
36
37In this example, we will deliberately produce a variety of calculations
38and outputs to demonstrate the ways that the negative binomial distribution
39can be implemented with this library: it is also deliberately over-commented.
40
41First we need to #define macros to control the error and discrete handling policies.
42For this simple example, we want to avoid throwing
43an exception (the default policy) and just return infinity.
44We want to treat the distribution as if it was continuous,
45so we choose a discrete_quantile policy of real,
46rather than the default policy integer_round_outwards.
47*/
48#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
49#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
50/*`
51After that we need some includes to provide easy access to the negative binomial distribution,
52[caution It is vital to #include distributions etc *after* the above #defines]
53and we need some std library iostream, of course.
54*/
55#include <boost/math/distributions/negative_binomial.hpp>
56 // for negative_binomial_distribution
57 using boost::math::negative_binomial; // typedef provides default type is double.
58 using ::boost::math::pdf; // Probability mass function.
59 using ::boost::math::cdf; // Cumulative density function.
60 using ::boost::math::quantile;
61
62#include <iostream>
63 using std::cout; using std::endl;
64 using std::noshowpoint; using std::fixed; using std::right; using std::left;
65#include <iomanip>
66 using std::setprecision; using std::setw;
67
68#include <limits>
69 using std::numeric_limits;
70//] [negative_binomial_eg1_1]
71
72int main()
73{
74 cout <<"Selling candy bars - using the negative binomial distribution."
75 << "\nby Dr. Diane Evans,"
76 "\nProfessor of Mathematics at Rose-Hulman Institute of Technology,"
77 << "\nsee http://en.wikipedia.org/wiki/Negative_binomial_distribution\n"
78 << endl;
79 cout << endl;
80 cout.precision(5);
81 // None of the values calculated have a useful accuracy as great this, but
82 // INF shows wrongly with < 5 !
83 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=240227
84//[negative_binomial_eg1_2
85/*`
86It is always sensible to use try and catch blocks because defaults policies are to
87throw an exception if anything goes wrong.
88
89A simple catch block (see below) will ensure that you get a
90helpful error message instead of an abrupt program abort.
91*/
92 try
93 {
94/*`
95Selling five candy bars means getting five successes, so successes r = 5.
96The total number of trials (n, in this case, houses visited) this takes is therefore
97 = sucesses + failures or k + r = k + 5.
98*/
99 double sales_quota = 5; // Pat's sales quota - successes (r).
100/*`
101At each house, there is a 0.4 probability (40%) of selling one candy bar
102and a 0.6 probability (60%) of selling nothing.
103*/
104 double success_fraction = 0.4; // success_fraction (p) - so failure_fraction is 0.6.
105/*`
106The Negative Binomial(r, p) distribution describes the probability of k failures
107and r successes in k+r Bernoulli(p) trials with success on the last trial.
108(A [@http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli trial]
109is one with only two possible outcomes, success of failure,
110and p is the probability of success).
111
112We therefore start by constructing a negative binomial distribution
113with parameters sales_quota (required successes) and probability of success.
114*/
115 negative_binomial nb(sales_quota, success_fraction); // type double by default.
116/*`
117To confirm, display the success_fraction & successes parameters of the distribution.
118*/
119 cout << "Pat has a sales per house success rate of " << success_fraction
120 << ".\nTherefore he would, on average, sell " << nb.success_fraction() * 100
121 << " bars after trying 100 houses." << endl;
122
123 int all_houses = 30; // The number of houses on the estate.
124
125 cout << "With a success rate of " << nb.success_fraction()
126 << ", he might expect, on average,\n"
127 "to need to visit about " << success_fraction * all_houses
128 << " houses in order to sell all " << nb.successes() << " bars. " << endl;
129/*`
130[pre
131Pat has a sales per house success rate of 0.4.
132Therefore he would, on average, sell 40 bars after trying 100 houses.
133With a success rate of 0.4, he might expect, on average,
134to need to visit about 12 houses in order to sell all 5 bars.
135]
136
137The random variable of interest is the number of houses
138that must be visited to sell five candy bars,
139so we substitute k = n - 5 into a negative_binomial(5, 0.4)
140and obtain the __pdf of the distribution of houses visited.
141Obviously, the best possible case is that Pat makes sales on all the first five houses.
142
143We calculate this using the pdf function:
144*/
145 cout << "Probability that Pat finishes on the " << sales_quota << "th house is "
146 << pdf(nb, 5 - sales_quota) << endl; // == pdf(nb, 0)
147/*`
148Of course, he could not finish on fewer than 5 houses because he must sell 5 candy bars.
149So the 5th house is the first that he could possibly finish on.
150
151To finish on or before the 8th house, Pat must finish at the 5th, 6th, 7th or 8th house.
152The probability that he will finish on *exactly* ( == ) on any house
153is the Probability Density Function (pdf).
154*/
155 cout << "Probability that Pat finishes on the 6th house is "
156 << pdf(nb, 6 - sales_quota) << endl;
157 cout << "Probability that Pat finishes on the 7th house is "
158 << pdf(nb, 7 - sales_quota) << endl;
159 cout << "Probability that Pat finishes on the 8th house is "
160 << pdf(nb, 8 - sales_quota) << endl;
161/*`
162[pre
163Probability that Pat finishes on the 6th house is 0.03072
164Probability that Pat finishes on the 7th house is 0.055296
165Probability that Pat finishes on the 8th house is 0.077414
166]
167
168The sum of the probabilities for these houses is the Cumulative Distribution Function (cdf).
169We can calculate it by adding the individual probabilities.
170*/
171 cout << "Probability that Pat finishes on or before the 8th house is sum "
172 "\n" << "pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = "
173 // Sum each of the mass/density probabilities for houses sales_quota = 5, 6, 7, & 8.
174 << pdf(nb, 5 - sales_quota) // 0 failures.
175 + pdf(nb, 6 - sales_quota) // 1 failure.
176 + pdf(nb, 7 - sales_quota) // 2 failures.
177 + pdf(nb, 8 - sales_quota) // 3 failures.
178 << endl;
179/*`[pre
180pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367
181]
182
183Or, usually better, by using the negative binomial *cumulative* distribution function.
184*/
185 cout << "\nProbability of selling his quota of " << sales_quota
186 << " bars\non or before the " << 8 << "th house is "
187 << cdf(nb, 8 - sales_quota) << endl;
188/*`[pre
189Probability of selling his quota of 5 bars on or before the 8th house is 0.17367
190]*/
191 cout << "\nProbability that Pat finishes exactly on the 10th house is "
192 << pdf(nb, 10 - sales_quota) << endl;
193 cout << "\nProbability of selling his quota of " << sales_quota
194 << " bars\non or before the " << 10 << "th house is "
195 << cdf(nb, 10 - sales_quota) << endl;
196/*`
197[pre
198Probability that Pat finishes exactly on the 10th house is 0.10033
199Probability of selling his quota of 5 bars on or before the 10th house is 0.3669
200]*/
201 cout << "Probability that Pat finishes exactly on the 11th house is "
202 << pdf(nb, 11 - sales_quota) << endl;
203 cout << "\nProbability of selling his quota of " << sales_quota
204 << " bars\non or before the " << 11 << "th house is "
205 << cdf(nb, 11 - sales_quota) << endl;
206/*`[pre
207Probability that Pat finishes on the 11th house is 0.10033
208Probability of selling his quota of 5 candy bars
209on or before the 11th house is 0.46723
210]*/
211 cout << "Probability that Pat finishes exactly on the 12th house is "
212 << pdf(nb, 12 - sales_quota) << endl;
213
214 cout << "\nProbability of selling his quota of " << sales_quota
215 << " bars\non or before the " << 12 << "th house is "
216 << cdf(nb, 12 - sales_quota) << endl;
217/*`[pre
218Probability that Pat finishes on the 12th house is 0.094596
219Probability of selling his quota of 5 candy bars
220on or before the 12th house is 0.56182
221]
222Finally consider the risk of Pat not selling his quota of 5 bars
223even after visiting all the houses.
224Calculate the probability that he /will/ sell on
225or before the last house:
226Calculate the probability that he would sell all his quota on the very last house.
227*/
228 cout << "Probability that Pat finishes on the " << all_houses
229 << " house is " << pdf(nb, all_houses - sales_quota) << endl;
230/*`
231Probability of selling his quota of 5 bars on the 30th house is
232[pre
233Probability that Pat finishes on the 30 house is 0.00069145
234]
235when he'd be very unlucky indeed!
236
237What is the probability that Pat exhausts all 30 houses in the neighborhood,
238and *still* doesn't sell the required 5 candy bars?
239*/
240 cout << "\nProbability of selling his quota of " << sales_quota
241 << " bars\non or before the " << all_houses << "th house is "
242 << cdf(nb, all_houses - sales_quota) << endl;
243/*`
244[pre
245Probability of selling his quota of 5 bars
246on or before the 30th house is 0.99849
247]
248
b32b8144 249So the risk of failing even after visiting all the houses is 1 - this probability,
7c673cae
FG
250 ``1 - cdf(nb, all_houses - sales_quota``
251But using this expression may cause serious inaccuracy,
252so it would be much better to use the complement of the cdf:
253So the risk of failing even at, or after, the 31th (non-existent) houses is 1 - this probability,
254 ``1 - cdf(nb, all_houses - sales_quota)``
255But using this expression may cause serious inaccuracy.
256So it would be much better to use the __complement of the cdf (see __why_complements).
257*/
258 cout << "\nProbability of failing to sell his quota of " << sales_quota
259 << " bars\neven after visiting all " << all_houses << " houses is "
260 << cdf(complement(nb, all_houses - sales_quota)) << endl;
261/*`
262[pre
263Probability of failing to sell his quota of 5 bars
264even after visiting all 30 houses is 0.0015101
265]
266We can also use the quantile (percentile), the inverse of the cdf, to
267predict which house Pat will finish on. So for the 8th house:
268*/
269 double p = cdf(nb, (8 - sales_quota));
270 cout << "Probability of meeting sales quota on or before 8th house is "<< p << endl;
271/*`
272[pre
273Probability of meeting sales quota on or before 8th house is 0.174
274]
275*/
276 cout << "If the confidence of meeting sales quota is " << p
277 << ", then the finishing house is " << quantile(nb, p) + sales_quota << endl;
278
279 cout<< " quantile(nb, p) = " << quantile(nb, p) << endl;
280/*`
281[pre
282If the confidence of meeting sales quota is 0.17367, then the finishing house is 8
283]
284Demanding absolute certainty that all 5 will be sold,
285implies an infinite number of trials.
286(Of course, there are only 30 houses on the estate,
287so he can't ever be *certain* of selling his quota).
288*/
289 cout << "If the confidence of meeting sales quota is " << 1.
290 << ", then the finishing house is " << quantile(nb, 1) + sales_quota << endl;
291 // 1.#INF == infinity.
292/*`[pre
293If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF
294]
295And similarly for a few other probabilities:
296*/
297 cout << "If the confidence of meeting sales quota is " << 0.
298 << ", then the finishing house is " << quantile(nb, 0.) + sales_quota << endl;
299
300 cout << "If the confidence of meeting sales quota is " << 0.5
301 << ", then the finishing house is " << quantile(nb, 0.5) + sales_quota << endl;
302
303 cout << "If the confidence of meeting sales quota is " << 1 - 0.00151 // 30 th
304 << ", then the finishing house is " << quantile(nb, 1 - 0.00151) + sales_quota << endl;
305/*`
306[pre
307If the confidence of meeting sales quota is 0, then the finishing house is 5
308If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337
309If the confidence of meeting sales quota is 0.99849, then the finishing house is 30
310]
311
312Notice that because we chose a discrete quantile policy of real,
313the result can be an 'unreal' fractional house.
314
315If the opposite is true, we don't want to assume any confidence, then this is tantamount
316to assuming that all the first sales_quota trials will be successful sales.
317*/
318 cout << "If confidence of meeting quota is zero\n(we assume all houses are successful sales)"
319 ", then finishing house is " << sales_quota << endl;
320/*`
321[pre
322If confidence of meeting quota is zero (we assume all houses are successful sales), then finishing house is 5
323If confidence of meeting quota is 0, then finishing house is 5
324]
325We can list quantiles for a few probabilities:
326*/
327
328 double ps[] = {0., 0.001, 0.01, 0.05, 0.1, 0.5, 0.9, 0.95, 0.99, 0.999, 1.};
329 // Confidence as fraction = 1-alpha, as percent = 100 * (1-alpha[i]) %
330 cout.precision(3);
92f5a8d4 331 for (unsigned i = 0; i < sizeof(ps)/sizeof(ps[0]); i++)
7c673cae
FG
332 {
333 cout << "If confidence of meeting quota is " << ps[i]
334 << ", then finishing house is " << quantile(nb, ps[i]) + sales_quota
335 << endl;
336 }
337
338/*`
339[pre
340If confidence of meeting quota is 0, then finishing house is 5
341If confidence of meeting quota is 0.001, then finishing house is 5
342If confidence of meeting quota is 0.01, then finishing house is 5
343If confidence of meeting quota is 0.05, then finishing house is 6.2
344If confidence of meeting quota is 0.1, then finishing house is 7.06
345If confidence of meeting quota is 0.5, then finishing house is 11.3
346If confidence of meeting quota is 0.9, then finishing house is 17.8
347If confidence of meeting quota is 0.95, then finishing house is 20.1
348If confidence of meeting quota is 0.99, then finishing house is 24.8
349If confidence of meeting quota is 0.999, then finishing house is 31.1
350If confidence of meeting quota is 1, then finishing house is 1.#INF
351]
352
353We could have applied a ceil function to obtain a 'worst case' integer value for house.
354``ceil(quantile(nb, ps[i]))``
355
356Or, if we had used the default discrete quantile policy, integer_outside, by omitting
357``#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real``
358we would have achieved the same effect.
359
360The real result gives some suggestion which house is most likely.
361For example, compare the real and integer_outside for 95% confidence.
362
363[pre
364If confidence of meeting quota is 0.95, then finishing house is 20.1
365If confidence of meeting quota is 0.95, then finishing house is 21
366]
367The real value 20.1 is much closer to 20 than 21, so integer_outside is pessimistic.
368We could also use integer_round_nearest policy to suggest that 20 is more likely.
369
370Finally, we can tabulate the probability for the last sale being exactly on each house.
371*/
372 cout << "\nHouse for " << sales_quota << "th (last) sale. Probability (%)" << endl;
373 cout.precision(5);
374 for (int i = (int)sales_quota; i < all_houses+1; i++)
375 {
376 cout << left << setw(3) << i << " " << setw(8) << cdf(nb, i - sales_quota) << endl;
377 }
378 cout << endl;
379/*`
380[pre
381House for 5 th (last) sale. Probability (%)
3825 0.01024
3836 0.04096
3847 0.096256
3858 0.17367
3869 0.26657
38710 0.3669
38811 0.46723
38912 0.56182
39013 0.64696
39114 0.72074
39215 0.78272
39316 0.83343
39417 0.874
39518 0.90583
39619 0.93039
39720 0.94905
39821 0.96304
39922 0.97342
40023 0.98103
40124 0.98655
40225 0.99053
40326 0.99337
40427 0.99539
40528 0.99681
40629 0.9978
40730 0.99849
408]
409
410As noted above, using a catch block is always a good idea, even if you do not expect to use it.
411*/
412 }
413 catch(const std::exception& e)
414 { // Since we have set an overflow policy of ignore_error,
415 // an overflow exception should never be thrown.
416 std::cout << "\nMessage from thrown exception was:\n " << e.what() << std::endl;
417/*`
418For example, without a ignore domain error policy, if we asked for ``pdf(nb, -1)`` for example, we would get:
419[pre
420Message from thrown exception was:
421 Error in function boost::math::pdf(const negative_binomial_distribution<double>&, double):
422 Number of failures argument is -1, but must be >= 0 !
423]
424*/
425//] [/ negative_binomial_eg1_2]
426 }
427 return 0;
428} // int main()
429
430
431/*
432
433Output is:
434
435Selling candy bars - using the negative binomial distribution.
436by Dr. Diane Evans,
437Professor of Mathematics at Rose-Hulman Institute of Technology,
438see http://en.wikipedia.org/wiki/Negative_binomial_distribution
439Pat has a sales per house success rate of 0.4.
440Therefore he would, on average, sell 40 bars after trying 100 houses.
441With a success rate of 0.4, he might expect, on average,
442to need to visit about 12 houses in order to sell all 5 bars.
443Probability that Pat finishes on the 5th house is 0.01024
444Probability that Pat finishes on the 6th house is 0.03072
445Probability that Pat finishes on the 7th house is 0.055296
446Probability that Pat finishes on the 8th house is 0.077414
447Probability that Pat finishes on or before the 8th house is sum
448pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367
449Probability of selling his quota of 5 bars
450on or before the 8th house is 0.17367
451Probability that Pat finishes exactly on the 10th house is 0.10033
452Probability of selling his quota of 5 bars
453on or before the 10th house is 0.3669
454Probability that Pat finishes exactly on the 11th house is 0.10033
455Probability of selling his quota of 5 bars
456on or before the 11th house is 0.46723
457Probability that Pat finishes exactly on the 12th house is 0.094596
458Probability of selling his quota of 5 bars
459on or before the 12th house is 0.56182
460Probability that Pat finishes on the 30 house is 0.00069145
461Probability of selling his quota of 5 bars
462on or before the 30th house is 0.99849
463Probability of failing to sell his quota of 5 bars
464even after visiting all 30 houses is 0.0015101
465Probability of meeting sales quota on or before 8th house is 0.17367
466If the confidence of meeting sales quota is 0.17367, then the finishing house is 8
467 quantile(nb, p) = 3
468If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF
469If the confidence of meeting sales quota is 0, then the finishing house is 5
470If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337
471If the confidence of meeting sales quota is 0.99849, then the finishing house is 30
472If confidence of meeting quota is zero
473(we assume all houses are successful sales), then finishing house is 5
474If confidence of meeting quota is 0, then finishing house is 5
475If confidence of meeting quota is 0.001, then finishing house is 5
476If confidence of meeting quota is 0.01, then finishing house is 5
477If confidence of meeting quota is 0.05, then finishing house is 6.2
478If confidence of meeting quota is 0.1, then finishing house is 7.06
479If confidence of meeting quota is 0.5, then finishing house is 11.3
480If confidence of meeting quota is 0.9, then finishing house is 17.8
481If confidence of meeting quota is 0.95, then finishing house is 20.1
482If confidence of meeting quota is 0.99, then finishing house is 24.8
483If confidence of meeting quota is 0.999, then finishing house is 31.1
484If confidence of meeting quota is 1, then finishing house is 1.#J
485House for 5th (last) sale. Probability (%)
4865 0.01024
4876 0.04096
4887 0.096256
4898 0.17367
4909 0.26657
49110 0.3669
49211 0.46723
49312 0.56182
49413 0.64696
49514 0.72074
49615 0.78272
49716 0.83343
49817 0.874
49918 0.90583
50019 0.93039
50120 0.94905
50221 0.96304
50322 0.97342
50423 0.98103
50524 0.98655
50625 0.99053
50726 0.99337
50827 0.99539
50928 0.99681
51029 0.9978
51130 0.99849
512
513*/