1/* boost random/bernoulli_distribution.hpp header file
2 *
3 * Copyright Jens Maurer 2000-2001
4 * Copyright Steven Watanabe 2011
5 * Distributed under the Boost Software License, Version 1.0. (See
6 * accompanying file LICENSE_1_0.txt or copy at
7 * http://www.boost.org/LICENSE_1_0.txt)
8 *
9 * See http://www.boost.org for most recent version including documentation.
10 *
11 * $Id$
12 *
13 * Revision history
14 * 2001-02-18 moved to individual header files
15 */
16
17#ifndef BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
18#define BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
19
20#include <iosfwd>
21#include <boost/assert.hpp>
22#include <boost/random/detail/config.hpp>
23#include <boost/random/detail/operators.hpp>
24
25namespace boost {
26namespace random {
27
28/**
29 * Instantiations of class template \bernoulli_distribution model a
30 * \random_distribution. Such a random distribution produces bool values
31 * distributed with probabilities P(true) = p and P(false) = 1-p. p is
32 * the parameter of the distribution.
33 */
34template<class RealType = double>
35class bernoulli_distribution
36{
37public:
38 // In principle, this could work with both integer and floating-point
39 // types. Generating floating-point random numbers in the first
40 // place is probably more expensive, so use integer as input.
41 typedef int input_type;
42 typedef bool result_type;
43
44 class param_type
45 {
46 public:
47
48 typedef bernoulli_distribution distribution_type;
49
50 /**
51 * Constructs the parameters of the distribution.
52 *
53 * Requires: 0 <= p <= 1
54 */
55 explicit param_type(RealType p_arg = RealType(0.5))
56 : _p(p_arg)
57 {
58 BOOST_ASSERT(_p >= 0);
59 BOOST_ASSERT(_p <= 1);
60 }
61
62 /** Returns the p parameter of the distribution. */
63 RealType p() const { return _p; }
64
65 /** Writes the parameters to a std::ostream. */
66 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
67 {
68 os << parm._p;
69 return os;
70 }
71
72 /** Reads the parameters from a std::istream. */
73 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
74 {
75 is >> parm._p;
76 return is;
77 }
78
79 /** Returns true if the two sets of parameters are equal. */
80 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
81 { return lhs._p == rhs._p; }
82
83 /** Returns true if the two sets of parameters are different. */
84 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
85
86 private:
87 RealType _p;
88 };
89
90 /**
91 * Constructs a \bernoulli_distribution object.
92 * p is the parameter of the distribution.
93 *
94 * Requires: 0 <= p <= 1
95 */
96 explicit bernoulli_distribution(const RealType& p_arg = RealType(0.5))
97 : _p(p_arg)
98 {
99 BOOST_ASSERT(_p >= 0);
100 BOOST_ASSERT(_p <= 1);
101 }
102 /**
103 * Constructs \bernoulli_distribution from its parameters
104 */
105 explicit bernoulli_distribution(const param_type& parm)
106 : _p(parm.p()) {}
107
108 // compiler-generated copy ctor and assignment operator are fine
109
110 /**
111 * Returns: The "p" parameter of the distribution.
112 */
113 RealType p() const { return _p; }
114
115 /** Returns the smallest value that the distribution can produce. */
116 bool min BOOST_PREVENT_MACRO_SUBSTITUTION () const
117 { return false; }
118 /** Returns the largest value that the distribution can produce. */
119 bool max BOOST_PREVENT_MACRO_SUBSTITUTION () const
120 { return true; }
121
122 /** Returns the parameters of the distribution. */
123 param_type param() const { return param_type(_p); }
124 /** Sets the parameters of the distribution. */
125 void param(const param_type& parm) { _p = parm.p(); }
126
127 /**
128 * Effects: Subsequent uses of the distribution do not depend
129 * on values produced by any engine prior to invoking reset.
130 */
131 void reset() { }
132
133 /**
134 * Returns: a random variate distributed according to the
135 * \bernoulli_distribution.
136 */
137 template<class Engine>
138 bool operator()(Engine& eng) const
139 {
140 if(_p == RealType(0))
141 return false;
142 else
143 return RealType(eng() - (eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
144 }
145
146 /**
147 * Returns: a random variate distributed according to the
148 * \bernoulli_distribution with parameters specified by param.
149 */
150 template<class Engine>
151 bool operator()(Engine& eng, const param_type& parm) const
152 {
153 return bernoulli_distribution(parm)(eng);
154 }
155
156 /**
157 * Writes the parameters of the distribution to a @c std::ostream.
158 */
159 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, bernoulli_distribution, bd)
160 {
161 os << bd._p;
162 return os;
163 }
164
165 /**
166 * Reads the parameters of the distribution from a @c std::istream.
167 */
168 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, bernoulli_distribution, bd)
169 {
170 is >> bd._p;
171 return is;
172 }
173
174 /**
175 * Returns true iff the two distributions will produce identical
176 * sequences of values given equal generators.
177 */
178 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(bernoulli_distribution, lhs, rhs)
179 { return lhs._p == rhs._p; }
180
181 /**
182 * Returns true iff the two distributions will produce different
183 * sequences of values given equal generators.
184 */
185 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(bernoulli_distribution)
186
187private:
188 RealType _p;
189};
190
191} // namespace random
192
193using random::bernoulli_distribution;
194
195} // namespace boost
196
197#endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
198