Chris@16
|
1 /* boost random/piecewise_constant_distribution.hpp header file
|
Chris@16
|
2 *
|
Chris@16
|
3 * Copyright Steven Watanabe 2011
|
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
|
Chris@16
|
13 #ifndef BOOST_RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_HPP_INCLUDED
|
Chris@16
|
14 #define BOOST_RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_HPP_INCLUDED
|
Chris@16
|
15
|
Chris@16
|
16 #include <vector>
|
Chris@16
|
17 #include <numeric>
|
Chris@16
|
18 #include <boost/assert.hpp>
|
Chris@16
|
19 #include <boost/random/uniform_real.hpp>
|
Chris@16
|
20 #include <boost/random/discrete_distribution.hpp>
|
Chris@16
|
21 #include <boost/random/detail/config.hpp>
|
Chris@16
|
22 #include <boost/random/detail/operators.hpp>
|
Chris@16
|
23 #include <boost/random/detail/vector_io.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
|
Chris@16
|
26 #include <initializer_list>
|
Chris@16
|
27 #endif
|
Chris@16
|
28
|
Chris@16
|
29 #include <boost/range/begin.hpp>
|
Chris@16
|
30 #include <boost/range/end.hpp>
|
Chris@16
|
31
|
Chris@16
|
32 namespace boost {
|
Chris@16
|
33 namespace random {
|
Chris@16
|
34
|
Chris@16
|
35 /**
|
Chris@16
|
36 * The class @c piecewise_constant_distribution models a \random_distribution.
|
Chris@16
|
37 */
|
Chris@16
|
38 template<class RealType = double, class WeightType = double>
|
Chris@16
|
39 class piecewise_constant_distribution {
|
Chris@16
|
40 public:
|
Chris@16
|
41 typedef std::size_t input_type;
|
Chris@16
|
42 typedef RealType result_type;
|
Chris@16
|
43
|
Chris@16
|
44 class param_type {
|
Chris@16
|
45 public:
|
Chris@16
|
46
|
Chris@16
|
47 typedef piecewise_constant_distribution distribution_type;
|
Chris@16
|
48
|
Chris@16
|
49 /**
|
Chris@16
|
50 * Constructs a @c param_type object, representing a distribution
|
Chris@16
|
51 * that produces values uniformly distributed in the range [0, 1).
|
Chris@16
|
52 */
|
Chris@16
|
53 param_type()
|
Chris@16
|
54 {
|
Chris@16
|
55 _weights.push_back(WeightType(1));
|
Chris@16
|
56 _intervals.push_back(RealType(0));
|
Chris@16
|
57 _intervals.push_back(RealType(1));
|
Chris@16
|
58 }
|
Chris@16
|
59 /**
|
Chris@16
|
60 * Constructs a @c param_type object from two iterator ranges
|
Chris@16
|
61 * containing the interval boundaries and the interval weights.
|
Chris@16
|
62 * If there are less than two boundaries, then this is equivalent to
|
Chris@16
|
63 * the default constructor and creates a single interval, [0, 1).
|
Chris@16
|
64 *
|
Chris@16
|
65 * The values of the interval boundaries must be strictly
|
Chris@16
|
66 * increasing, and the number of weights must be one less than
|
Chris@16
|
67 * the number of interval boundaries. If there are extra
|
Chris@16
|
68 * weights, they are ignored.
|
Chris@16
|
69 */
|
Chris@16
|
70 template<class IntervalIter, class WeightIter>
|
Chris@16
|
71 param_type(IntervalIter intervals_first, IntervalIter intervals_last,
|
Chris@16
|
72 WeightIter weight_first)
|
Chris@16
|
73 : _intervals(intervals_first, intervals_last)
|
Chris@16
|
74 {
|
Chris@16
|
75 if(_intervals.size() < 2) {
|
Chris@16
|
76 _intervals.clear();
|
Chris@16
|
77 _intervals.push_back(RealType(0));
|
Chris@16
|
78 _intervals.push_back(RealType(1));
|
Chris@16
|
79 _weights.push_back(WeightType(1));
|
Chris@16
|
80 } else {
|
Chris@16
|
81 _weights.reserve(_intervals.size() - 1);
|
Chris@16
|
82 for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
|
Chris@16
|
83 _weights.push_back(*weight_first++);
|
Chris@16
|
84 }
|
Chris@16
|
85 }
|
Chris@16
|
86 }
|
Chris@16
|
87 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
|
Chris@16
|
88 /**
|
Chris@16
|
89 * Constructs a @c param_type object from an
|
Chris@16
|
90 * initializer_list containing the interval boundaries
|
Chris@16
|
91 * and a unary function specifying the weights. Each
|
Chris@16
|
92 * weight is determined by calling the function at the
|
Chris@16
|
93 * midpoint of the corresponding interval.
|
Chris@16
|
94 *
|
Chris@16
|
95 * If the initializer_list contains less than two elements,
|
Chris@16
|
96 * this is equivalent to the default constructor and the
|
Chris@16
|
97 * distribution will produce values uniformly distributed
|
Chris@16
|
98 * in the range [0, 1).
|
Chris@16
|
99 */
|
Chris@16
|
100 template<class T, class F>
|
Chris@16
|
101 param_type(const std::initializer_list<T>& il, F f)
|
Chris@16
|
102 : _intervals(il.begin(), il.end())
|
Chris@16
|
103 {
|
Chris@16
|
104 if(_intervals.size() < 2) {
|
Chris@16
|
105 _intervals.clear();
|
Chris@16
|
106 _intervals.push_back(RealType(0));
|
Chris@16
|
107 _intervals.push_back(RealType(1));
|
Chris@16
|
108 _weights.push_back(WeightType(1));
|
Chris@16
|
109 } else {
|
Chris@16
|
110 _weights.reserve(_intervals.size() - 1);
|
Chris@16
|
111 for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
|
Chris@16
|
112 RealType midpoint = (_intervals[i] + _intervals[i + 1]) / 2;
|
Chris@16
|
113 _weights.push_back(f(midpoint));
|
Chris@16
|
114 }
|
Chris@16
|
115 }
|
Chris@16
|
116 }
|
Chris@16
|
117 #endif
|
Chris@16
|
118 /**
|
Chris@16
|
119 * Constructs a @c param_type object from Boost.Range
|
Chris@16
|
120 * ranges holding the interval boundaries and the weights. If
|
Chris@16
|
121 * there are less than two interval boundaries, this is equivalent
|
Chris@16
|
122 * to the default constructor and the distribution will produce
|
Chris@16
|
123 * values uniformly distributed in the range [0, 1). The
|
Chris@16
|
124 * number of weights must be one less than the number of
|
Chris@16
|
125 * interval boundaries.
|
Chris@16
|
126 */
|
Chris@16
|
127 template<class IntervalRange, class WeightRange>
|
Chris@16
|
128 param_type(const IntervalRange& intervals_arg,
|
Chris@16
|
129 const WeightRange& weights_arg)
|
Chris@16
|
130 : _intervals(boost::begin(intervals_arg), boost::end(intervals_arg)),
|
Chris@16
|
131 _weights(boost::begin(weights_arg), boost::end(weights_arg))
|
Chris@16
|
132 {
|
Chris@16
|
133 if(_intervals.size() < 2) {
|
Chris@16
|
134 _intervals.clear();
|
Chris@16
|
135 _intervals.push_back(RealType(0));
|
Chris@16
|
136 _intervals.push_back(RealType(1));
|
Chris@16
|
137 _weights.push_back(WeightType(1));
|
Chris@16
|
138 }
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 /**
|
Chris@16
|
142 * Constructs the parameters for a distribution that approximates a
|
Chris@16
|
143 * function. The range of the distribution is [xmin, xmax). This
|
Chris@16
|
144 * range is divided into nw equally sized intervals and the weights
|
Chris@16
|
145 * are found by calling the unary function f on the midpoints of the
|
Chris@16
|
146 * intervals.
|
Chris@16
|
147 */
|
Chris@16
|
148 template<class F>
|
Chris@16
|
149 param_type(std::size_t nw, RealType xmin, RealType xmax, F f)
|
Chris@16
|
150 {
|
Chris@16
|
151 std::size_t n = (nw == 0) ? 1 : nw;
|
Chris@16
|
152 double delta = (xmax - xmin) / n;
|
Chris@16
|
153 BOOST_ASSERT(delta > 0);
|
Chris@16
|
154 for(std::size_t k = 0; k < n; ++k) {
|
Chris@16
|
155 _weights.push_back(f(xmin + k*delta + delta/2));
|
Chris@16
|
156 _intervals.push_back(xmin + k*delta);
|
Chris@16
|
157 }
|
Chris@16
|
158 _intervals.push_back(xmax);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 /** Returns a vector containing the interval boundaries. */
|
Chris@16
|
162 std::vector<RealType> intervals() const { return _intervals; }
|
Chris@16
|
163
|
Chris@16
|
164 /**
|
Chris@16
|
165 * Returns a vector containing the probability densities
|
Chris@16
|
166 * over all the intervals of the distribution.
|
Chris@16
|
167 */
|
Chris@16
|
168 std::vector<RealType> densities() const
|
Chris@16
|
169 {
|
Chris@16
|
170 RealType sum = std::accumulate(_weights.begin(), _weights.end(),
|
Chris@16
|
171 static_cast<RealType>(0));
|
Chris@16
|
172 std::vector<RealType> result;
|
Chris@16
|
173 result.reserve(_weights.size());
|
Chris@16
|
174 for(std::size_t i = 0; i < _weights.size(); ++i) {
|
Chris@16
|
175 RealType width = _intervals[i + 1] - _intervals[i];
|
Chris@16
|
176 result.push_back(_weights[i] / (sum * width));
|
Chris@16
|
177 }
|
Chris@16
|
178 return result;
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 /** Writes the parameters to a @c std::ostream. */
|
Chris@16
|
182 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
|
Chris@16
|
183 {
|
Chris@16
|
184 detail::print_vector(os, parm._intervals);
|
Chris@16
|
185 detail::print_vector(os, parm._weights);
|
Chris@16
|
186 return os;
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189 /** Reads the parameters from a @c std::istream. */
|
Chris@16
|
190 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
|
Chris@16
|
191 {
|
Chris@16
|
192 std::vector<RealType> new_intervals;
|
Chris@16
|
193 std::vector<WeightType> new_weights;
|
Chris@16
|
194 detail::read_vector(is, new_intervals);
|
Chris@16
|
195 detail::read_vector(is, new_weights);
|
Chris@16
|
196 if(is) {
|
Chris@16
|
197 parm._intervals.swap(new_intervals);
|
Chris@16
|
198 parm._weights.swap(new_weights);
|
Chris@16
|
199 }
|
Chris@16
|
200 return is;
|
Chris@16
|
201 }
|
Chris@16
|
202
|
Chris@16
|
203 /** Returns true if the two sets of parameters are the same. */
|
Chris@16
|
204 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
|
Chris@16
|
205 {
|
Chris@16
|
206 return lhs._intervals == rhs._intervals
|
Chris@16
|
207 && lhs._weights == rhs._weights;
|
Chris@16
|
208 }
|
Chris@16
|
209 /** Returns true if the two sets of parameters are different. */
|
Chris@16
|
210 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
|
Chris@16
|
211
|
Chris@16
|
212 private:
|
Chris@16
|
213
|
Chris@16
|
214 friend class piecewise_constant_distribution;
|
Chris@16
|
215
|
Chris@16
|
216 std::vector<RealType> _intervals;
|
Chris@16
|
217 std::vector<WeightType> _weights;
|
Chris@16
|
218 };
|
Chris@16
|
219
|
Chris@16
|
220 /**
|
Chris@16
|
221 * Creates a new @c piecewise_constant_distribution with
|
Chris@16
|
222 * a single interval, [0, 1).
|
Chris@16
|
223 */
|
Chris@16
|
224 piecewise_constant_distribution()
|
Chris@16
|
225 {
|
Chris@16
|
226 _intervals.push_back(RealType(0));
|
Chris@16
|
227 _intervals.push_back(RealType(1));
|
Chris@16
|
228 }
|
Chris@16
|
229 /**
|
Chris@16
|
230 * Constructs a piecewise_constant_distribution from two iterator ranges
|
Chris@16
|
231 * containing the interval boundaries and the interval weights.
|
Chris@16
|
232 * If there are less than two boundaries, then this is equivalent to
|
Chris@16
|
233 * the default constructor and creates a single interval, [0, 1).
|
Chris@16
|
234 *
|
Chris@16
|
235 * The values of the interval boundaries must be strictly
|
Chris@16
|
236 * increasing, and the number of weights must be one less than
|
Chris@16
|
237 * the number of interval boundaries. If there are extra
|
Chris@16
|
238 * weights, they are ignored.
|
Chris@16
|
239 *
|
Chris@16
|
240 * For example,
|
Chris@16
|
241 *
|
Chris@16
|
242 * @code
|
Chris@16
|
243 * double intervals[] = { 0.0, 1.0, 4.0 };
|
Chris@16
|
244 * double weights[] = { 1.0, 1.0 };
|
Chris@16
|
245 * piecewise_constant_distribution<> dist(
|
Chris@16
|
246 * &intervals[0], &intervals[0] + 3, &weights[0]);
|
Chris@16
|
247 * @endcode
|
Chris@16
|
248 *
|
Chris@16
|
249 * The distribution has a 50% chance of producing a
|
Chris@16
|
250 * value between 0 and 1 and a 50% chance of producing
|
Chris@16
|
251 * a value between 1 and 4.
|
Chris@16
|
252 */
|
Chris@16
|
253 template<class IntervalIter, class WeightIter>
|
Chris@16
|
254 piecewise_constant_distribution(IntervalIter first_interval,
|
Chris@16
|
255 IntervalIter last_interval,
|
Chris@16
|
256 WeightIter first_weight)
|
Chris@16
|
257 : _intervals(first_interval, last_interval)
|
Chris@16
|
258 {
|
Chris@16
|
259 if(_intervals.size() < 2) {
|
Chris@16
|
260 _intervals.clear();
|
Chris@16
|
261 _intervals.push_back(RealType(0));
|
Chris@16
|
262 _intervals.push_back(RealType(1));
|
Chris@16
|
263 } else {
|
Chris@16
|
264 std::vector<WeightType> actual_weights;
|
Chris@16
|
265 actual_weights.reserve(_intervals.size() - 1);
|
Chris@16
|
266 for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
|
Chris@16
|
267 actual_weights.push_back(*first_weight++);
|
Chris@16
|
268 }
|
Chris@16
|
269 typedef discrete_distribution<std::size_t, WeightType> bins_type;
|
Chris@16
|
270 typename bins_type::param_type bins_param(actual_weights);
|
Chris@16
|
271 _bins.param(bins_param);
|
Chris@16
|
272 }
|
Chris@16
|
273 }
|
Chris@16
|
274 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
|
Chris@16
|
275 /**
|
Chris@16
|
276 * Constructs a piecewise_constant_distribution from an
|
Chris@16
|
277 * initializer_list containing the interval boundaries
|
Chris@16
|
278 * and a unary function specifying the weights. Each
|
Chris@16
|
279 * weight is determined by calling the function at the
|
Chris@16
|
280 * midpoint of the corresponding interval.
|
Chris@16
|
281 *
|
Chris@16
|
282 * If the initializer_list contains less than two elements,
|
Chris@16
|
283 * this is equivalent to the default constructor and the
|
Chris@16
|
284 * distribution will produce values uniformly distributed
|
Chris@16
|
285 * in the range [0, 1).
|
Chris@16
|
286 */
|
Chris@16
|
287 template<class T, class F>
|
Chris@16
|
288 piecewise_constant_distribution(std::initializer_list<T> il, F f)
|
Chris@16
|
289 : _intervals(il.begin(), il.end())
|
Chris@16
|
290 {
|
Chris@16
|
291 if(_intervals.size() < 2) {
|
Chris@16
|
292 _intervals.clear();
|
Chris@16
|
293 _intervals.push_back(RealType(0));
|
Chris@16
|
294 _intervals.push_back(RealType(1));
|
Chris@16
|
295 } else {
|
Chris@16
|
296 std::vector<WeightType> actual_weights;
|
Chris@16
|
297 actual_weights.reserve(_intervals.size() - 1);
|
Chris@16
|
298 for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
|
Chris@16
|
299 RealType midpoint = (_intervals[i] + _intervals[i + 1]) / 2;
|
Chris@16
|
300 actual_weights.push_back(f(midpoint));
|
Chris@16
|
301 }
|
Chris@16
|
302 typedef discrete_distribution<std::size_t, WeightType> bins_type;
|
Chris@16
|
303 typename bins_type::param_type bins_param(actual_weights);
|
Chris@16
|
304 _bins.param(bins_param);
|
Chris@16
|
305 }
|
Chris@16
|
306 }
|
Chris@16
|
307 #endif
|
Chris@16
|
308 /**
|
Chris@16
|
309 * Constructs a piecewise_constant_distribution from Boost.Range
|
Chris@16
|
310 * ranges holding the interval boundaries and the weights. If
|
Chris@16
|
311 * there are less than two interval boundaries, this is equivalent
|
Chris@16
|
312 * to the default constructor and the distribution will produce
|
Chris@16
|
313 * values uniformly distributed in the range [0, 1). The
|
Chris@16
|
314 * number of weights must be one less than the number of
|
Chris@16
|
315 * interval boundaries.
|
Chris@16
|
316 */
|
Chris@16
|
317 template<class IntervalsRange, class WeightsRange>
|
Chris@16
|
318 piecewise_constant_distribution(const IntervalsRange& intervals_arg,
|
Chris@16
|
319 const WeightsRange& weights_arg)
|
Chris@16
|
320 : _bins(weights_arg),
|
Chris@16
|
321 _intervals(boost::begin(intervals_arg), boost::end(intervals_arg))
|
Chris@16
|
322 {
|
Chris@16
|
323 if(_intervals.size() < 2) {
|
Chris@16
|
324 _intervals.clear();
|
Chris@16
|
325 _intervals.push_back(RealType(0));
|
Chris@16
|
326 _intervals.push_back(RealType(1));
|
Chris@16
|
327 }
|
Chris@16
|
328 }
|
Chris@16
|
329 /**
|
Chris@16
|
330 * Constructs a piecewise_constant_distribution that approximates a
|
Chris@16
|
331 * function. The range of the distribution is [xmin, xmax). This
|
Chris@16
|
332 * range is divided into nw equally sized intervals and the weights
|
Chris@16
|
333 * are found by calling the unary function f on the midpoints of the
|
Chris@16
|
334 * intervals.
|
Chris@16
|
335 */
|
Chris@16
|
336 template<class F>
|
Chris@16
|
337 piecewise_constant_distribution(std::size_t nw,
|
Chris@16
|
338 RealType xmin,
|
Chris@16
|
339 RealType xmax,
|
Chris@16
|
340 F f)
|
Chris@16
|
341 : _bins(nw, xmin, xmax, f)
|
Chris@16
|
342 {
|
Chris@16
|
343 if(nw == 0) { nw = 1; }
|
Chris@16
|
344 RealType delta = (xmax - xmin) / nw;
|
Chris@16
|
345 _intervals.reserve(nw + 1);
|
Chris@16
|
346 for(std::size_t i = 0; i < nw; ++i) {
|
Chris@16
|
347 _intervals.push_back(xmin + i * delta);
|
Chris@16
|
348 }
|
Chris@16
|
349 _intervals.push_back(xmax);
|
Chris@16
|
350 }
|
Chris@16
|
351 /**
|
Chris@16
|
352 * Constructs a piecewise_constant_distribution from its parameters.
|
Chris@16
|
353 */
|
Chris@16
|
354 explicit piecewise_constant_distribution(const param_type& parm)
|
Chris@16
|
355 : _bins(parm._weights),
|
Chris@16
|
356 _intervals(parm._intervals)
|
Chris@16
|
357 {
|
Chris@16
|
358 }
|
Chris@16
|
359
|
Chris@16
|
360 /**
|
Chris@16
|
361 * Returns a value distributed according to the parameters of the
|
Chris@16
|
362 * piecewist_constant_distribution.
|
Chris@16
|
363 */
|
Chris@16
|
364 template<class URNG>
|
Chris@16
|
365 RealType operator()(URNG& urng) const
|
Chris@16
|
366 {
|
Chris@16
|
367 std::size_t i = _bins(urng);
|
Chris@16
|
368 return uniform_real<RealType>(_intervals[i], _intervals[i+1])(urng);
|
Chris@16
|
369 }
|
Chris@16
|
370
|
Chris@16
|
371 /**
|
Chris@16
|
372 * Returns a value distributed according to the parameters
|
Chris@16
|
373 * specified by param.
|
Chris@16
|
374 */
|
Chris@16
|
375 template<class URNG>
|
Chris@16
|
376 RealType operator()(URNG& urng, const param_type& parm) const
|
Chris@16
|
377 {
|
Chris@16
|
378 return piecewise_constant_distribution(parm)(urng);
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 /** Returns the smallest value that the distribution can produce. */
|
Chris@16
|
382 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
|
Chris@16
|
383 { return _intervals.front(); }
|
Chris@16
|
384 /** Returns the largest value that the distribution can produce. */
|
Chris@16
|
385 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
|
Chris@16
|
386 { return _intervals.back(); }
|
Chris@16
|
387
|
Chris@16
|
388 /**
|
Chris@16
|
389 * Returns a vector containing the probability density
|
Chris@16
|
390 * over each interval.
|
Chris@16
|
391 */
|
Chris@16
|
392 std::vector<RealType> densities() const
|
Chris@16
|
393 {
|
Chris@16
|
394 std::vector<RealType> result(_bins.probabilities());
|
Chris@16
|
395 for(std::size_t i = 0; i < result.size(); ++i) {
|
Chris@16
|
396 result[i] /= (_intervals[i+1] - _intervals[i]);
|
Chris@16
|
397 }
|
Chris@16
|
398 return(result);
|
Chris@16
|
399 }
|
Chris@16
|
400 /** Returns a vector containing the interval boundaries. */
|
Chris@16
|
401 std::vector<RealType> intervals() const { return _intervals; }
|
Chris@16
|
402
|
Chris@16
|
403 /** Returns the parameters of the distribution. */
|
Chris@16
|
404 param_type param() const
|
Chris@16
|
405 {
|
Chris@16
|
406 return param_type(_intervals, _bins.probabilities());
|
Chris@16
|
407 }
|
Chris@16
|
408 /** Sets the parameters of the distribution. */
|
Chris@16
|
409 void param(const param_type& parm)
|
Chris@16
|
410 {
|
Chris@16
|
411 std::vector<RealType> new_intervals(parm._intervals);
|
Chris@16
|
412 typedef discrete_distribution<std::size_t, RealType> bins_type;
|
Chris@16
|
413 typename bins_type::param_type bins_param(parm._weights);
|
Chris@16
|
414 _bins.param(bins_param);
|
Chris@16
|
415 _intervals.swap(new_intervals);
|
Chris@16
|
416 }
|
Chris@16
|
417
|
Chris@16
|
418 /**
|
Chris@16
|
419 * Effects: Subsequent uses of the distribution do not depend
|
Chris@16
|
420 * on values produced by any engine prior to invoking reset.
|
Chris@16
|
421 */
|
Chris@16
|
422 void reset() { _bins.reset(); }
|
Chris@16
|
423
|
Chris@16
|
424 /** Writes a distribution to a @c std::ostream. */
|
Chris@16
|
425 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(
|
Chris@16
|
426 os, piecewise_constant_distribution, pcd)
|
Chris@16
|
427 {
|
Chris@16
|
428 os << pcd.param();
|
Chris@16
|
429 return os;
|
Chris@16
|
430 }
|
Chris@16
|
431
|
Chris@16
|
432 /** Reads a distribution from a @c std::istream */
|
Chris@16
|
433 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(
|
Chris@16
|
434 is, piecewise_constant_distribution, pcd)
|
Chris@16
|
435 {
|
Chris@16
|
436 param_type parm;
|
Chris@16
|
437 if(is >> parm) {
|
Chris@16
|
438 pcd.param(parm);
|
Chris@16
|
439 }
|
Chris@16
|
440 return is;
|
Chris@16
|
441 }
|
Chris@16
|
442
|
Chris@16
|
443 /**
|
Chris@16
|
444 * Returns true if the two distributions will return the
|
Chris@16
|
445 * same sequence of values, when passed equal generators.
|
Chris@16
|
446 */
|
Chris@16
|
447 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(
|
Chris@16
|
448 piecewise_constant_distribution, lhs, rhs)
|
Chris@16
|
449 {
|
Chris@16
|
450 return lhs._bins == rhs._bins && lhs._intervals == rhs._intervals;
|
Chris@16
|
451 }
|
Chris@16
|
452 /**
|
Chris@16
|
453 * Returns true if the two distributions may return different
|
Chris@16
|
454 * sequences of values, when passed equal generators.
|
Chris@16
|
455 */
|
Chris@16
|
456 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(piecewise_constant_distribution)
|
Chris@16
|
457
|
Chris@16
|
458 private:
|
Chris@16
|
459 discrete_distribution<std::size_t, WeightType> _bins;
|
Chris@16
|
460 std::vector<RealType> _intervals;
|
Chris@16
|
461 };
|
Chris@16
|
462
|
Chris@16
|
463 }
|
Chris@16
|
464 }
|
Chris@16
|
465
|
Chris@16
|
466 #endif
|