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 25 namespace boost { 26 namespace 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 */ 34 template<class RealType = double> 35 class bernoulli_distribution 36 { 37 public: 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 */ param_type(RealType p_arg=RealType (0.5))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. */ p() const63 RealType p() const { return _p; } 64 65 /** Writes the parameters to a std::ostream. */ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,param_type,parm)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. */ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,param_type,parm)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. */ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type,lhs,rhs)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 */ bernoulli_distribution(const RealType & p_arg=RealType (0.5))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 */ bernoulli_distribution(const param_type & parm)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 */ p() const113 RealType p() const { return _p; } 114 115 /** Returns the smallest value that the distribution can produce. */ BOOST_PREVENT_MACRO_SUBSTITUTION() const116 bool min BOOST_PREVENT_MACRO_SUBSTITUTION () const 117 { return false; } 118 /** Returns the largest value that the distribution can produce. */ BOOST_PREVENT_MACRO_SUBSTITUTION() const119 bool max BOOST_PREVENT_MACRO_SUBSTITUTION () const 120 { return true; } 121 122 /** Returns the parameters of the distribution. */ param() const123 param_type param() const { return param_type(_p); } 124 /** Sets the parameters of the distribution. */ param(const param_type & parm)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 */ reset()131 void reset() { } 132 133 /** 134 * Returns: a random variate distributed according to the 135 * \bernoulli_distribution. 136 */ 137 template<class Engine> operator ()(Engine & eng) const138 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> operator ()(Engine & eng,const param_type & parm) const151 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 */ BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,bernoulli_distribution,bd)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 */ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,bernoulli_distribution,bd)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 */ BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(bernoulli_distribution,lhs,rhs)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 187 private: 188 RealType _p; 189 }; 190 191 } // namespace random 192 193 using random::bernoulli_distribution; 194 195 } // namespace boost 196 197 #endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP 198