Chris@16
|
1 /* boost random/uniform_01.hpp header file
|
Chris@16
|
2 *
|
Chris@16
|
3 * Copyright Jens Maurer 2000-2001
|
Chris@16
|
4 * Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 * accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 *
|
Chris@16
|
8 * See http://www.boost.org for most recent version including documentation.
|
Chris@16
|
9 *
|
Chris@101
|
10 * $Id$
|
Chris@16
|
11 *
|
Chris@16
|
12 * Revision history
|
Chris@16
|
13 * 2001-02-18 moved to individual header files
|
Chris@16
|
14 */
|
Chris@16
|
15
|
Chris@16
|
16 #ifndef BOOST_RANDOM_UNIFORM_01_HPP
|
Chris@16
|
17 #define BOOST_RANDOM_UNIFORM_01_HPP
|
Chris@16
|
18
|
Chris@16
|
19 #include <iostream>
|
Chris@16
|
20 #include <boost/config.hpp>
|
Chris@16
|
21 #include <boost/limits.hpp>
|
Chris@16
|
22 #include <boost/static_assert.hpp>
|
Chris@16
|
23 #include <boost/random/detail/config.hpp>
|
Chris@16
|
24 #include <boost/random/detail/ptr_helper.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/random/detail/disable_warnings.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost {
|
Chris@16
|
29 namespace random {
|
Chris@16
|
30
|
Chris@16
|
31 #ifdef BOOST_RANDOM_DOXYGEN
|
Chris@16
|
32
|
Chris@16
|
33 /**
|
Chris@16
|
34 * The distribution function uniform_01 models a \random_distribution.
|
Chris@16
|
35 * On each invocation, it returns a random floating-point value
|
Chris@16
|
36 * uniformly distributed in the range [0..1).
|
Chris@16
|
37 *
|
Chris@16
|
38 * The template parameter RealType shall denote a float-like value type
|
Chris@16
|
39 * with support for binary operators +, -, and /.
|
Chris@16
|
40 *
|
Chris@16
|
41 * Note: The current implementation is buggy, because it may not fill
|
Chris@16
|
42 * all of the mantissa with random bits. I'm unsure how to fill a
|
Chris@16
|
43 * (to-be-invented) @c boost::bigfloat class with random bits efficiently.
|
Chris@16
|
44 * It's probably time for a traits class.
|
Chris@16
|
45 */
|
Chris@16
|
46 template<class RealType = double>
|
Chris@16
|
47 class uniform_01
|
Chris@16
|
48 {
|
Chris@16
|
49 public:
|
Chris@16
|
50 typedef RealType input_type;
|
Chris@16
|
51 typedef RealType result_type;
|
Chris@16
|
52 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const;
|
Chris@16
|
53 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const;
|
Chris@16
|
54 void reset();
|
Chris@16
|
55
|
Chris@16
|
56 template<class Engine>
|
Chris@16
|
57 result_type operator()(Engine& eng);
|
Chris@16
|
58
|
Chris@16
|
59 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
|
Chris@16
|
60 template<class CharT, class Traits>
|
Chris@16
|
61 friend std::basic_ostream<CharT,Traits>&
|
Chris@16
|
62 operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
|
Chris@16
|
63 {
|
Chris@16
|
64 return os;
|
Chris@16
|
65 }
|
Chris@16
|
66
|
Chris@16
|
67 template<class CharT, class Traits>
|
Chris@16
|
68 friend std::basic_istream<CharT,Traits>&
|
Chris@16
|
69 operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
|
Chris@16
|
70 {
|
Chris@16
|
71 return is;
|
Chris@16
|
72 }
|
Chris@16
|
73 #endif
|
Chris@16
|
74 };
|
Chris@16
|
75
|
Chris@16
|
76 #else
|
Chris@16
|
77
|
Chris@16
|
78 namespace detail {
|
Chris@16
|
79
|
Chris@16
|
80 template<class RealType>
|
Chris@16
|
81 class new_uniform_01
|
Chris@16
|
82 {
|
Chris@16
|
83 public:
|
Chris@16
|
84 typedef RealType input_type;
|
Chris@16
|
85 typedef RealType result_type;
|
Chris@16
|
86 // compiler-generated copy ctor and copy assignment are fine
|
Chris@16
|
87 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
|
Chris@16
|
88 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
|
Chris@16
|
89 void reset() { }
|
Chris@16
|
90
|
Chris@16
|
91 template<class Engine>
|
Chris@16
|
92 result_type operator()(Engine& eng) {
|
Chris@16
|
93 for (;;) {
|
Chris@16
|
94 typedef typename Engine::result_type base_result;
|
Chris@16
|
95 result_type factor = result_type(1) /
|
Chris@16
|
96 (result_type((eng.max)()-(eng.min)()) +
|
Chris@16
|
97 result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));
|
Chris@16
|
98 result_type result = result_type(eng() - (eng.min)()) * factor;
|
Chris@16
|
99 if (result < result_type(1))
|
Chris@16
|
100 return result;
|
Chris@16
|
101 }
|
Chris@16
|
102 }
|
Chris@16
|
103
|
Chris@16
|
104 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
|
Chris@16
|
105 template<class CharT, class Traits>
|
Chris@16
|
106 friend std::basic_ostream<CharT,Traits>&
|
Chris@16
|
107 operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
|
Chris@16
|
108 {
|
Chris@16
|
109 return os;
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 template<class CharT, class Traits>
|
Chris@16
|
113 friend std::basic_istream<CharT,Traits>&
|
Chris@16
|
114 operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
|
Chris@16
|
115 {
|
Chris@16
|
116 return is;
|
Chris@16
|
117 }
|
Chris@16
|
118 #endif
|
Chris@16
|
119 };
|
Chris@16
|
120
|
Chris@16
|
121 template<class UniformRandomNumberGenerator, class RealType>
|
Chris@16
|
122 class backward_compatible_uniform_01
|
Chris@16
|
123 {
|
Chris@16
|
124 typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
|
Chris@16
|
125 public:
|
Chris@16
|
126 typedef UniformRandomNumberGenerator base_type;
|
Chris@16
|
127 typedef RealType result_type;
|
Chris@16
|
128
|
Chris@16
|
129 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
|
Chris@16
|
130
|
Chris@101
|
131 #if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
|
Chris@16
|
132 BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
|
Chris@16
|
133 #endif
|
Chris@16
|
134
|
Chris@16
|
135 explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
|
Chris@16
|
136 : _rng(rng),
|
Chris@16
|
137 _factor(result_type(1) /
|
Chris@16
|
138 (result_type((base().max)()-(base().min)()) +
|
Chris@16
|
139 result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
|
Chris@16
|
140 {
|
Chris@16
|
141 }
|
Chris@16
|
142 // compiler-generated copy ctor and copy assignment are fine
|
Chris@16
|
143
|
Chris@16
|
144 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
|
Chris@16
|
145 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
|
Chris@16
|
146 typename traits::value_type& base() { return traits::ref(_rng); }
|
Chris@16
|
147 const typename traits::value_type& base() const { return traits::ref(_rng); }
|
Chris@16
|
148 void reset() { }
|
Chris@16
|
149
|
Chris@16
|
150 result_type operator()() {
|
Chris@16
|
151 for (;;) {
|
Chris@16
|
152 result_type result = result_type(base()() - (base().min)()) * _factor;
|
Chris@16
|
153 if (result < result_type(1))
|
Chris@16
|
154 return result;
|
Chris@16
|
155 }
|
Chris@16
|
156 }
|
Chris@16
|
157
|
Chris@16
|
158 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
Chris@16
|
159 template<class CharT, class Traits>
|
Chris@16
|
160 friend std::basic_ostream<CharT,Traits>&
|
Chris@16
|
161 operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)
|
Chris@16
|
162 {
|
Chris@16
|
163 os << u._rng;
|
Chris@16
|
164 return os;
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 template<class CharT, class Traits>
|
Chris@16
|
168 friend std::basic_istream<CharT,Traits>&
|
Chris@16
|
169 operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)
|
Chris@16
|
170 {
|
Chris@16
|
171 is >> u._rng;
|
Chris@16
|
172 return is;
|
Chris@16
|
173 }
|
Chris@16
|
174 #endif
|
Chris@16
|
175
|
Chris@16
|
176 private:
|
Chris@16
|
177 typedef typename traits::value_type::result_type base_result;
|
Chris@16
|
178 UniformRandomNumberGenerator _rng;
|
Chris@16
|
179 result_type _factor;
|
Chris@16
|
180 };
|
Chris@16
|
181
|
Chris@16
|
182 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
183 // A definition is required even for integral static constants
|
Chris@16
|
184 template<class UniformRandomNumberGenerator, class RealType>
|
Chris@16
|
185 const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
|
Chris@16
|
186 #endif
|
Chris@16
|
187
|
Chris@16
|
188 template<class UniformRandomNumberGenerator>
|
Chris@16
|
189 struct select_uniform_01
|
Chris@16
|
190 {
|
Chris@16
|
191 template<class RealType>
|
Chris@16
|
192 struct apply
|
Chris@16
|
193 {
|
Chris@16
|
194 typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;
|
Chris@16
|
195 };
|
Chris@16
|
196 };
|
Chris@16
|
197
|
Chris@16
|
198 template<>
|
Chris@16
|
199 struct select_uniform_01<float>
|
Chris@16
|
200 {
|
Chris@16
|
201 template<class RealType>
|
Chris@16
|
202 struct apply
|
Chris@16
|
203 {
|
Chris@16
|
204 typedef new_uniform_01<float> type;
|
Chris@16
|
205 };
|
Chris@16
|
206 };
|
Chris@16
|
207
|
Chris@16
|
208 template<>
|
Chris@16
|
209 struct select_uniform_01<double>
|
Chris@16
|
210 {
|
Chris@16
|
211 template<class RealType>
|
Chris@16
|
212 struct apply
|
Chris@16
|
213 {
|
Chris@16
|
214 typedef new_uniform_01<double> type;
|
Chris@16
|
215 };
|
Chris@16
|
216 };
|
Chris@16
|
217
|
Chris@16
|
218 template<>
|
Chris@16
|
219 struct select_uniform_01<long double>
|
Chris@16
|
220 {
|
Chris@16
|
221 template<class RealType>
|
Chris@16
|
222 struct apply
|
Chris@16
|
223 {
|
Chris@16
|
224 typedef new_uniform_01<long double> type;
|
Chris@16
|
225 };
|
Chris@16
|
226 };
|
Chris@16
|
227
|
Chris@16
|
228 }
|
Chris@16
|
229
|
Chris@16
|
230 // Because it is so commonly used: uniform distribution on the real [0..1)
|
Chris@16
|
231 // range. This allows for specializations to avoid a costly int -> float
|
Chris@16
|
232 // conversion plus float multiplication
|
Chris@16
|
233 template<class UniformRandomNumberGenerator = double, class RealType = double>
|
Chris@16
|
234 class uniform_01
|
Chris@16
|
235 : public detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type
|
Chris@16
|
236 {
|
Chris@16
|
237 typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;
|
Chris@16
|
238 typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
|
Chris@16
|
239 public:
|
Chris@16
|
240
|
Chris@16
|
241 uniform_01() {}
|
Chris@16
|
242
|
Chris@16
|
243 explicit uniform_01(typename traits::rvalue_type rng)
|
Chris@16
|
244 : impl_type(rng)
|
Chris@16
|
245 {
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 #if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
Chris@16
|
249 template<class CharT, class Traits>
|
Chris@16
|
250 friend std::basic_ostream<CharT,Traits>&
|
Chris@16
|
251 operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
|
Chris@16
|
252 {
|
Chris@16
|
253 os << static_cast<const impl_type&>(u);
|
Chris@16
|
254 return os;
|
Chris@16
|
255 }
|
Chris@16
|
256
|
Chris@16
|
257 template<class CharT, class Traits>
|
Chris@16
|
258 friend std::basic_istream<CharT,Traits>&
|
Chris@16
|
259 operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
|
Chris@16
|
260 {
|
Chris@16
|
261 is >> static_cast<impl_type&>(u);
|
Chris@16
|
262 return is;
|
Chris@16
|
263 }
|
Chris@16
|
264 #endif
|
Chris@16
|
265 };
|
Chris@16
|
266
|
Chris@16
|
267 #endif
|
Chris@16
|
268
|
Chris@16
|
269 } // namespace random
|
Chris@16
|
270
|
Chris@16
|
271 using random::uniform_01;
|
Chris@16
|
272
|
Chris@16
|
273 } // namespace boost
|
Chris@16
|
274
|
Chris@16
|
275 #include <boost/random/detail/enable_warnings.hpp>
|
Chris@16
|
276
|
Chris@16
|
277 #endif // BOOST_RANDOM_UNIFORM_01_HPP
|