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