]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* boost random/negative_binomial_distribution.hpp header file |
2 | * | |
3 | * Copyright Steven Watanabe 2010 | |
4 | * Distributed under the Boost Software License, Version 1.0. (See | |
5 | * accompanying file LICENSE_1_0.txt or copy at | |
6 | * http://www.boost.org/LICENSE_1_0.txt) | |
7 | * | |
8 | * See http://www.boost.org for most recent version including documentation. | |
9 | * | |
10 | * $Id$ | |
11 | */ | |
12 | ||
13 | #ifndef BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED | |
14 | #define BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED | |
15 | ||
16 | #include <iosfwd> | |
17 | ||
18 | #include <boost/limits.hpp> | |
19 | #include <boost/random/detail/config.hpp> | |
20 | #include <boost/random/gamma_distribution.hpp> | |
21 | #include <boost/random/poisson_distribution.hpp> | |
22 | ||
23 | namespace boost { | |
24 | namespace random { | |
25 | ||
26 | /** | |
27 | * The negative binomial distribution is an integer valued | |
28 | * distribution with two parameters, @c k and @c p. The | |
29 | * distribution produces non-negative values. | |
30 | * | |
31 | * The distribution function is | |
32 | * \f$\displaystyle P(i) = {k+i-1\choose i}p^k(1-p)^i\f$. | |
33 | * | |
34 | * This implementation uses a gamma-poisson mixture. | |
35 | */ | |
36 | template<class IntType = int, class RealType = double> | |
37 | class negative_binomial_distribution { | |
38 | public: | |
39 | typedef IntType result_type; | |
40 | typedef RealType input_type; | |
41 | ||
42 | class param_type { | |
43 | public: | |
44 | typedef negative_binomial_distribution distribution_type; | |
45 | /** | |
46 | * Construct a param_type object. @c k and @c p | |
47 | * are the parameters of the distribution. | |
48 | * | |
49 | * Requires: k >=0 && 0 <= p <= 1 | |
50 | */ | |
51 | explicit param_type(IntType k_arg = 1, RealType p_arg = RealType (0.5)) | |
52 | : _k(k_arg), _p(p_arg) | |
53 | {} | |
54 | /** Returns the @c k parameter of the distribution. */ | |
55 | IntType k() const { return _k; } | |
56 | /** Returns the @c p parameter of the distribution. */ | |
57 | RealType p() const { return _p; } | |
58 | #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS | |
59 | /** Writes the parameters of the distribution to a @c std::ostream. */ | |
60 | template<class CharT, class Traits> | |
61 | friend std::basic_ostream<CharT,Traits>& | |
62 | operator<<(std::basic_ostream<CharT,Traits>& os, | |
63 | const param_type& parm) | |
64 | { | |
65 | os << parm._p << " " << parm._k; | |
66 | return os; | |
67 | } | |
68 | ||
69 | /** Reads the parameters of the distribution from a @c std::istream. */ | |
70 | template<class CharT, class Traits> | |
71 | friend std::basic_istream<CharT,Traits>& | |
72 | operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm) | |
73 | { | |
74 | is >> parm._p >> std::ws >> parm._k; | |
75 | return is; | |
76 | } | |
77 | #endif | |
78 | /** Returns true if the parameters have the same values. */ | |
79 | friend bool operator==(const param_type& lhs, const param_type& rhs) | |
80 | { | |
81 | return lhs._k == rhs._k && lhs._p == rhs._p; | |
82 | } | |
83 | /** Returns true if the parameters have different values. */ | |
84 | friend bool operator!=(const param_type& lhs, const param_type& rhs) | |
85 | { | |
86 | return !(lhs == rhs); | |
87 | } | |
88 | private: | |
89 | IntType _k; | |
90 | RealType _p; | |
91 | }; | |
92 | ||
93 | /** | |
94 | * Construct a @c negative_binomial_distribution object. @c k and @c p | |
95 | * are the parameters of the distribution. | |
96 | * | |
97 | * Requires: k >=0 && 0 <= p <= 1 | |
98 | */ | |
99 | explicit negative_binomial_distribution(IntType k_arg = 1, | |
100 | RealType p_arg = RealType(0.5)) | |
101 | : _k(k_arg), _p(p_arg) | |
102 | {} | |
103 | ||
104 | /** | |
105 | * Construct an @c negative_binomial_distribution object from the | |
106 | * parameters. | |
107 | */ | |
108 | explicit negative_binomial_distribution(const param_type& parm) | |
109 | : _k(parm.k()), _p(parm.p()) | |
110 | {} | |
111 | ||
112 | /** | |
113 | * Returns a random variate distributed according to the | |
114 | * negative binomial distribution. | |
115 | */ | |
116 | template<class URNG> | |
117 | IntType operator()(URNG& urng) const | |
118 | { | |
119 | gamma_distribution<RealType> gamma(_k, (1-_p)/_p); | |
120 | poisson_distribution<IntType, RealType> poisson(gamma(urng)); | |
121 | return poisson(urng); | |
122 | } | |
123 | ||
124 | /** | |
125 | * Returns a random variate distributed according to the negative | |
126 | * binomial distribution with parameters specified by @c param. | |
127 | */ | |
128 | template<class URNG> | |
129 | IntType operator()(URNG& urng, const param_type& parm) const | |
130 | { | |
131 | return negative_binomial_distribution(parm)(urng); | |
132 | } | |
133 | ||
134 | /** Returns the @c k parameter of the distribution. */ | |
135 | IntType k() const { return _k; } | |
136 | /** Returns the @c p parameter of the distribution. */ | |
137 | RealType p() const { return _p; } | |
138 | ||
139 | /** Returns the smallest value that the distribution can produce. */ | |
140 | IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; } | |
141 | /** Returns the largest value that the distribution can produce. */ | |
142 | IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const | |
143 | { return (std::numeric_limits<IntType>::max)(); } | |
144 | ||
145 | /** Returns the parameters of the distribution. */ | |
146 | param_type param() const { return param_type(_k, _p); } | |
147 | /** Sets parameters of the distribution. */ | |
148 | void param(const param_type& parm) | |
149 | { | |
150 | _k = parm.k(); | |
151 | _p = parm.p(); | |
152 | } | |
153 | ||
154 | /** | |
155 | * Effects: Subsequent uses of the distribution do not depend | |
156 | * on values produced by any engine prior to invoking reset. | |
157 | */ | |
158 | void reset() { } | |
159 | ||
160 | #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS | |
161 | /** Writes the parameters of the distribution to a @c std::ostream. */ | |
162 | template<class CharT, class Traits> | |
163 | friend std::basic_ostream<CharT,Traits>& | |
164 | operator<<(std::basic_ostream<CharT,Traits>& os, | |
165 | const negative_binomial_distribution& bd) | |
166 | { | |
167 | os << bd.param(); | |
168 | return os; | |
169 | } | |
170 | ||
171 | /** Reads the parameters of the distribution from a @c std::istream. */ | |
172 | template<class CharT, class Traits> | |
173 | friend std::basic_istream<CharT,Traits>& | |
174 | operator>>(std::basic_istream<CharT,Traits>& is, | |
175 | negative_binomial_distribution& bd) | |
176 | { | |
177 | bd.read(is); | |
178 | return is; | |
179 | } | |
180 | #endif | |
181 | ||
182 | /** Returns true if the two distributions will produce the same | |
183 | sequence of values, given equal generators. */ | |
184 | friend bool operator==(const negative_binomial_distribution& lhs, | |
185 | const negative_binomial_distribution& rhs) | |
186 | { | |
187 | return lhs._k == rhs._k && lhs._p == rhs._p; | |
188 | } | |
189 | /** Returns true if the two distributions could produce different | |
190 | sequences of values, given equal generators. */ | |
191 | friend bool operator!=(const negative_binomial_distribution& lhs, | |
192 | const negative_binomial_distribution& rhs) | |
193 | { | |
194 | return !(lhs == rhs); | |
195 | } | |
196 | ||
197 | private: | |
198 | ||
199 | /// @cond \show_private | |
200 | ||
201 | template<class CharT, class Traits> | |
202 | void read(std::basic_istream<CharT, Traits>& is) { | |
203 | param_type parm; | |
204 | if(is >> parm) { | |
205 | param(parm); | |
206 | } | |
207 | } | |
208 | ||
209 | // parameters | |
210 | IntType _k; | |
211 | RealType _p; | |
212 | ||
213 | /// @endcond | |
214 | }; | |
215 | ||
216 | } | |
217 | ||
218 | } | |
219 | ||
220 | #endif |