File indexing completed on 2025-01-18 09:51:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
0018 #define BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
0019
0020 #include <boost/config/no_tr1/cmath.hpp> // std::log
0021 #include <iosfwd>
0022 #include <ios>
0023 #include <boost/assert.hpp>
0024 #include <boost/random/detail/config.hpp>
0025 #include <boost/random/detail/operators.hpp>
0026 #include <boost/random/uniform_01.hpp>
0027
0028 namespace boost {
0029 namespace random {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 template<class IntType = int, class RealType = double>
0047 class geometric_distribution
0048 {
0049 public:
0050 typedef RealType input_type;
0051 typedef IntType result_type;
0052
0053 class param_type
0054 {
0055 public:
0056
0057 typedef geometric_distribution distribution_type;
0058
0059
0060 explicit param_type(RealType p_arg = RealType(0.5))
0061 : _p(p_arg)
0062 {
0063 BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
0064 }
0065
0066
0067 RealType p() const { return _p; }
0068
0069
0070 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
0071 {
0072 os << parm._p;
0073 return os;
0074 }
0075
0076
0077 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
0078 {
0079 double p_in;
0080 if(is >> p_in) {
0081 if(p_in > RealType(0) && p_in < RealType(1)) {
0082 parm._p = p_in;
0083 } else {
0084 is.setstate(std::ios_base::failbit);
0085 }
0086 }
0087 return is;
0088 }
0089
0090
0091 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
0092 { return lhs._p == rhs._p; }
0093
0094
0095 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
0096
0097
0098 private:
0099 RealType _p;
0100 };
0101
0102
0103
0104
0105
0106
0107 explicit geometric_distribution(const RealType& p_arg = RealType(0.5))
0108 : _p(p_arg)
0109 {
0110 BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
0111 init();
0112 }
0113
0114
0115 explicit geometric_distribution(const param_type& parm)
0116 : _p(parm.p())
0117 {
0118 init();
0119 }
0120
0121
0122
0123
0124 RealType p() const { return _p; }
0125
0126
0127 IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return IntType(0); }
0128
0129
0130 IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
0131 { return (std::numeric_limits<IntType>::max)(); }
0132
0133
0134 param_type param() const { return param_type(_p); }
0135
0136
0137 void param(const param_type& parm)
0138 {
0139 _p = parm.p();
0140 init();
0141 }
0142
0143
0144
0145
0146
0147 void reset() { }
0148
0149
0150
0151
0152
0153 template<class Engine>
0154 result_type operator()(Engine& eng) const
0155 {
0156 using std::log;
0157 using std::floor;
0158 RealType x = RealType(1) - boost::uniform_01<RealType>()(eng);
0159 return IntType(floor(log(x) / _log_1mp));
0160 }
0161
0162
0163
0164
0165
0166 template<class Engine>
0167 result_type operator()(Engine& eng, const param_type& parm) const
0168 { return geometric_distribution(parm)(eng); }
0169
0170
0171 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
0172 {
0173 os << gd._p;
0174 return os;
0175 }
0176
0177
0178 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
0179 {
0180 param_type parm;
0181 if(is >> parm) {
0182 gd.param(parm);
0183 }
0184 return is;
0185 }
0186
0187
0188
0189
0190
0191 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(geometric_distribution, lhs, rhs)
0192 { return lhs._p == rhs._p; }
0193
0194
0195
0196
0197
0198 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(geometric_distribution)
0199
0200 private:
0201
0202
0203
0204 void init()
0205 {
0206 using std::log;
0207 _log_1mp = log(1 - _p);
0208 }
0209
0210 RealType _p;
0211 RealType _log_1mp;
0212
0213
0214 };
0215
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225 template<class IntType = int, class RealType = double>
0226 class geometric_distribution
0227 {
0228 public:
0229 typedef RealType input_type;
0230 typedef IntType result_type;
0231
0232 explicit geometric_distribution(RealType p_arg = RealType(0.5))
0233 : _impl(1 - p_arg) {}
0234
0235 RealType p() const { return 1 - _impl.p(); }
0236
0237 void reset() {}
0238
0239 template<class Engine>
0240 IntType operator()(Engine& eng) const { return _impl(eng) + IntType(1); }
0241
0242 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
0243 {
0244 os << gd.p();
0245 return os;
0246 }
0247
0248 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
0249 {
0250 RealType val;
0251 if(is >> val) {
0252 typename impl_type::param_type impl_param(1 - val);
0253 gd._impl.param(impl_param);
0254 }
0255 return is;
0256 }
0257
0258 private:
0259 typedef random::geometric_distribution<IntType, RealType> impl_type;
0260 impl_type _impl;
0261 };
0262
0263
0264
0265 }
0266
0267 #endif