File indexing completed on 2025-01-18 09:51:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
0016 #define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
0017
0018 #include <iosfwd>
0019 #include <ios>
0020 #include <istream>
0021 #include <boost/assert.hpp>
0022 #include <boost/config.hpp>
0023 #include <boost/random/detail/config.hpp>
0024 #include <boost/random/detail/operators.hpp>
0025 #include <boost/random/detail/signed_unsigned_tools.hpp>
0026 #include <boost/type_traits/is_integral.hpp>
0027
0028 namespace boost {
0029 namespace random {
0030 namespace detail {
0031
0032 template<class Engine, class T>
0033 T generate_uniform_real(
0034 Engine& eng, T min_value, T max_value,
0035 boost::false_type )
0036 {
0037 for(;;) {
0038 typedef T result_type;
0039 result_type numerator = static_cast<T>(eng() - (eng.min)());
0040 result_type divisor = static_cast<T>((eng.max)() - (eng.min)());
0041 BOOST_ASSERT(divisor > 0);
0042 BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
0043 T result = numerator / divisor * (max_value - min_value) + min_value;
0044 if(result < max_value) return result;
0045 }
0046 }
0047
0048 template<class Engine, class T>
0049 T generate_uniform_real(
0050 Engine& eng, T min_value, T max_value,
0051 boost::true_type )
0052 {
0053 for(;;) {
0054 typedef T result_type;
0055 typedef typename Engine::result_type base_result;
0056 result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)()));
0057 result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1;
0058 BOOST_ASSERT(divisor > 0);
0059 BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
0060 T result = numerator / divisor * (max_value - min_value) + min_value;
0061 if(result < max_value) return result;
0062 }
0063 }
0064
0065 template<class Engine, class T>
0066 inline T generate_uniform_real(Engine& eng, T min_value, T max_value)
0067 {
0068 if(max_value / 2 - min_value / 2 > (std::numeric_limits<T>::max)() / 2)
0069 return 2 * generate_uniform_real(eng, T(min_value / 2), T(max_value / 2));
0070 typedef typename Engine::result_type base_result;
0071 return generate_uniform_real(eng, min_value, max_value,
0072 boost::is_integral<base_result>());
0073 }
0074
0075 }
0076
0077
0078
0079
0080
0081
0082 template<class RealType = double>
0083 class uniform_real_distribution
0084 {
0085 public:
0086 typedef RealType input_type;
0087 typedef RealType result_type;
0088
0089 class param_type
0090 {
0091 public:
0092
0093 typedef uniform_real_distribution distribution_type;
0094
0095
0096
0097
0098
0099
0100 explicit param_type(RealType min_arg = RealType(0.0),
0101 RealType max_arg = RealType(1.0))
0102 : _min(min_arg), _max(max_arg)
0103 {
0104 BOOST_ASSERT(_min < _max);
0105 }
0106
0107
0108 RealType a() const { return _min; }
0109
0110 RealType b() const { return _max; }
0111
0112
0113 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
0114 {
0115 os << parm._min << " " << parm._max;
0116 return os;
0117 }
0118
0119
0120 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
0121 {
0122 RealType min_in, max_in;
0123 if(is >> min_in >> std::ws >> max_in) {
0124 if(min_in <= max_in) {
0125 parm._min = min_in;
0126 parm._max = max_in;
0127 } else {
0128 is.setstate(std::ios_base::failbit);
0129 }
0130 }
0131 return is;
0132 }
0133
0134
0135 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
0136 { return lhs._min == rhs._min && lhs._max == rhs._max; }
0137
0138
0139 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
0140
0141 private:
0142
0143 RealType _min;
0144 RealType _max;
0145 };
0146
0147
0148
0149
0150
0151
0152
0153 explicit uniform_real_distribution(
0154 RealType min_arg = RealType(0.0),
0155 RealType max_arg = RealType(1.0))
0156 : _min(min_arg), _max(max_arg)
0157 {
0158 BOOST_ASSERT(min_arg < max_arg);
0159 }
0160
0161 explicit uniform_real_distribution(const param_type& parm)
0162 : _min(parm.a()), _max(parm.b()) {}
0163
0164
0165 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
0166
0167 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
0168
0169
0170 RealType a() const { return _min; }
0171
0172 RealType b() const { return _max; }
0173
0174
0175 param_type param() const { return param_type(_min, _max); }
0176
0177 void param(const param_type& parm)
0178 {
0179 _min = parm.a();
0180 _max = parm.b();
0181 }
0182
0183
0184
0185
0186
0187 void reset() { }
0188
0189
0190 template<class Engine>
0191 result_type operator()(Engine& eng) const
0192 { return detail::generate_uniform_real(eng, _min, _max); }
0193
0194
0195
0196
0197
0198 template<class Engine>
0199 result_type operator()(Engine& eng, const param_type& parm) const
0200 { return detail::generate_uniform_real(eng, parm.a(), parm.b()); }
0201
0202
0203 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_real_distribution, ud)
0204 {
0205 os << ud.param();
0206 return os;
0207 }
0208
0209
0210 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_real_distribution, ud)
0211 {
0212 param_type parm;
0213 if(is >> parm) {
0214 ud.param(parm);
0215 }
0216 return is;
0217 }
0218
0219
0220
0221
0222
0223 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_real_distribution, lhs, rhs)
0224 { return lhs._min == rhs._min && lhs._max == rhs._max; }
0225
0226
0227
0228
0229
0230 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_real_distribution)
0231
0232 private:
0233 RealType _min;
0234 RealType _max;
0235 };
0236
0237 }
0238 }
0239
0240 #endif