Chris@16
|
1 /* boost random/uniform_real_distribution.hpp header file
|
Chris@16
|
2 *
|
Chris@16
|
3 * Copyright Jens Maurer 2000-2001
|
Chris@16
|
4 * Copyright Steven Watanabe 2011
|
Chris@16
|
5 * Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 * accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 *
|
Chris@16
|
9 * See http://www.boost.org for most recent version including documentation.
|
Chris@16
|
10 *
|
Chris@101
|
11 * $Id$
|
Chris@16
|
12 *
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
Chris@16
|
16 #define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
Chris@16
|
17
|
Chris@16
|
18 #include <iosfwd>
|
Chris@16
|
19 #include <ios>
|
Chris@16
|
20 #include <istream>
|
Chris@16
|
21 #include <boost/assert.hpp>
|
Chris@16
|
22 #include <boost/config.hpp>
|
Chris@16
|
23 #include <boost/random/detail/config.hpp>
|
Chris@16
|
24 #include <boost/random/detail/operators.hpp>
|
Chris@16
|
25 #include <boost/random/detail/signed_unsigned_tools.hpp>
|
Chris@16
|
26 #include <boost/type_traits/is_integral.hpp>
|
Chris@101
|
27 #include <boost/mpl/bool.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 namespace boost {
|
Chris@16
|
30 namespace random {
|
Chris@16
|
31 namespace detail {
|
Chris@16
|
32
|
Chris@16
|
33 template<class Engine, class T>
|
Chris@16
|
34 T generate_uniform_real(
|
Chris@16
|
35 Engine& eng, T min_value, T max_value,
|
Chris@16
|
36 boost::mpl::false_ /** is_integral<Engine::result_type> */)
|
Chris@16
|
37 {
|
Chris@16
|
38 for(;;) {
|
Chris@16
|
39 typedef T result_type;
|
Chris@16
|
40 result_type numerator = static_cast<T>(eng() - (eng.min)());
|
Chris@16
|
41 result_type divisor = static_cast<T>((eng.max)() - (eng.min)());
|
Chris@16
|
42 BOOST_ASSERT(divisor > 0);
|
Chris@16
|
43 BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
|
Chris@16
|
44 T result = numerator / divisor * (max_value - min_value) + min_value;
|
Chris@16
|
45 if(result < max_value) return result;
|
Chris@16
|
46 }
|
Chris@16
|
47 }
|
Chris@16
|
48
|
Chris@16
|
49 template<class Engine, class T>
|
Chris@16
|
50 T generate_uniform_real(
|
Chris@16
|
51 Engine& eng, T min_value, T max_value,
|
Chris@16
|
52 boost::mpl::true_ /** is_integral<Engine::result_type> */)
|
Chris@16
|
53 {
|
Chris@16
|
54 for(;;) {
|
Chris@16
|
55 typedef T result_type;
|
Chris@16
|
56 typedef typename Engine::result_type base_result;
|
Chris@16
|
57 result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)()));
|
Chris@16
|
58 result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1;
|
Chris@16
|
59 BOOST_ASSERT(divisor > 0);
|
Chris@16
|
60 BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
|
Chris@16
|
61 T result = numerator / divisor * (max_value - min_value) + min_value;
|
Chris@16
|
62 if(result < max_value) return result;
|
Chris@16
|
63 }
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 template<class Engine, class T>
|
Chris@16
|
67 inline T generate_uniform_real(Engine& eng, T min_value, T max_value)
|
Chris@16
|
68 {
|
Chris@101
|
69 if(max_value / 2 - min_value / 2 > (std::numeric_limits<T>::max)() / 2)
|
Chris@101
|
70 return 2 * generate_uniform_real(eng, min_value / 2, max_value / 2);
|
Chris@16
|
71 typedef typename Engine::result_type base_result;
|
Chris@16
|
72 return generate_uniform_real(eng, min_value, max_value,
|
Chris@16
|
73 boost::is_integral<base_result>());
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 /**
|
Chris@16
|
79 * The class template uniform_real_distribution models a \random_distribution.
|
Chris@16
|
80 * On each invocation, it returns a random floating-point value uniformly
|
Chris@16
|
81 * distributed in the range [min..max).
|
Chris@16
|
82 */
|
Chris@16
|
83 template<class RealType = double>
|
Chris@16
|
84 class uniform_real_distribution
|
Chris@16
|
85 {
|
Chris@16
|
86 public:
|
Chris@16
|
87 typedef RealType input_type;
|
Chris@16
|
88 typedef RealType result_type;
|
Chris@16
|
89
|
Chris@16
|
90 class param_type
|
Chris@16
|
91 {
|
Chris@16
|
92 public:
|
Chris@16
|
93
|
Chris@16
|
94 typedef uniform_real_distribution distribution_type;
|
Chris@16
|
95
|
Chris@16
|
96 /**
|
Chris@16
|
97 * Constructs the parameters of a uniform_real_distribution.
|
Chris@16
|
98 *
|
Chris@16
|
99 * Requires min <= max
|
Chris@16
|
100 */
|
Chris@16
|
101 explicit param_type(RealType min_arg = RealType(0.0),
|
Chris@16
|
102 RealType max_arg = RealType(1.0))
|
Chris@16
|
103 : _min(min_arg), _max(max_arg)
|
Chris@16
|
104 {
|
Chris@101
|
105 BOOST_ASSERT(_min < _max);
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 /** Returns the minimum value of the distribution. */
|
Chris@16
|
109 RealType a() const { return _min; }
|
Chris@16
|
110 /** Returns the maximum value of the distribution. */
|
Chris@16
|
111 RealType b() const { return _max; }
|
Chris@16
|
112
|
Chris@16
|
113 /** Writes the parameters to a @c std::ostream. */
|
Chris@16
|
114 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
|
Chris@16
|
115 {
|
Chris@16
|
116 os << parm._min << " " << parm._max;
|
Chris@16
|
117 return os;
|
Chris@16
|
118 }
|
Chris@16
|
119
|
Chris@16
|
120 /** Reads the parameters from a @c std::istream. */
|
Chris@16
|
121 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
|
Chris@16
|
122 {
|
Chris@16
|
123 RealType min_in, max_in;
|
Chris@16
|
124 if(is >> min_in >> std::ws >> max_in) {
|
Chris@16
|
125 if(min_in <= max_in) {
|
Chris@16
|
126 parm._min = min_in;
|
Chris@16
|
127 parm._max = max_in;
|
Chris@16
|
128 } else {
|
Chris@16
|
129 is.setstate(std::ios_base::failbit);
|
Chris@16
|
130 }
|
Chris@16
|
131 }
|
Chris@16
|
132 return is;
|
Chris@16
|
133 }
|
Chris@16
|
134
|
Chris@16
|
135 /** Returns true if the two sets of parameters are equal. */
|
Chris@16
|
136 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
|
Chris@16
|
137 { return lhs._min == rhs._min && lhs._max == rhs._max; }
|
Chris@16
|
138
|
Chris@16
|
139 /** Returns true if the two sets of parameters are different. */
|
Chris@16
|
140 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
|
Chris@16
|
141
|
Chris@16
|
142 private:
|
Chris@16
|
143
|
Chris@16
|
144 RealType _min;
|
Chris@16
|
145 RealType _max;
|
Chris@16
|
146 };
|
Chris@16
|
147
|
Chris@16
|
148 /**
|
Chris@16
|
149 * Constructs a uniform_real_distribution. @c min and @c max are
|
Chris@16
|
150 * the parameters of the distribution.
|
Chris@16
|
151 *
|
Chris@16
|
152 * Requires: min <= max
|
Chris@16
|
153 */
|
Chris@16
|
154 explicit uniform_real_distribution(
|
Chris@16
|
155 RealType min_arg = RealType(0.0),
|
Chris@16
|
156 RealType max_arg = RealType(1.0))
|
Chris@16
|
157 : _min(min_arg), _max(max_arg)
|
Chris@16
|
158 {
|
Chris@101
|
159 BOOST_ASSERT(min_arg < max_arg);
|
Chris@16
|
160 }
|
Chris@16
|
161 /** Constructs a uniform_real_distribution from its parameters. */
|
Chris@16
|
162 explicit uniform_real_distribution(const param_type& parm)
|
Chris@16
|
163 : _min(parm.a()), _max(parm.b()) {}
|
Chris@16
|
164
|
Chris@16
|
165 /** Returns the minimum value of the distribution */
|
Chris@16
|
166 RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
|
Chris@16
|
167 /** Returns the maximum value of the distribution */
|
Chris@16
|
168 RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
|
Chris@16
|
169
|
Chris@16
|
170 /** Returns the minimum value of the distribution */
|
Chris@16
|
171 RealType a() const { return _min; }
|
Chris@16
|
172 /** Returns the maximum value of the distribution */
|
Chris@16
|
173 RealType b() const { return _max; }
|
Chris@16
|
174
|
Chris@16
|
175 /** Returns the parameters of the distribution. */
|
Chris@16
|
176 param_type param() const { return param_type(_min, _max); }
|
Chris@16
|
177 /** Sets the parameters of the distribution. */
|
Chris@16
|
178 void param(const param_type& parm)
|
Chris@16
|
179 {
|
Chris@16
|
180 _min = parm.a();
|
Chris@16
|
181 _max = parm.b();
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 /**
|
Chris@16
|
185 * Effects: Subsequent uses of the distribution do not depend
|
Chris@16
|
186 * on values produced by any engine prior to invoking reset.
|
Chris@16
|
187 */
|
Chris@16
|
188 void reset() { }
|
Chris@16
|
189
|
Chris@16
|
190 /** Returns a value uniformly distributed in the range [min, max). */
|
Chris@16
|
191 template<class Engine>
|
Chris@16
|
192 result_type operator()(Engine& eng) const
|
Chris@16
|
193 { return detail::generate_uniform_real(eng, _min, _max); }
|
Chris@16
|
194
|
Chris@16
|
195 /**
|
Chris@16
|
196 * Returns a value uniformly distributed in the range
|
Chris@16
|
197 * [param.a(), param.b()).
|
Chris@16
|
198 */
|
Chris@16
|
199 template<class Engine>
|
Chris@16
|
200 result_type operator()(Engine& eng, const param_type& parm) const
|
Chris@16
|
201 { return detail::generate_uniform_real(eng, parm.a(), parm.b()); }
|
Chris@16
|
202
|
Chris@16
|
203 /** Writes the distribution to a @c std::ostream. */
|
Chris@16
|
204 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_real_distribution, ud)
|
Chris@16
|
205 {
|
Chris@16
|
206 os << ud.param();
|
Chris@16
|
207 return os;
|
Chris@16
|
208 }
|
Chris@16
|
209
|
Chris@16
|
210 /** Reads the distribution from a @c std::istream. */
|
Chris@16
|
211 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_real_distribution, ud)
|
Chris@16
|
212 {
|
Chris@16
|
213 param_type parm;
|
Chris@16
|
214 if(is >> parm) {
|
Chris@16
|
215 ud.param(parm);
|
Chris@16
|
216 }
|
Chris@16
|
217 return is;
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 /**
|
Chris@16
|
221 * Returns true if the two distributions will produce identical sequences
|
Chris@16
|
222 * of values given equal generators.
|
Chris@16
|
223 */
|
Chris@16
|
224 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_real_distribution, lhs, rhs)
|
Chris@16
|
225 { return lhs._min == rhs._min && lhs._max == rhs._max; }
|
Chris@16
|
226
|
Chris@16
|
227 /**
|
Chris@16
|
228 * Returns true if the two distributions may produce different sequences
|
Chris@16
|
229 * of values given equal generators.
|
Chris@16
|
230 */
|
Chris@16
|
231 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_real_distribution)
|
Chris@16
|
232
|
Chris@16
|
233 private:
|
Chris@16
|
234 RealType _min;
|
Chris@16
|
235 RealType _max;
|
Chris@16
|
236 };
|
Chris@16
|
237
|
Chris@16
|
238 } // namespace random
|
Chris@16
|
239 } // namespace boost
|
Chris@16
|
240
|
Chris@16
|
241 #endif // BOOST_RANDOM_UNIFORM_INT_HPP
|