]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/random.h
Enable __float128 test for 32bit.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / random.h
CommitLineData
8e79468d
BK
1// random number generation -*- C++ -*-
2
15ecdcc6 3// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
8e79468d
BK
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
748086b7 8// Free Software Foundation; either version 3, or (at your option)
8e79468d
BK
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
748086b7
JJ
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
8e79468d
BK
24
25/**
26 * @file bits/random.h
27 * This is an internal header file, included by other library headers.
f910786b 28 * Do not attempt to use it directly. @headername{random}
8e79468d
BK
29 */
30
06f29237
PC
31#ifndef _RANDOM_H
32#define _RANDOM_H 1
33
8e79468d
BK
34#include <vector>
35
12ffa228
BK
36namespace std _GLIBCXX_VISIBILITY(default)
37{
38_GLIBCXX_BEGIN_NAMESPACE_VERSION
53dc5044 39
8e79468d
BK
40 // [26.4] Random number generation
41
42 /**
037181bc
BK
43 * @defgroup random Random Number Generation
44 * @ingroup numerics
45 *
8e79468d
BK
46 * A facility for generating random numbers on selected distributions.
47 * @{
48 */
49
50 /**
51 * @brief A function template for converting the output of a (integral)
52 * uniform random number generator to a floatng point result in the range
53 * [0-1).
54 */
55 template<typename _RealType, size_t __bits,
56 typename _UniformRandomNumberGenerator>
57 _RealType
58 generate_canonical(_UniformRandomNumberGenerator& __g);
59
12ffa228
BK
60_GLIBCXX_END_NAMESPACE_VERSION
61
8e79468d
BK
62 /*
63 * Implementation-space details.
64 */
65 namespace __detail
66 {
12ffa228
BK
67 _GLIBCXX_BEGIN_NAMESPACE_VERSION
68
8e79468d 69 template<typename _UIntType, size_t __w,
95fe602e
PC
70 bool = __w < static_cast<size_t>
71 (std::numeric_limits<_UIntType>::digits)>
8e79468d
BK
72 struct _Shift
73 { static const _UIntType __value = 0; };
74
75 template<typename _UIntType, size_t __w>
76 struct _Shift<_UIntType, __w, true>
77 { static const _UIntType __value = _UIntType(1) << __w; };
78
b94f4bef 79 template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
8e79468d
BK
80 struct _Mod;
81
82 // Dispatch based on modulus value to prevent divide-by-zero compile-time
83 // errors when m == 0.
b94f4bef 84 template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
8e79468d
BK
85 inline _Tp
86 __mod(_Tp __x)
b94f4bef 87 { return _Mod<_Tp, __m, __a, __c, __m == 0>::__calc(__x); }
8e79468d
BK
88
89 /*
90 * An adaptor class for converting the output of any Generator into
91 * the input for a specific Distribution.
92 */
93 template<typename _Engine, typename _DInputType>
94 struct _Adaptor
95 {
96
97 public:
98 _Adaptor(_Engine& __g)
99 : _M_g(__g) { }
100
101 _DInputType
102 min() const
9b88236b 103 { return _DInputType(0); }
8e79468d
BK
104
105 _DInputType
106 max() const
9b88236b 107 { return _DInputType(1); }
8e79468d
BK
108
109 /*
110 * Converts a value generated by the adapted random number generator
111 * into a value in the input domain for the dependent random number
112 * distribution.
8e79468d
BK
113 */
114 _DInputType
115 operator()()
116 {
9b88236b
PC
117 return std::generate_canonical<_DInputType,
118 std::numeric_limits<_DInputType>::digits,
119 _Engine>(_M_g);
8e79468d
BK
120 }
121
122 private:
123 _Engine& _M_g;
124 };
12ffa228
BK
125
126 _GLIBCXX_END_NAMESPACE_VERSION
8e79468d
BK
127 } // namespace __detail
128
12ffa228
BK
129_GLIBCXX_BEGIN_NAMESPACE_VERSION
130
8e79468d 131 /**
037181bc
BK
132 * @addtogroup random_generators Random Number Generators
133 * @ingroup random
8e79468d
BK
134 *
135 * These classes define objects which provide random or pseudorandom
136 * numbers, either from a discrete or a continuous interval. The
137 * random number generator supplied as a part of this library are
138 * all uniform random number generators which provide a sequence of
139 * random number uniformly distributed over their range.
140 *
141 * A number generator is a function object with an operator() that
142 * takes zero arguments and returns a number.
143 *
144 * A compliant random number generator must satisfy the following
145 * requirements. <table border=1 cellpadding=10 cellspacing=0>
146 * <caption align=top>Random Number Generator Requirements</caption>
147 * <tr><td>To be documented.</td></tr> </table>
148 *
149 * @{
150 */
151
152 /**
153 * @brief A model of a linear congruential random number generator.
154 *
6cc5a790
BK
155 * A random number generator that produces pseudorandom numbers via
156 * linear function:
157 * @f[
158 * x_{i+1}\leftarrow(ax_{i} + c) \bmod m
159 * @f]
8e79468d
BK
160 *
161 * The template parameter @p _UIntType must be an unsigned integral type
162 * large enough to store values up to (__m-1). If the template parameter
163 * @p __m is 0, the modulus @p __m used is
164 * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
165 * parameters @p __a and @p __c must be less than @p __m.
166 *
6cc5a790 167 * The size of the state is @f$1@f$.
8e79468d
BK
168 */
169 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
170 class linear_congruential_engine
171 {
77e3c516 172 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
f6d08b43 173 "substituting _UIntType not an unsigned integral type");
77e3c516 174 static_assert(__m == 0u || (__a < __m && __c < __m),
f6d08b43 175 "template argument substituting __m out of bounds");
8e79468d
BK
176
177 public:
178 /** The type of the generated random value. */
179 typedef _UIntType result_type;
180
181 /** The multiplier. */
94a86be0 182 static constexpr result_type multiplier = __a;
8e79468d 183 /** An increment. */
94a86be0 184 static constexpr result_type increment = __c;
8e79468d 185 /** The modulus. */
94a86be0
BK
186 static constexpr result_type modulus = __m;
187 static constexpr result_type default_seed = 1u;
8e79468d
BK
188
189 /**
190 * @brief Constructs a %linear_congruential_engine random number
191 * generator engine with seed @p __s. The default seed value
192 * is 1.
193 *
194 * @param __s The initial seed value.
195 */
196 explicit
197 linear_congruential_engine(result_type __s = default_seed)
15ecdcc6 198 { seed(__s); }
8e79468d
BK
199
200 /**
201 * @brief Constructs a %linear_congruential_engine random number
202 * generator engine seeded from the seed sequence @p __q.
203 *
204 * @param __q the seed sequence.
205 */
05eeebfe
PC
206 template<typename _Sseq, typename = typename
207 std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
208 ::type>
15ecdcc6
PC
209 explicit
210 linear_congruential_engine(_Sseq& __q)
05eeebfe 211 { seed(__q); }
8e79468d
BK
212
213 /**
214 * @brief Reseeds the %linear_congruential_engine random number generator
04b70271 215 * engine sequence to the seed @p __s.
8e79468d
BK
216 *
217 * @param __s The new seed.
218 */
219 void
220 seed(result_type __s = default_seed);
221
222 /**
223 * @brief Reseeds the %linear_congruential_engine random number generator
224 * engine
225 * sequence using values from the seed sequence @p __q.
226 *
227 * @param __q the seed sequence.
228 */
05eeebfe
PC
229 template<typename _Sseq>
230 typename std::enable_if<std::is_class<_Sseq>::value>::type
15ecdcc6 231 seed(_Sseq& __q);
8e79468d
BK
232
233 /**
234 * @brief Gets the smallest possible value in the output range.
235 *
236 * The minimum depends on the @p __c parameter: if it is zero, the
237 * minimum generated must be > 0, otherwise 0 is allowed.
8e79468d 238 */
94a86be0
BK
239 static constexpr result_type
240 min()
96a9203b 241 { return __c == 0u ? 1u : 0u; }
8e79468d
BK
242
243 /**
244 * @brief Gets the largest possible value in the output range.
8e79468d 245 */
94a86be0
BK
246 static constexpr result_type
247 max()
96a9203b 248 { return __m - 1u; }
8e79468d
BK
249
250 /**
251 * @brief Discard a sequence of random numbers.
8e79468d
BK
252 */
253 void
254 discard(unsigned long long __z)
255 {
256 for (; __z != 0ULL; --__z)
257 (*this)();
258 }
259
260 /**
261 * @brief Gets the next random number in the sequence.
262 */
263 result_type
b01630bb
PC
264 operator()()
265 {
b94f4bef 266 _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
b01630bb
PC
267 return _M_x;
268 }
8e79468d
BK
269
270 /**
271 * @brief Compares two linear congruential random number generator
272 * objects of the same type for equality.
273 *
274 * @param __lhs A linear congruential random number generator object.
275 * @param __rhs Another linear congruential random number generator
276 * object.
277 *
fc05e1ba
PC
278 * @returns true if the infinite sequences of generated values
279 * would be equal, false otherwise.
8e79468d
BK
280 */
281 friend bool
282 operator==(const linear_congruential_engine& __lhs,
283 const linear_congruential_engine& __rhs)
284 { return __lhs._M_x == __rhs._M_x; }
285
286 /**
287 * @brief Writes the textual representation of the state x(i) of x to
288 * @p __os.
289 *
290 * @param __os The output stream.
291 * @param __lcr A % linear_congruential_engine random number generator.
292 * @returns __os.
293 */
294 template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
b94f4bef 295 _UIntType1 __m1, typename _CharT, typename _Traits>
8e79468d 296 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
297 operator<<(std::basic_ostream<_CharT, _Traits>&,
298 const std::linear_congruential_engine<_UIntType1,
299 __a1, __c1, __m1>&);
8e79468d
BK
300
301 /**
302 * @brief Sets the state of the engine by reading its textual
303 * representation from @p __is.
304 *
305 * The textual representation must have been previously written using
306 * an output stream whose imbued locale and whose type's template
307 * specialization arguments _CharT and _Traits were the same as those
308 * of @p __is.
309 *
310 * @param __is The input stream.
311 * @param __lcr A % linear_congruential_engine random number generator.
312 * @returns __is.
313 */
314 template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
b94f4bef 315 _UIntType1 __m1, typename _CharT, typename _Traits>
8e79468d 316 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
317 operator>>(std::basic_istream<_CharT, _Traits>&,
318 std::linear_congruential_engine<_UIntType1, __a1,
319 __c1, __m1>&);
8e79468d
BK
320
321 private:
8e79468d
BK
322 _UIntType _M_x;
323 };
324
fc05e1ba
PC
325 /**
326 * @brief Compares two linear congruential random number generator
327 * objects of the same type for inequality.
328 *
329 * @param __lhs A linear congruential random number generator object.
330 * @param __rhs Another linear congruential random number generator
331 * object.
332 *
333 * @returns true if the infinite sequences of generated values
334 * would be different, false otherwise.
335 */
336 template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
337 inline bool
338 operator!=(const std::linear_congruential_engine<_UIntType, __a,
339 __c, __m>& __lhs,
340 const std::linear_congruential_engine<_UIntType, __a,
341 __c, __m>& __rhs)
342 { return !(__lhs == __rhs); }
343
8e79468d
BK
344
345 /**
346 * A generalized feedback shift register discrete random number generator.
347 *
348 * This algorithm avoids multiplication and division and is designed to be
349 * friendly to a pipelined architecture. If the parameters are chosen
350 * correctly, this generator will produce numbers with a very long period and
351 * fairly good apparent entropy, although still not cryptographically strong.
352 *
353 * The best way to use this generator is with the predefined mt19937 class.
354 *
355 * This algorithm was originally invented by Makoto Matsumoto and
356 * Takuji Nishimura.
357 *
358 * @var word_size The number of bits in each element of the state vector.
359 * @var state_size The degree of recursion.
360 * @var shift_size The period parameter.
361 * @var mask_bits The separation point bit index.
362 * @var parameter_a The last row of the twist matrix.
363 * @var output_u The first right-shift tempering matrix parameter.
364 * @var output_s The first left-shift tempering matrix parameter.
365 * @var output_b The first left-shift tempering matrix mask.
366 * @var output_t The second left-shift tempering matrix parameter.
367 * @var output_c The second left-shift tempering matrix mask.
368 * @var output_l The second right-shift tempering matrix parameter.
369 */
370 template<typename _UIntType, size_t __w,
371 size_t __n, size_t __m, size_t __r,
372 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
373 _UIntType __b, size_t __t,
374 _UIntType __c, size_t __l, _UIntType __f>
375 class mersenne_twister_engine
376 {
77e3c516 377 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
f6d08b43 378 "substituting _UIntType not an unsigned integral type");
77e3c516 379 static_assert(1u <= __m && __m <= __n,
f6d08b43
PC
380 "template argument substituting __m out of bounds");
381 static_assert(__r <= __w, "template argument substituting "
382 "__r out of bound");
383 static_assert(__u <= __w, "template argument substituting "
384 "__u out of bound");
385 static_assert(__s <= __w, "template argument substituting "
386 "__s out of bound");
387 static_assert(__t <= __w, "template argument substituting "
388 "__t out of bound");
389 static_assert(__l <= __w, "template argument substituting "
390 "__l out of bound");
77e3c516 391 static_assert(__w <= std::numeric_limits<_UIntType>::digits,
f6d08b43 392 "template argument substituting __w out of bound");
6855fe45 393 static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
f6d08b43 394 "template argument substituting __a out of bound");
6855fe45 395 static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
f6d08b43 396 "template argument substituting __b out of bound");
6855fe45 397 static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
f6d08b43 398 "template argument substituting __c out of bound");
b94f4bef 399 static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
f6d08b43 400 "template argument substituting __d out of bound");
b94f4bef 401 static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
f6d08b43 402 "template argument substituting __f out of bound");
8e79468d
BK
403
404 public:
405 /** The type of the generated random value. */
406 typedef _UIntType result_type;
407
408 // parameter values
94a86be0
BK
409 static constexpr size_t word_size = __w;
410 static constexpr size_t state_size = __n;
411 static constexpr size_t shift_size = __m;
412 static constexpr size_t mask_bits = __r;
413 static constexpr result_type xor_mask = __a;
414 static constexpr size_t tempering_u = __u;
415 static constexpr result_type tempering_d = __d;
416 static constexpr size_t tempering_s = __s;
417 static constexpr result_type tempering_b = __b;
418 static constexpr size_t tempering_t = __t;
419 static constexpr result_type tempering_c = __c;
420 static constexpr size_t tempering_l = __l;
421 static constexpr result_type initialization_multiplier = __f;
422 static constexpr result_type default_seed = 5489u;
8e79468d
BK
423
424 // constructors and member function
425 explicit
426 mersenne_twister_engine(result_type __sd = default_seed)
427 { seed(__sd); }
428
429 /**
430 * @brief Constructs a %mersenne_twister_engine random number generator
431 * engine seeded from the seed sequence @p __q.
432 *
433 * @param __q the seed sequence.
434 */
05eeebfe
PC
435 template<typename _Sseq, typename = typename
436 std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
437 ::type>
15ecdcc6
PC
438 explicit
439 mersenne_twister_engine(_Sseq& __q)
05eeebfe 440 { seed(__q); }
8e79468d
BK
441
442 void
443 seed(result_type __sd = default_seed);
444
05eeebfe
PC
445 template<typename _Sseq>
446 typename std::enable_if<std::is_class<_Sseq>::value>::type
15ecdcc6 447 seed(_Sseq& __q);
8e79468d
BK
448
449 /**
450 * @brief Gets the smallest possible value in the output range.
8e79468d 451 */
94a86be0
BK
452 static constexpr result_type
453 min()
8e79468d
BK
454 { return 0; };
455
456 /**
457 * @brief Gets the largest possible value in the output range.
8e79468d 458 */
94a86be0
BK
459 static constexpr result_type
460 max()
6855fe45 461 { return __detail::_Shift<_UIntType, __w>::__value - 1; }
8e79468d
BK
462
463 /**
464 * @brief Discard a sequence of random numbers.
8e79468d
BK
465 */
466 void
467 discard(unsigned long long __z)
468 {
469 for (; __z != 0ULL; --__z)
470 (*this)();
471 }
472
473 result_type
474 operator()();
475
476 /**
477 * @brief Compares two % mersenne_twister_engine random number generator
478 * objects of the same type for equality.
479 *
480 * @param __lhs A % mersenne_twister_engine random number generator
481 * object.
482 * @param __rhs Another % mersenne_twister_engine random number
483 * generator object.
484 *
fc05e1ba
PC
485 * @returns true if the infinite sequences of generated values
486 * would be equal, false otherwise.
8e79468d
BK
487 */
488 friend bool
489 operator==(const mersenne_twister_engine& __lhs,
490 const mersenne_twister_engine& __rhs)
491 { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
492
493 /**
494 * @brief Inserts the current state of a % mersenne_twister_engine
495 * random number generator engine @p __x into the output stream
496 * @p __os.
497 *
498 * @param __os An output stream.
499 * @param __x A % mersenne_twister_engine random number generator
500 * engine.
501 *
502 * @returns The output stream with the state of @p __x inserted or in
503 * an error state.
504 */
505 template<typename _UIntType1,
506 size_t __w1, size_t __n1,
507 size_t __m1, size_t __r1,
508 _UIntType1 __a1, size_t __u1,
509 _UIntType1 __d1, size_t __s1,
510 _UIntType1 __b1, size_t __t1,
511 _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
512 typename _CharT, typename _Traits>
513 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
514 operator<<(std::basic_ostream<_CharT, _Traits>&,
515 const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
516 __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
517 __l1, __f1>&);
8e79468d
BK
518
519 /**
520 * @brief Extracts the current state of a % mersenne_twister_engine
521 * random number generator engine @p __x from the input stream
522 * @p __is.
523 *
524 * @param __is An input stream.
525 * @param __x A % mersenne_twister_engine random number generator
526 * engine.
527 *
528 * @returns The input stream with the state of @p __x extracted or in
529 * an error state.
530 */
531 template<typename _UIntType1,
532 size_t __w1, size_t __n1,
533 size_t __m1, size_t __r1,
534 _UIntType1 __a1, size_t __u1,
535 _UIntType1 __d1, size_t __s1,
536 _UIntType1 __b1, size_t __t1,
537 _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
538 typename _CharT, typename _Traits>
539 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
540 operator>>(std::basic_istream<_CharT, _Traits>&,
541 std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
542 __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
543 __l1, __f1>&);
8e79468d
BK
544
545 private:
8e79468d
BK
546 _UIntType _M_x[state_size];
547 size_t _M_p;
548 };
549
fc05e1ba
PC
550 /**
551 * @brief Compares two % mersenne_twister_engine random number generator
552 * objects of the same type for inequality.
553 *
554 * @param __lhs A % mersenne_twister_engine random number generator
555 * object.
556 * @param __rhs Another % mersenne_twister_engine random number
557 * generator object.
558 *
559 * @returns true if the infinite sequences of generated values
560 * would be different, false otherwise.
561 */
562 template<typename _UIntType, size_t __w,
563 size_t __n, size_t __m, size_t __r,
564 _UIntType __a, size_t __u, _UIntType __d, size_t __s,
565 _UIntType __b, size_t __t,
566 _UIntType __c, size_t __l, _UIntType __f>
567 inline bool
568 operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
569 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
570 const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
571 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
572 { return !(__lhs == __rhs); }
573
574
8e79468d
BK
575 /**
576 * @brief The Marsaglia-Zaman generator.
577 *
578 * This is a model of a Generalized Fibonacci discrete random number
579 * generator, sometimes referred to as the SWC generator.
580 *
581 * A discrete random number generator that produces pseudorandom
6cc5a790
BK
582 * numbers using:
583 * @f[
584 * x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m
585 * @f]
8e79468d 586 *
6cc5a790
BK
587 * The size of the state is @f$r@f$
588 * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
8e79468d
BK
589 *
590 * @var _M_x The state of the generator. This is a ring buffer.
591 * @var _M_carry The carry.
592 * @var _M_p Current index of x(i - r).
593 */
594 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
595 class subtract_with_carry_engine
596 {
77e3c516 597 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
f6d08b43 598 "substituting _UIntType not an unsigned integral type");
77e3c516 599 static_assert(0u < __s && __s < __r,
f6d08b43 600 "template argument substituting __s out of bounds");
77e3c516 601 static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
f6d08b43 602 "template argument substituting __w out of bounds");
8e79468d
BK
603
604 public:
605 /** The type of the generated random value. */
606 typedef _UIntType result_type;
607
608 // parameter values
94a86be0
BK
609 static constexpr size_t word_size = __w;
610 static constexpr size_t short_lag = __s;
611 static constexpr size_t long_lag = __r;
612 static constexpr result_type default_seed = 19780503u;
8e79468d
BK
613
614 /**
615 * @brief Constructs an explicitly seeded % subtract_with_carry_engine
616 * random number generator.
617 */
618 explicit
619 subtract_with_carry_engine(result_type __sd = default_seed)
15ecdcc6 620 { seed(__sd); }
8e79468d
BK
621
622 /**
623 * @brief Constructs a %subtract_with_carry_engine random number engine
624 * seeded from the seed sequence @p __q.
625 *
626 * @param __q the seed sequence.
627 */
05eeebfe
PC
628 template<typename _Sseq, typename = typename
629 std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
630 ::type>
15ecdcc6
PC
631 explicit
632 subtract_with_carry_engine(_Sseq& __q)
05eeebfe 633 { seed(__q); }
8e79468d
BK
634
635 /**
6cc5a790 636 * @brief Seeds the initial state @f$x_0@f$ of the random number
8e79468d
BK
637 * generator.
638 *
639 * N1688[4.19] modifies this as follows. If @p __value == 0,
640 * sets value to 19780503. In any case, with a linear
641 * congruential generator lcg(i) having parameters @f$ m_{lcg} =
642 * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
643 * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
644 * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$
645 * set carry to 1, otherwise sets carry to 0.
646 */
647 void
648 seed(result_type __sd = default_seed);
649
650 /**
6cc5a790 651 * @brief Seeds the initial state @f$x_0@f$ of the
8e79468d
BK
652 * % subtract_with_carry_engine random number generator.
653 */
05eeebfe
PC
654 template<typename _Sseq>
655 typename std::enable_if<std::is_class<_Sseq>::value>::type
15ecdcc6 656 seed(_Sseq& __q);
8e79468d
BK
657
658 /**
659 * @brief Gets the inclusive minimum value of the range of random
660 * integers returned by this generator.
8e79468d 661 */
94a86be0
BK
662 static constexpr result_type
663 min()
8e79468d
BK
664 { return 0; }
665
666 /**
667 * @brief Gets the inclusive maximum value of the range of random
668 * integers returned by this generator.
8e79468d 669 */
94a86be0
BK
670 static constexpr result_type
671 max()
6855fe45 672 { return __detail::_Shift<_UIntType, __w>::__value - 1; }
8e79468d
BK
673
674 /**
675 * @brief Discard a sequence of random numbers.
8e79468d
BK
676 */
677 void
678 discard(unsigned long long __z)
679 {
680 for (; __z != 0ULL; --__z)
681 (*this)();
682 }
683
684 /**
685 * @brief Gets the next random number in the sequence.
686 */
687 result_type
688 operator()();
689
690 /**
691 * @brief Compares two % subtract_with_carry_engine random number
692 * generator objects of the same type for equality.
693 *
694 * @param __lhs A % subtract_with_carry_engine random number generator
695 * object.
696 * @param __rhs Another % subtract_with_carry_engine random number
697 * generator object.
698 *
fc05e1ba
PC
699 * @returns true if the infinite sequences of generated values
700 * would be equal, false otherwise.
701 */
8e79468d
BK
702 friend bool
703 operator==(const subtract_with_carry_engine& __lhs,
704 const subtract_with_carry_engine& __rhs)
705 { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
706
707 /**
708 * @brief Inserts the current state of a % subtract_with_carry_engine
709 * random number generator engine @p __x into the output stream
710 * @p __os.
711 *
712 * @param __os An output stream.
713 * @param __x A % subtract_with_carry_engine random number generator
714 * engine.
715 *
716 * @returns The output stream with the state of @p __x inserted or in
717 * an error state.
718 */
719 template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
720 typename _CharT, typename _Traits>
721 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
722 operator<<(std::basic_ostream<_CharT, _Traits>&,
723 const std::subtract_with_carry_engine<_UIntType1, __w1,
724 __s1, __r1>&);
8e79468d
BK
725
726 /**
727 * @brief Extracts the current state of a % subtract_with_carry_engine
728 * random number generator engine @p __x from the input stream
729 * @p __is.
730 *
731 * @param __is An input stream.
15ecdcc6
PC
732 * @param __x A % subtract_with_carry_engine random number generator
733 * engine.
8e79468d
BK
734 *
735 * @returns The input stream with the state of @p __x extracted or in
736 * an error state.
737 */
738 template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
739 typename _CharT, typename _Traits>
740 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
741 operator>>(std::basic_istream<_CharT, _Traits>&,
742 std::subtract_with_carry_engine<_UIntType1, __w1,
743 __s1, __r1>&);
8e79468d
BK
744
745 private:
8e79468d
BK
746 _UIntType _M_x[long_lag];
747 _UIntType _M_carry;
748 size_t _M_p;
749 };
750
fc05e1ba
PC
751 /**
752 * @brief Compares two % subtract_with_carry_engine random number
753 * generator objects of the same type for inequality.
754 *
755 * @param __lhs A % subtract_with_carry_engine random number generator
756 * object.
757 * @param __rhs Another % subtract_with_carry_engine random number
758 * generator object.
759 *
760 * @returns true if the infinite sequences of generated values
761 * would be different, false otherwise.
762 */
763 template<typename _UIntType, size_t __w, size_t __s, size_t __r>
764 inline bool
765 operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
766 __s, __r>& __lhs,
767 const std::subtract_with_carry_engine<_UIntType, __w,
768 __s, __r>& __rhs)
769 { return !(__lhs == __rhs); }
770
771
8e79468d
BK
772 /**
773 * Produces random numbers from some base engine by discarding blocks of
774 * data.
775 *
776 * 0 <= @p __r <= @p __p
777 */
778 template<typename _RandomNumberEngine, size_t __p, size_t __r>
779 class discard_block_engine
780 {
77e3c516 781 static_assert(1 <= __r && __r <= __p,
f6d08b43 782 "template argument substituting __r out of bounds");
8e79468d
BK
783
784 public:
785 /** The type of the generated random value. */
786 typedef typename _RandomNumberEngine::result_type result_type;
787
788 // parameter values
94a86be0
BK
789 static constexpr size_t block_size = __p;
790 static constexpr size_t used_block = __r;
8e79468d
BK
791
792 /**
793 * @brief Constructs a default %discard_block_engine engine.
794 *
795 * The underlying engine is default constructed as well.
796 */
797 discard_block_engine()
798 : _M_b(), _M_n(0) { }
799
800 /**
801 * @brief Copy constructs a %discard_block_engine engine.
802 *
803 * Copies an existing base class random number generator.
804 * @param rng An existing (base class) engine object.
805 */
806 explicit
807 discard_block_engine(const _RandomNumberEngine& __rne)
808 : _M_b(__rne), _M_n(0) { }
809
810 /**
811 * @brief Move constructs a %discard_block_engine engine.
812 *
813 * Copies an existing base class random number generator.
814 * @param rng An existing (base class) engine object.
815 */
816 explicit
817 discard_block_engine(_RandomNumberEngine&& __rne)
818 : _M_b(std::move(__rne)), _M_n(0) { }
819
820 /**
821 * @brief Seed constructs a %discard_block_engine engine.
822 *
823 * Constructs the underlying generator engine seeded with @p __s.
824 * @param __s A seed value for the base class engine.
825 */
826 explicit
827 discard_block_engine(result_type __s)
828 : _M_b(__s), _M_n(0) { }
829
830 /**
831 * @brief Generator construct a %discard_block_engine engine.
832 *
833 * @param __q A seed sequence.
834 */
05eeebfe
PC
835 template<typename _Sseq, typename = typename
836 std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
837 && !std::is_same<_Sseq, _RandomNumberEngine>::value>
838 ::type>
15ecdcc6
PC
839 explicit
840 discard_block_engine(_Sseq& __q)
841 : _M_b(__q), _M_n(0)
842 { }
8e79468d
BK
843
844 /**
845 * @brief Reseeds the %discard_block_engine object with the default
846 * seed for the underlying base class generator engine.
847 */
848 void
849 seed()
850 {
851 _M_b.seed();
852 _M_n = 0;
853 }
854
855 /**
856 * @brief Reseeds the %discard_block_engine object with the default
857 * seed for the underlying base class generator engine.
858 */
859 void
860 seed(result_type __s)
861 {
862 _M_b.seed(__s);
863 _M_n = 0;
864 }
865
866 /**
867 * @brief Reseeds the %discard_block_engine object with the given seed
868 * sequence.
869 * @param __q A seed generator function.
870 */
05eeebfe 871 template<typename _Sseq>
15ecdcc6
PC
872 void
873 seed(_Sseq& __q)
874 {
05eeebfe 875 _M_b.seed(__q);
15ecdcc6
PC
876 _M_n = 0;
877 }
8e79468d
BK
878
879 /**
880 * @brief Gets a const reference to the underlying generator engine
881 * object.
882 */
883 const _RandomNumberEngine&
884 base() const
885 { return _M_b; }
886
887 /**
888 * @brief Gets the minimum value in the generated random number range.
8e79468d 889 */
94a86be0
BK
890 static constexpr result_type
891 min()
892 { return _RandomNumberEngine::min(); }
8e79468d
BK
893
894 /**
895 * @brief Gets the maximum value in the generated random number range.
8e79468d 896 */
94a86be0
BK
897 static constexpr result_type
898 max()
899 { return _RandomNumberEngine::max(); }
8e79468d
BK
900
901 /**
902 * @brief Discard a sequence of random numbers.
8e79468d
BK
903 */
904 void
905 discard(unsigned long long __z)
906 {
907 for (; __z != 0ULL; --__z)
908 (*this)();
909 }
910
911 /**
912 * @brief Gets the next value in the generated random number sequence.
913 */
914 result_type
915 operator()();
916
917 /**
918 * @brief Compares two %discard_block_engine random number generator
919 * objects of the same type for equality.
920 *
921 * @param __lhs A %discard_block_engine random number generator object.
922 * @param __rhs Another %discard_block_engine random number generator
923 * object.
924 *
fc05e1ba
PC
925 * @returns true if the infinite sequences of generated values
926 * would be equal, false otherwise.
8e79468d
BK
927 */
928 friend bool
929 operator==(const discard_block_engine& __lhs,
930 const discard_block_engine& __rhs)
fc05e1ba 931 { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
8e79468d
BK
932
933 /**
934 * @brief Inserts the current state of a %discard_block_engine random
935 * number generator engine @p __x into the output stream
936 * @p __os.
937 *
938 * @param __os An output stream.
939 * @param __x A %discard_block_engine random number generator engine.
940 *
941 * @returns The output stream with the state of @p __x inserted or in
942 * an error state.
943 */
944 template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
945 typename _CharT, typename _Traits>
946 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
947 operator<<(std::basic_ostream<_CharT, _Traits>&,
948 const std::discard_block_engine<_RandomNumberEngine1,
949 __p1, __r1>&);
8e79468d
BK
950
951 /**
952 * @brief Extracts the current state of a % subtract_with_carry_engine
953 * random number generator engine @p __x from the input stream
954 * @p __is.
955 *
956 * @param __is An input stream.
957 * @param __x A %discard_block_engine random number generator engine.
958 *
959 * @returns The input stream with the state of @p __x extracted or in
960 * an error state.
961 */
962 template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
963 typename _CharT, typename _Traits>
964 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
965 operator>>(std::basic_istream<_CharT, _Traits>&,
966 std::discard_block_engine<_RandomNumberEngine1,
967 __p1, __r1>&);
8e79468d
BK
968
969 private:
970 _RandomNumberEngine _M_b;
971 size_t _M_n;
972 };
973
fc05e1ba
PC
974 /**
975 * @brief Compares two %discard_block_engine random number generator
976 * objects of the same type for inequality.
977 *
978 * @param __lhs A %discard_block_engine random number generator object.
979 * @param __rhs Another %discard_block_engine random number generator
980 * object.
981 *
982 * @returns true if the infinite sequences of generated values
983 * would be different, false otherwise.
984 */
985 template<typename _RandomNumberEngine, size_t __p, size_t __r>
986 inline bool
987 operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
988 __r>& __lhs,
989 const std::discard_block_engine<_RandomNumberEngine, __p,
990 __r>& __rhs)
991 { return !(__lhs == __rhs); }
992
993
8e79468d
BK
994 /**
995 * Produces random numbers by combining random numbers from some base
996 * engine to produce random numbers with a specifies number of bits @p __w.
997 */
998 template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
999 class independent_bits_engine
1000 {
77e3c516 1001 static_assert(std::is_unsigned<_UIntType>::value, "template argument "
f6d08b43 1002 "substituting _UIntType not an unsigned integral type");
77e3c516 1003 static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
f6d08b43 1004 "template argument substituting __w out of bounds");
8e79468d
BK
1005
1006 public:
1007 /** The type of the generated random value. */
1008 typedef _UIntType result_type;
1009
1010 /**
1011 * @brief Constructs a default %independent_bits_engine engine.
1012 *
1013 * The underlying engine is default constructed as well.
1014 */
1015 independent_bits_engine()
1016 : _M_b() { }
1017
1018 /**
1019 * @brief Copy constructs a %independent_bits_engine engine.
1020 *
1021 * Copies an existing base class random number generator.
1022 * @param rng An existing (base class) engine object.
1023 */
1024 explicit
1025 independent_bits_engine(const _RandomNumberEngine& __rne)
1026 : _M_b(__rne) { }
1027
1028 /**
1029 * @brief Move constructs a %independent_bits_engine engine.
1030 *
1031 * Copies an existing base class random number generator.
1032 * @param rng An existing (base class) engine object.
1033 */
1034 explicit
1035 independent_bits_engine(_RandomNumberEngine&& __rne)
1036 : _M_b(std::move(__rne)) { }
1037
1038 /**
1039 * @brief Seed constructs a %independent_bits_engine engine.
1040 *
1041 * Constructs the underlying generator engine seeded with @p __s.
1042 * @param __s A seed value for the base class engine.
1043 */
1044 explicit
1045 independent_bits_engine(result_type __s)
1046 : _M_b(__s) { }
1047
1048 /**
1049 * @brief Generator construct a %independent_bits_engine engine.
1050 *
1051 * @param __q A seed sequence.
1052 */
05eeebfe
PC
1053 template<typename _Sseq, typename = typename
1054 std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
1055 && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1056 ::type>
15ecdcc6
PC
1057 explicit
1058 independent_bits_engine(_Sseq& __q)
1059 : _M_b(__q)
1060 { }
8e79468d
BK
1061
1062 /**
1063 * @brief Reseeds the %independent_bits_engine object with the default
1064 * seed for the underlying base class generator engine.
1065 */
1066 void
1067 seed()
1068 { _M_b.seed(); }
1069
1070 /**
1071 * @brief Reseeds the %independent_bits_engine object with the default
1072 * seed for the underlying base class generator engine.
1073 */
1074 void
1075 seed(result_type __s)
1076 { _M_b.seed(__s); }
1077
1078 /**
1079 * @brief Reseeds the %independent_bits_engine object with the given
1080 * seed sequence.
1081 * @param __q A seed generator function.
1082 */
05eeebfe 1083 template<typename _Sseq>
15ecdcc6
PC
1084 void
1085 seed(_Sseq& __q)
05eeebfe 1086 { _M_b.seed(__q); }
8e79468d
BK
1087
1088 /**
1089 * @brief Gets a const reference to the underlying generator engine
1090 * object.
1091 */
1092 const _RandomNumberEngine&
1093 base() const
1094 { return _M_b; }
1095
1096 /**
1097 * @brief Gets the minimum value in the generated random number range.
8e79468d 1098 */
94a86be0
BK
1099 static constexpr result_type
1100 min()
8e79468d
BK
1101 { return 0U; }
1102
1103 /**
1104 * @brief Gets the maximum value in the generated random number range.
8e79468d 1105 */
94a86be0
BK
1106 static constexpr result_type
1107 max()
6855fe45 1108 { return __detail::_Shift<_UIntType, __w>::__value - 1; }
8e79468d
BK
1109
1110 /**
1111 * @brief Discard a sequence of random numbers.
8e79468d
BK
1112 */
1113 void
1114 discard(unsigned long long __z)
1115 {
1116 for (; __z != 0ULL; --__z)
1117 (*this)();
1118 }
1119
1120 /**
1121 * @brief Gets the next value in the generated random number sequence.
1122 */
1123 result_type
1124 operator()();
1125
1126 /**
1127 * @brief Compares two %independent_bits_engine random number generator
1128 * objects of the same type for equality.
1129 *
1130 * @param __lhs A %independent_bits_engine random number generator
1131 * object.
1132 * @param __rhs Another %independent_bits_engine random number generator
1133 * object.
1134 *
fc05e1ba
PC
1135 * @returns true if the infinite sequences of generated values
1136 * would be equal, false otherwise.
8e79468d
BK
1137 */
1138 friend bool
1139 operator==(const independent_bits_engine& __lhs,
1140 const independent_bits_engine& __rhs)
1141 { return __lhs._M_b == __rhs._M_b; }
1142
1143 /**
1144 * @brief Extracts the current state of a % subtract_with_carry_engine
1145 * random number generator engine @p __x from the input stream
1146 * @p __is.
1147 *
1148 * @param __is An input stream.
1149 * @param __x A %independent_bits_engine random number generator
1150 * engine.
1151 *
1152 * @returns The input stream with the state of @p __x extracted or in
1153 * an error state.
1154 */
1155 template<typename _CharT, typename _Traits>
1156 friend std::basic_istream<_CharT, _Traits>&
1157 operator>>(std::basic_istream<_CharT, _Traits>& __is,
94986f6d 1158 std::independent_bits_engine<_RandomNumberEngine,
8e79468d
BK
1159 __w, _UIntType>& __x)
1160 {
1161 __is >> __x._M_b;
1162 return __is;
1163 }
1164
1165 private:
1166 _RandomNumberEngine _M_b;
1167 };
1168
fc05e1ba
PC
1169 /**
1170 * @brief Compares two %independent_bits_engine random number generator
1171 * objects of the same type for inequality.
1172 *
1173 * @param __lhs A %independent_bits_engine random number generator
1174 * object.
1175 * @param __rhs Another %independent_bits_engine random number generator
1176 * object.
1177 *
1178 * @returns true if the infinite sequences of generated values
1179 * would be different, false otherwise.
1180 */
1181 template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1182 inline bool
1183 operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
1184 _UIntType>& __lhs,
1185 const std::independent_bits_engine<_RandomNumberEngine, __w,
1186 _UIntType>& __rhs)
1187 { return !(__lhs == __rhs); }
1188
8e79468d
BK
1189 /**
1190 * @brief Inserts the current state of a %independent_bits_engine random
1191 * number generator engine @p __x into the output stream @p __os.
1192 *
1193 * @param __os An output stream.
1194 * @param __x A %independent_bits_engine random number generator engine.
1195 *
1196 * @returns The output stream with the state of @p __x inserted or in
1197 * an error state.
1198 */
1199 template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
1200 typename _CharT, typename _Traits>
1201 std::basic_ostream<_CharT, _Traits>&
1202 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
94986f6d 1203 const std::independent_bits_engine<_RandomNumberEngine,
8e79468d
BK
1204 __w, _UIntType>& __x)
1205 {
1206 __os << __x.base();
1207 return __os;
1208 }
1209
fc05e1ba 1210
8e79468d
BK
1211 /**
1212 * @brief Produces random numbers by combining random numbers from some
1213 * base engine to produce random numbers with a specifies number of bits
1214 * @p __w.
1215 */
1216 template<typename _RandomNumberEngine, size_t __k>
1217 class shuffle_order_engine
1218 {
a20c8540 1219 static_assert(1u <= __k, "template argument substituting "
f6d08b43 1220 "__k out of bound");
8e79468d
BK
1221
1222 public:
1223 /** The type of the generated random value. */
1224 typedef typename _RandomNumberEngine::result_type result_type;
1225
94a86be0 1226 static constexpr size_t table_size = __k;
8e79468d
BK
1227
1228 /**
1229 * @brief Constructs a default %shuffle_order_engine engine.
1230 *
1231 * The underlying engine is default constructed as well.
1232 */
1233 shuffle_order_engine()
1234 : _M_b()
1235 { _M_initialize(); }
1236
1237 /**
1238 * @brief Copy constructs a %shuffle_order_engine engine.
1239 *
1240 * Copies an existing base class random number generator.
1241 * @param rng An existing (base class) engine object.
1242 */
1243 explicit
1244 shuffle_order_engine(const _RandomNumberEngine& __rne)
1245 : _M_b(__rne)
1246 { _M_initialize(); }
1247
1248 /**
1249 * @brief Move constructs a %shuffle_order_engine engine.
1250 *
1251 * Copies an existing base class random number generator.
1252 * @param rng An existing (base class) engine object.
1253 */
1254 explicit
1255 shuffle_order_engine(_RandomNumberEngine&& __rne)
1256 : _M_b(std::move(__rne))
1257 { _M_initialize(); }
1258
1259 /**
1260 * @brief Seed constructs a %shuffle_order_engine engine.
1261 *
1262 * Constructs the underlying generator engine seeded with @p __s.
1263 * @param __s A seed value for the base class engine.
1264 */
1265 explicit
1266 shuffle_order_engine(result_type __s)
1267 : _M_b(__s)
1268 { _M_initialize(); }
1269
1270 /**
1271 * @brief Generator construct a %shuffle_order_engine engine.
1272 *
1273 * @param __q A seed sequence.
1274 */
05eeebfe
PC
1275 template<typename _Sseq, typename = typename
1276 std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
1277 && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1278 ::type>
15ecdcc6
PC
1279 explicit
1280 shuffle_order_engine(_Sseq& __q)
1281 : _M_b(__q)
1282 { _M_initialize(); }
8e79468d
BK
1283
1284 /**
94986f6d
PC
1285 * @brief Reseeds the %shuffle_order_engine object with the default seed
1286 for the underlying base class generator engine.
8e79468d
BK
1287 */
1288 void
1289 seed()
1290 {
1291 _M_b.seed();
1292 _M_initialize();
1293 }
1294
1295 /**
1296 * @brief Reseeds the %shuffle_order_engine object with the default seed
1297 * for the underlying base class generator engine.
1298 */
1299 void
1300 seed(result_type __s)
1301 {
1302 _M_b.seed(__s);
1303 _M_initialize();
1304 }
1305
1306 /**
1307 * @brief Reseeds the %shuffle_order_engine object with the given seed
1308 * sequence.
1309 * @param __q A seed generator function.
1310 */
05eeebfe 1311 template<typename _Sseq>
15ecdcc6
PC
1312 void
1313 seed(_Sseq& __q)
1314 {
05eeebfe 1315 _M_b.seed(__q);
15ecdcc6
PC
1316 _M_initialize();
1317 }
8e79468d
BK
1318
1319 /**
1320 * Gets a const reference to the underlying generator engine object.
1321 */
1322 const _RandomNumberEngine&
1323 base() const
1324 { return _M_b; }
1325
1326 /**
1327 * Gets the minimum value in the generated random number range.
8e79468d 1328 */
94a86be0
BK
1329 static constexpr result_type
1330 min()
1331 { return _RandomNumberEngine::min(); }
8e79468d
BK
1332
1333 /**
1334 * Gets the maximum value in the generated random number range.
8e79468d 1335 */
94a86be0
BK
1336 static constexpr result_type
1337 max()
1338 { return _RandomNumberEngine::max(); }
8e79468d
BK
1339
1340 /**
1341 * Discard a sequence of random numbers.
8e79468d
BK
1342 */
1343 void
1344 discard(unsigned long long __z)
1345 {
1346 for (; __z != 0ULL; --__z)
1347 (*this)();
1348 }
1349
1350 /**
1351 * Gets the next value in the generated random number sequence.
1352 */
1353 result_type
1354 operator()();
1355
1356 /**
1357 * Compares two %shuffle_order_engine random number generator objects
1358 * of the same type for equality.
1359 *
1360 * @param __lhs A %shuffle_order_engine random number generator object.
1361 * @param __rhs Another %shuffle_order_engine random number generator
1362 * object.
1363 *
fc05e1ba
PC
1364 * @returns true if the infinite sequences of generated values
1365 * would be equal, false otherwise.
1366 */
8e79468d
BK
1367 friend bool
1368 operator==(const shuffle_order_engine& __lhs,
1369 const shuffle_order_engine& __rhs)
1370 { return __lhs._M_b == __rhs._M_b; }
1371
1372 /**
1373 * @brief Inserts the current state of a %shuffle_order_engine random
1374 * number generator engine @p __x into the output stream
1375 @p __os.
1376 *
1377 * @param __os An output stream.
1378 * @param __x A %shuffle_order_engine random number generator engine.
1379 *
1380 * @returns The output stream with the state of @p __x inserted or in
1381 * an error state.
1382 */
1383 template<typename _RandomNumberEngine1, size_t __k1,
1384 typename _CharT, typename _Traits>
1385 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
1386 operator<<(std::basic_ostream<_CharT, _Traits>&,
1387 const std::shuffle_order_engine<_RandomNumberEngine1,
1388 __k1>&);
8e79468d
BK
1389
1390 /**
1391 * @brief Extracts the current state of a % subtract_with_carry_engine
1392 * random number generator engine @p __x from the input stream
1393 * @p __is.
1394 *
1395 * @param __is An input stream.
1396 * @param __x A %shuffle_order_engine random number generator engine.
1397 *
1398 * @returns The input stream with the state of @p __x extracted or in
1399 * an error state.
1400 */
1401 template<typename _RandomNumberEngine1, size_t __k1,
1402 typename _CharT, typename _Traits>
1403 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
1404 operator>>(std::basic_istream<_CharT, _Traits>&,
1405 std::shuffle_order_engine<_RandomNumberEngine1, __k1>&);
8e79468d
BK
1406
1407 private:
1408 void _M_initialize()
1409 {
1410 for (size_t __i = 0; __i < __k; ++__i)
1411 _M_v[__i] = _M_b();
1412 _M_y = _M_b();
1413 }
1414
1415 _RandomNumberEngine _M_b;
1416 result_type _M_v[__k];
1417 result_type _M_y;
1418 };
1419
fc05e1ba
PC
1420 /**
1421 * Compares two %shuffle_order_engine random number generator objects
1422 * of the same type for inequality.
1423 *
1424 * @param __lhs A %shuffle_order_engine random number generator object.
1425 * @param __rhs Another %shuffle_order_engine random number generator
1426 * object.
1427 *
1428 * @returns true if the infinite sequences of generated values
1429 * would be different, false otherwise.
1430 */
1431 template<typename _RandomNumberEngine, size_t __k>
1432 inline bool
1433 operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
1434 __k>& __lhs,
1435 const std::shuffle_order_engine<_RandomNumberEngine,
1436 __k>& __rhs)
1437 { return !(__lhs == __rhs); }
1438
1439
8e79468d
BK
1440 /**
1441 * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
1442 */
1443 typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
1444 minstd_rand0;
1445
1446 /**
6cc5a790 1447 * An alternative LCR (Lehmer Generator function).
8e79468d
BK
1448 */
1449 typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
1450 minstd_rand;
1451
1452 /**
1453 * The classic Mersenne Twister.
1454 *
1455 * Reference:
2a60a9f6
BK
1456 * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
1457 * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
8e79468d
BK
1458 * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
1459 */
1460 typedef mersenne_twister_engine<
1461 uint_fast32_t,
1462 32, 624, 397, 31,
1463 0x9908b0dfUL, 11,
1464 0xffffffffUL, 7,
1465 0x9d2c5680UL, 15,
1466 0xefc60000UL, 18, 1812433253UL> mt19937;
1467
1468 /**
1469 * An alternative Mersenne Twister.
1470 */
1471 typedef mersenne_twister_engine<
1472 uint_fast64_t,
1473 64, 312, 156, 31,
1474 0xb5026f5aa96619e9ULL, 29,
1475 0x5555555555555555ULL, 17,
1476 0x71d67fffeda60000ULL, 37,
1477 0xfff7eee000000000ULL, 43,
1478 6364136223846793005ULL> mt19937_64;
1479
8e79468d
BK
1480 typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
1481 ranlux24_base;
1482
8e79468d
BK
1483 typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
1484 ranlux48_base;
1485
b94f4bef
PC
1486 typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
1487
8e79468d
BK
1488 typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
1489
8e79468d
BK
1490 typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
1491
8e79468d
BK
1492 typedef minstd_rand0 default_random_engine;
1493
1494 /**
1495 * A standard interface to a platform-specific non-deterministic
1496 * random number generator (if any are available).
1497 */
1498 class random_device
1499 {
1500 public:
1501 /** The type of the generated random value. */
1502 typedef unsigned int result_type;
1503
1504 // constructors, destructors and member functions
1505
1506#ifdef _GLIBCXX_USE_RANDOM_TR1
1507
1508 explicit
1509 random_device(const std::string& __token = "/dev/urandom")
1510 {
1511 if ((__token != "/dev/urandom" && __token != "/dev/random")
1512 || !(_M_file = std::fopen(__token.c_str(), "rb")))
1513 std::__throw_runtime_error(__N("random_device::"
1514 "random_device(const std::string&)"));
1515 }
1516
1517 ~random_device()
1518 { std::fclose(_M_file); }
1519
1520#else
1521
1522 explicit
1523 random_device(const std::string& __token = "mt19937")
1524 : _M_mt(_M_strtoul(__token)) { }
1525
1526 private:
1527 static unsigned long
1528 _M_strtoul(const std::string& __str)
1529 {
1530 unsigned long __ret = 5489UL;
1531 if (__str != "mt19937")
1532 {
1533 const char* __nptr = __str.c_str();
1534 char* __endptr;
1535 __ret = std::strtoul(__nptr, &__endptr, 0);
1536 if (*__nptr == '\0' || *__endptr != '\0')
1537 std::__throw_runtime_error(__N("random_device::_M_strtoul"
1538 "(const std::string&)"));
1539 }
1540 return __ret;
1541 }
1542
1543 public:
1544
1545#endif
1546
1547 result_type
1548 min() const
1549 { return std::numeric_limits<result_type>::min(); }
1550
1551 result_type
1552 max() const
1553 { return std::numeric_limits<result_type>::max(); }
1554
1555 double
1556 entropy() const
1557 { return 0.0; }
1558
1559 result_type
1560 operator()()
1561 {
1562#ifdef _GLIBCXX_USE_RANDOM_TR1
1563 result_type __ret;
1564 std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1565 1, _M_file);
1566 return __ret;
1567#else
1568 return _M_mt();
1569#endif
1570 }
1571
1572 // No copy functions.
1573 random_device(const random_device&) = delete;
1574 void operator=(const random_device&) = delete;
1575
1576 private:
1577
1578#ifdef _GLIBCXX_USE_RANDOM_TR1
1579 FILE* _M_file;
1580#else
1581 mt19937 _M_mt;
1582#endif
1583 };
1584
037181bc 1585 /* @} */ // group random_generators
8e79468d
BK
1586
1587 /**
037181bc
BK
1588 * @addtogroup random_distributions Random Number Distributions
1589 * @ingroup random
8e79468d
BK
1590 * @{
1591 */
1592
1593 /**
94a86be0 1594 * @addtogroup random_distributions_uniform Uniform Distributions
037181bc 1595 * @ingroup random_distributions
8e79468d
BK
1596 * @{
1597 */
1598
1599 /**
1600 * @brief Uniform discrete distribution for random numbers.
1601 * A discrete random distribution on the range @f$[min, max]@f$ with equal
1602 * probability throughout the range.
1603 */
1604 template<typename _IntType = int>
1605 class uniform_int_distribution
1606 {
77e3c516
PC
1607 static_assert(std::is_integral<_IntType>::value,
1608 "template argument not an integral type");
8e79468d
BK
1609
1610 public:
1611 /** The type of the range of the distribution. */
1612 typedef _IntType result_type;
1613 /** Parameter type. */
1614 struct param_type
1615 {
1616 typedef uniform_int_distribution<_IntType> distribution_type;
1617
1618 explicit
9b88236b
PC
1619 param_type(_IntType __a = 0,
1620 _IntType __b = std::numeric_limits<_IntType>::max())
8e79468d
BK
1621 : _M_a(__a), _M_b(__b)
1622 {
1623 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1624 }
1625
1626 result_type
1627 a() const
1628 { return _M_a; }
1629
1630 result_type
1631 b() const
1632 { return _M_b; }
1633
fc05e1ba
PC
1634 friend bool
1635 operator==(const param_type& __p1, const param_type& __p2)
1636 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1637
8e79468d
BK
1638 private:
1639 _IntType _M_a;
1640 _IntType _M_b;
1641 };
1642
1643 public:
1644 /**
1645 * @brief Constructs a uniform distribution object.
1646 */
1647 explicit
9b88236b
PC
1648 uniform_int_distribution(_IntType __a = 0,
1649 _IntType __b = std::numeric_limits<_IntType>::max())
8e79468d
BK
1650 : _M_param(__a, __b)
1651 { }
1652
1653 explicit
1654 uniform_int_distribution(const param_type& __p)
1655 : _M_param(__p)
1656 { }
1657
1658 /**
1659 * @brief Resets the distribution state.
1660 *
1661 * Does nothing for the uniform integer distribution.
1662 */
1663 void
1664 reset() { }
1665
1666 result_type
1667 a() const
1668 { return _M_param.a(); }
1669
1670 result_type
1671 b() const
1672 { return _M_param.b(); }
1673
8e79468d
BK
1674 /**
1675 * @brief Returns the parameter set of the distribution.
1676 */
1677 param_type
1678 param() const
1679 { return _M_param; }
1680
1681 /**
1682 * @brief Sets the parameter set of the distribution.
1683 * @param __param The new parameter set of the distribution.
1684 */
1685 void
1686 param(const param_type& __param)
1687 { _M_param = __param; }
1688
1689 /**
247d8075
PC
1690 * @brief Returns the inclusive lower bound of the distribution range.
1691 */
1692 result_type
1693 min() const
1694 { return this->a(); }
1695
1696 /**
1697 * @brief Returns the inclusive upper bound of the distribution range.
1698 */
1699 result_type
1700 max() const
1701 { return this->b(); }
1702
1703 /**
1704 * @brief Generating functions.
8e79468d
BK
1705 */
1706 template<typename _UniformRandomNumberGenerator>
1707 result_type
1708 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 1709 { return this->operator()(__urng, this->param()); }
8e79468d 1710
8e79468d
BK
1711 template<typename _UniformRandomNumberGenerator>
1712 result_type
1713 operator()(_UniformRandomNumberGenerator& __urng,
9b88236b 1714 const param_type& __p);
8e79468d
BK
1715
1716 param_type _M_param;
1717 };
1718
fc05e1ba
PC
1719 /**
1720 * @brief Return true if two uniform integer distributions have
1721 * the same parameters.
1722 */
1723 template<typename _IntType>
1724 inline bool
1725 operator==(const std::uniform_int_distribution<_IntType>& __d1,
1726 const std::uniform_int_distribution<_IntType>& __d2)
1727 { return __d1.param() == __d2.param(); }
1728
1729 /**
1730 * @brief Return true if two uniform integer distributions have
1731 * different parameters.
1732 */
1733 template<typename _IntType>
1734 inline bool
1735 operator!=(const std::uniform_int_distribution<_IntType>& __d1,
1736 const std::uniform_int_distribution<_IntType>& __d2)
1737 { return !(__d1 == __d2); }
1738
8e79468d
BK
1739 /**
1740 * @brief Inserts a %uniform_int_distribution random number
1741 * distribution @p __x into the output stream @p os.
1742 *
1743 * @param __os An output stream.
1744 * @param __x A %uniform_int_distribution random number distribution.
1745 *
1746 * @returns The output stream with the state of @p __x inserted or in
1747 * an error state.
1748 */
1749 template<typename _IntType, typename _CharT, typename _Traits>
1750 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
1751 operator<<(std::basic_ostream<_CharT, _Traits>&,
1752 const std::uniform_int_distribution<_IntType>&);
8e79468d
BK
1753
1754 /**
1755 * @brief Extracts a %uniform_int_distribution random number distribution
1756 * @p __x from the input stream @p __is.
1757 *
1758 * @param __is An input stream.
1759 * @param __x A %uniform_int_distribution random number generator engine.
1760 *
1761 * @returns The input stream with @p __x extracted or in an error state.
1762 */
1763 template<typename _IntType, typename _CharT, typename _Traits>
1764 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
1765 operator>>(std::basic_istream<_CharT, _Traits>&,
1766 std::uniform_int_distribution<_IntType>&);
8e79468d
BK
1767
1768
1769 /**
1770 * @brief Uniform continuous distribution for random numbers.
1771 *
1772 * A continuous random distribution on the range [min, max) with equal
1773 * probability throughout the range. The URNG should be real-valued and
1774 * deliver number in the range [0, 1).
1775 */
1776 template<typename _RealType = double>
1777 class uniform_real_distribution
1778 {
77e3c516
PC
1779 static_assert(std::is_floating_point<_RealType>::value,
1780 "template argument not a floating point type");
1781
8e79468d
BK
1782 public:
1783 /** The type of the range of the distribution. */
1784 typedef _RealType result_type;
1785 /** Parameter type. */
1786 struct param_type
1787 {
1788 typedef uniform_real_distribution<_RealType> distribution_type;
1789
1790 explicit
1791 param_type(_RealType __a = _RealType(0),
1792 _RealType __b = _RealType(1))
1793 : _M_a(__a), _M_b(__b)
1794 {
1795 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1796 }
1797
1798 result_type
1799 a() const
1800 { return _M_a; }
1801
1802 result_type
1803 b() const
1804 { return _M_b; }
1805
fc05e1ba
PC
1806 friend bool
1807 operator==(const param_type& __p1, const param_type& __p2)
1808 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1809
8e79468d
BK
1810 private:
1811 _RealType _M_a;
1812 _RealType _M_b;
1813 };
1814
1815 public:
1816 /**
1817 * @brief Constructs a uniform_real_distribution object.
1818 *
1819 * @param __min [IN] The lower bound of the distribution.
1820 * @param __max [IN] The upper bound of the distribution.
1821 */
1822 explicit
1823 uniform_real_distribution(_RealType __a = _RealType(0),
1824 _RealType __b = _RealType(1))
1825 : _M_param(__a, __b)
1826 { }
1827
1828 explicit
1829 uniform_real_distribution(const param_type& __p)
1830 : _M_param(__p)
1831 { }
1832
1833 /**
1834 * @brief Resets the distribution state.
1835 *
1836 * Does nothing for the uniform real distribution.
1837 */
1838 void
1839 reset() { }
1840
1841 result_type
1842 a() const
1843 { return _M_param.a(); }
1844
1845 result_type
1846 b() const
1847 { return _M_param.b(); }
1848
247d8075
PC
1849 /**
1850 * @brief Returns the parameter set of the distribution.
1851 */
1852 param_type
1853 param() const
1854 { return _M_param; }
1855
1856 /**
1857 * @brief Sets the parameter set of the distribution.
1858 * @param __param The new parameter set of the distribution.
1859 */
1860 void
1861 param(const param_type& __param)
1862 { _M_param = __param; }
1863
8e79468d
BK
1864 /**
1865 * @brief Returns the inclusive lower bound of the distribution range.
1866 */
1867 result_type
1868 min() const
1869 { return this->a(); }
1870
1871 /**
1872 * @brief Returns the inclusive upper bound of the distribution range.
1873 */
1874 result_type
1875 max() const
1876 { return this->b(); }
1877
1878 /**
247d8075 1879 * @brief Generating functions.
8e79468d 1880 */
8e79468d
BK
1881 template<typename _UniformRandomNumberGenerator>
1882 result_type
1883 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 1884 { return this->operator()(__urng, this->param()); }
8e79468d
BK
1885
1886 template<typename _UniformRandomNumberGenerator>
1887 result_type
1888 operator()(_UniformRandomNumberGenerator& __urng,
1889 const param_type& __p)
1890 {
1891 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1892 __aurng(__urng);
1893 return (__aurng() * (__p.b() - __p.a())) + __p.a();
1894 }
1895
1896 private:
1897 param_type _M_param;
1898 };
1899
fc05e1ba
PC
1900 /**
1901 * @brief Return true if two uniform real distributions have
1902 * the same parameters.
1903 */
1904 template<typename _IntType>
1905 inline bool
1906 operator==(const std::uniform_real_distribution<_IntType>& __d1,
1907 const std::uniform_real_distribution<_IntType>& __d2)
1908 { return __d1.param() == __d2.param(); }
1909
1910 /**
1911 * @brief Return true if two uniform real distributions have
1912 * different parameters.
1913 */
1914 template<typename _IntType>
1915 inline bool
1916 operator!=(const std::uniform_real_distribution<_IntType>& __d1,
1917 const std::uniform_real_distribution<_IntType>& __d2)
1918 { return !(__d1 == __d2); }
1919
8e79468d
BK
1920 /**
1921 * @brief Inserts a %uniform_real_distribution random number
1922 * distribution @p __x into the output stream @p __os.
1923 *
1924 * @param __os An output stream.
1925 * @param __x A %uniform_real_distribution random number distribution.
1926 *
1927 * @returns The output stream with the state of @p __x inserted or in
1928 * an error state.
1929 */
1930 template<typename _RealType, typename _CharT, typename _Traits>
1931 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
1932 operator<<(std::basic_ostream<_CharT, _Traits>&,
1933 const std::uniform_real_distribution<_RealType>&);
8e79468d
BK
1934
1935 /**
1936 * @brief Extracts a %uniform_real_distribution random number distribution
1937 * @p __x from the input stream @p __is.
1938 *
1939 * @param __is An input stream.
1940 * @param __x A %uniform_real_distribution random number generator engine.
1941 *
1942 * @returns The input stream with @p __x extracted or in an error state.
1943 */
1944 template<typename _RealType, typename _CharT, typename _Traits>
1945 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
1946 operator>>(std::basic_istream<_CharT, _Traits>&,
1947 std::uniform_real_distribution<_RealType>&);
8e79468d 1948
037181bc 1949 /* @} */ // group random_distributions_uniform
8e79468d
BK
1950
1951 /**
94a86be0 1952 * @addtogroup random_distributions_normal Normal Distributions
037181bc 1953 * @ingroup random_distributions
8e79468d
BK
1954 * @{
1955 */
1956
1957 /**
1958 * @brief A normal continuous distribution for random numbers.
1959 *
1960 * The formula for the normal probability density function is
6cc5a790
BK
1961 * @f[
1962 * p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
1963 * e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} }
1964 * @f]
8e79468d
BK
1965 */
1966 template<typename _RealType = double>
1967 class normal_distribution
1968 {
77e3c516
PC
1969 static_assert(std::is_floating_point<_RealType>::value,
1970 "template argument not a floating point type");
1971
8e79468d
BK
1972 public:
1973 /** The type of the range of the distribution. */
1974 typedef _RealType result_type;
1975 /** Parameter type. */
1976 struct param_type
1977 {
1978 typedef normal_distribution<_RealType> distribution_type;
1979
1980 explicit
1981 param_type(_RealType __mean = _RealType(0),
1982 _RealType __stddev = _RealType(1))
1983 : _M_mean(__mean), _M_stddev(__stddev)
1984 {
1985 _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
1986 }
1987
1988 _RealType
1989 mean() const
1990 { return _M_mean; }
1991
1992 _RealType
1993 stddev() const
1994 { return _M_stddev; }
1995
fc05e1ba
PC
1996 friend bool
1997 operator==(const param_type& __p1, const param_type& __p2)
1998 { return (__p1._M_mean == __p2._M_mean
1999 && __p1._M_stddev == __p2._M_stddev); }
2000
8e79468d
BK
2001 private:
2002 _RealType _M_mean;
2003 _RealType _M_stddev;
2004 };
2005
2006 public:
2007 /**
6cc5a790 2008 * Constructs a normal distribution with parameters @f$mean@f$ and
8e79468d
BK
2009 * standard deviation.
2010 */
2011 explicit
2012 normal_distribution(result_type __mean = result_type(0),
2013 result_type __stddev = result_type(1))
2014 : _M_param(__mean, __stddev), _M_saved_available(false)
2015 { }
2016
2017 explicit
2018 normal_distribution(const param_type& __p)
2019 : _M_param(__p), _M_saved_available(false)
2020 { }
2021
2022 /**
2023 * @brief Resets the distribution state.
2024 */
2025 void
2026 reset()
2027 { _M_saved_available = false; }
2028
2029 /**
2030 * @brief Returns the mean of the distribution.
2031 */
2032 _RealType
2033 mean() const
2034 { return _M_param.mean(); }
2035
2036 /**
2037 * @brief Returns the standard deviation of the distribution.
2038 */
2039 _RealType
2040 stddev() const
2041 { return _M_param.stddev(); }
2042
2043 /**
2044 * @brief Returns the parameter set of the distribution.
2045 */
2046 param_type
2047 param() const
2048 { return _M_param; }
2049
2050 /**
2051 * @brief Sets the parameter set of the distribution.
2052 * @param __param The new parameter set of the distribution.
2053 */
2054 void
2055 param(const param_type& __param)
2056 { _M_param = __param; }
2057
2058 /**
2059 * @brief Returns the greatest lower bound value of the distribution.
2060 */
2061 result_type
2062 min() const
2063 { return std::numeric_limits<result_type>::min(); }
2064
2065 /**
2066 * @brief Returns the least upper bound value of the distribution.
2067 */
2068 result_type
2069 max() const
2070 { return std::numeric_limits<result_type>::max(); }
2071
247d8075
PC
2072 /**
2073 * @brief Generating functions.
2074 */
8e79468d
BK
2075 template<typename _UniformRandomNumberGenerator>
2076 result_type
2077 operator()(_UniformRandomNumberGenerator& __urng)
2078 { return this->operator()(__urng, this->param()); }
2079
2080 template<typename _UniformRandomNumberGenerator>
2081 result_type
2082 operator()(_UniformRandomNumberGenerator& __urng,
2083 const param_type& __p);
2084
fc05e1ba
PC
2085 /**
2086 * @brief Return true if two normal distributions have
2087 * the same parameters and the sequences that would
2088 * be generated are equal.
2089 */
2090 template<typename _RealType1>
2091 friend bool
2092 operator==(const std::normal_distribution<_RealType1>& __d1,
2093 const std::normal_distribution<_RealType1>& __d2);
2094
8e79468d
BK
2095 /**
2096 * @brief Inserts a %normal_distribution random number distribution
2097 * @p __x into the output stream @p __os.
2098 *
2099 * @param __os An output stream.
2100 * @param __x A %normal_distribution random number distribution.
2101 *
2102 * @returns The output stream with the state of @p __x inserted or in
2103 * an error state.
2104 */
2105 template<typename _RealType1, typename _CharT, typename _Traits>
2106 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
2107 operator<<(std::basic_ostream<_CharT, _Traits>&,
2108 const std::normal_distribution<_RealType1>&);
8e79468d
BK
2109
2110 /**
2111 * @brief Extracts a %normal_distribution random number distribution
2112 * @p __x from the input stream @p __is.
2113 *
2114 * @param __is An input stream.
2115 * @param __x A %normal_distribution random number generator engine.
2116 *
2117 * @returns The input stream with @p __x extracted or in an error
2118 * state.
2119 */
2120 template<typename _RealType1, typename _CharT, typename _Traits>
2121 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
2122 operator>>(std::basic_istream<_CharT, _Traits>&,
2123 std::normal_distribution<_RealType1>&);
8e79468d
BK
2124
2125 private:
2126 param_type _M_param;
2127 result_type _M_saved;
2128 bool _M_saved_available;
2129 };
2130
fc05e1ba
PC
2131 /**
2132 * @brief Return true if two normal distributions are different.
2133 */
2134 template<typename _RealType>
2135 inline bool
2136 operator!=(const std::normal_distribution<_RealType>& __d1,
2137 const std::normal_distribution<_RealType>& __d2)
2138 { return !(__d1 == __d2); }
2139
8e79468d
BK
2140
2141 /**
2142 * @brief A lognormal_distribution random number distribution.
2143 *
2144 * The formula for the normal probability mass function is
6cc5a790
BK
2145 * @f[
2146 * p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
2147 * \exp{-\frac{(\ln{x} - m)^2}{2s^2}}
2148 * @f]
8e79468d
BK
2149 */
2150 template<typename _RealType = double>
2151 class lognormal_distribution
2152 {
77e3c516
PC
2153 static_assert(std::is_floating_point<_RealType>::value,
2154 "template argument not a floating point type");
2155
8e79468d
BK
2156 public:
2157 /** The type of the range of the distribution. */
2158 typedef _RealType result_type;
2159 /** Parameter type. */
2160 struct param_type
2161 {
2162 typedef lognormal_distribution<_RealType> distribution_type;
2163
2164 explicit
2165 param_type(_RealType __m = _RealType(0),
2166 _RealType __s = _RealType(1))
2167 : _M_m(__m), _M_s(__s)
2168 { }
2169
2170 _RealType
2171 m() const
2172 { return _M_m; }
2173
2174 _RealType
2175 s() const
2176 { return _M_s; }
2177
fc05e1ba
PC
2178 friend bool
2179 operator==(const param_type& __p1, const param_type& __p2)
2180 { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
2181
8e79468d
BK
2182 private:
2183 _RealType _M_m;
2184 _RealType _M_s;
2185 };
2186
2187 explicit
2188 lognormal_distribution(_RealType __m = _RealType(0),
2189 _RealType __s = _RealType(1))
b01630bb 2190 : _M_param(__m, __s), _M_nd()
8e79468d
BK
2191 { }
2192
2193 explicit
2194 lognormal_distribution(const param_type& __p)
b01630bb 2195 : _M_param(__p), _M_nd()
8e79468d
BK
2196 { }
2197
2198 /**
2199 * Resets the distribution state.
2200 */
2201 void
2202 reset()
b01630bb 2203 { _M_nd.reset(); }
8e79468d
BK
2204
2205 /**
2206 *
2207 */
2208 _RealType
2209 m() const
2210 { return _M_param.m(); }
2211
2212 _RealType
2213 s() const
2214 { return _M_param.s(); }
2215
2216 /**
2217 * @brief Returns the parameter set of the distribution.
2218 */
2219 param_type
2220 param() const
2221 { return _M_param; }
2222
2223 /**
2224 * @brief Sets the parameter set of the distribution.
2225 * @param __param The new parameter set of the distribution.
2226 */
2227 void
2228 param(const param_type& __param)
2229 { _M_param = __param; }
2230
2231 /**
2232 * @brief Returns the greatest lower bound value of the distribution.
2233 */
2234 result_type
2235 min() const
2236 { return result_type(0); }
2237
2238 /**
2239 * @brief Returns the least upper bound value of the distribution.
2240 */
2241 result_type
2242 max() const
2243 { return std::numeric_limits<result_type>::max(); }
2244
247d8075
PC
2245 /**
2246 * @brief Generating functions.
2247 */
8e79468d
BK
2248 template<typename _UniformRandomNumberGenerator>
2249 result_type
2250 operator()(_UniformRandomNumberGenerator& __urng)
2251 { return this->operator()(__urng, this->param()); }
2252
2253 template<typename _UniformRandomNumberGenerator>
2254 result_type
2255 operator()(_UniformRandomNumberGenerator& __urng,
b01630bb
PC
2256 const param_type& __p)
2257 { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
8e79468d 2258
fc05e1ba
PC
2259 /**
2260 * @brief Return true if two lognormal distributions have
2261 * the same parameters and the sequences that would
2262 * be generated are equal.
2263 */
2264 template<typename _RealType1>
2265 friend bool
2266 operator==(const std::lognormal_distribution<_RealType1>& __d1,
2267 const std::lognormal_distribution<_RealType1>& __d2)
2268 { return (__d1.param() == __d2.param()
2269 && __d1._M_nd == __d2._M_nd); }
2270
e1923769
ESR
2271 /**
2272 * @brief Inserts a %lognormal_distribution random number distribution
2273 * @p __x into the output stream @p __os.
2274 *
2275 * @param __os An output stream.
2276 * @param __x A %lognormal_distribution random number distribution.
2277 *
2278 * @returns The output stream with the state of @p __x inserted or in
2279 * an error state.
2280 */
2281 template<typename _RealType1, typename _CharT, typename _Traits>
2282 friend std::basic_ostream<_CharT, _Traits>&
2283 operator<<(std::basic_ostream<_CharT, _Traits>&,
2284 const std::lognormal_distribution<_RealType1>&);
2285
2286 /**
2287 * @brief Extracts a %lognormal_distribution random number distribution
2288 * @p __x from the input stream @p __is.
2289 *
2290 * @param __is An input stream.
2291 * @param __x A %lognormal_distribution random number
2292 * generator engine.
2293 *
2294 * @returns The input stream with @p __x extracted or in an error state.
2295 */
2296 template<typename _RealType1, typename _CharT, typename _Traits>
2297 friend std::basic_istream<_CharT, _Traits>&
2298 operator>>(std::basic_istream<_CharT, _Traits>&,
2299 std::lognormal_distribution<_RealType1>&);
2300
8e79468d
BK
2301 private:
2302 param_type _M_param;
b01630bb 2303
f9b09dec 2304 std::normal_distribution<result_type> _M_nd;
8e79468d
BK
2305 };
2306
fc05e1ba
PC
2307 /**
2308 * @brief Return true if two lognormal distributions are different.
2309 */
2310 template<typename _RealType>
2311 inline bool
2312 operator!=(const std::lognormal_distribution<_RealType>& __d1,
2313 const std::lognormal_distribution<_RealType>& __d2)
2314 { return !(__d1 == __d2); }
2315
2316
f9b09dec
PC
2317 /**
2318 * @brief A gamma continuous distribution for random numbers.
2319 *
6cc5a790
BK
2320 * The formula for the gamma probability density function is:
2321 * @f[
2322 * p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
2323 * (x/\beta)^{\alpha - 1} e^{-x/\beta}
2324 * @f]
f9b09dec
PC
2325 */
2326 template<typename _RealType = double>
2327 class gamma_distribution
2328 {
77e3c516
PC
2329 static_assert(std::is_floating_point<_RealType>::value,
2330 "template argument not a floating point type");
2331
f9b09dec
PC
2332 public:
2333 /** The type of the range of the distribution. */
2334 typedef _RealType result_type;
2335 /** Parameter type. */
2336 struct param_type
2337 {
2338 typedef gamma_distribution<_RealType> distribution_type;
2339 friend class gamma_distribution<_RealType>;
2340
2341 explicit
2342 param_type(_RealType __alpha_val = _RealType(1),
2343 _RealType __beta_val = _RealType(1))
2344 : _M_alpha(__alpha_val), _M_beta(__beta_val)
2345 {
2346 _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
2347 _M_initialize();
2348 }
2349
2350 _RealType
2351 alpha() const
2352 { return _M_alpha; }
2353
2354 _RealType
2355 beta() const
2356 { return _M_beta; }
2357
fc05e1ba
PC
2358 friend bool
2359 operator==(const param_type& __p1, const param_type& __p2)
2360 { return (__p1._M_alpha == __p2._M_alpha
2361 && __p1._M_beta == __p2._M_beta); }
2362
f9b09dec
PC
2363 private:
2364 void
2365 _M_initialize();
2366
2367 _RealType _M_alpha;
2368 _RealType _M_beta;
2369
2370 _RealType _M_malpha, _M_a2;
2371 };
2372
2373 public:
2374 /**
2375 * @brief Constructs a gamma distribution with parameters
6cc5a790 2376 * @f$\alpha@f$ and @f$\beta@f$.
f9b09dec
PC
2377 */
2378 explicit
2379 gamma_distribution(_RealType __alpha_val = _RealType(1),
2380 _RealType __beta_val = _RealType(1))
2381 : _M_param(__alpha_val, __beta_val), _M_nd()
2382 { }
2383
2384 explicit
2385 gamma_distribution(const param_type& __p)
2386 : _M_param(__p), _M_nd()
2387 { }
2388
2389 /**
2390 * @brief Resets the distribution state.
2391 */
2392 void
2393 reset()
2394 { _M_nd.reset(); }
2395
2396 /**
6cc5a790 2397 * @brief Returns the @f$\alpha@f$ of the distribution.
f9b09dec
PC
2398 */
2399 _RealType
2400 alpha() const
2401 { return _M_param.alpha(); }
2402
2403 /**
6cc5a790 2404 * @brief Returns the @f$\beta@f$ of the distribution.
f9b09dec
PC
2405 */
2406 _RealType
2407 beta() const
2408 { return _M_param.beta(); }
2409
2410 /**
2411 * @brief Returns the parameter set of the distribution.
2412 */
2413 param_type
2414 param() const
2415 { return _M_param; }
2416
2417 /**
2418 * @brief Sets the parameter set of the distribution.
2419 * @param __param The new parameter set of the distribution.
2420 */
2421 void
2422 param(const param_type& __param)
2423 { _M_param = __param; }
2424
2425 /**
2426 * @brief Returns the greatest lower bound value of the distribution.
2427 */
2428 result_type
2429 min() const
2430 { return result_type(0); }
2431
2432 /**
2433 * @brief Returns the least upper bound value of the distribution.
2434 */
2435 result_type
2436 max() const
2437 { return std::numeric_limits<result_type>::max(); }
2438
247d8075
PC
2439 /**
2440 * @brief Generating functions.
2441 */
f9b09dec
PC
2442 template<typename _UniformRandomNumberGenerator>
2443 result_type
2444 operator()(_UniformRandomNumberGenerator& __urng)
2445 { return this->operator()(__urng, this->param()); }
2446
2447 template<typename _UniformRandomNumberGenerator>
2448 result_type
2449 operator()(_UniformRandomNumberGenerator& __urng,
2450 const param_type& __p);
2451
fc05e1ba
PC
2452 /**
2453 * @brief Return true if two gamma distributions have the same
2454 * parameters and the sequences that would be generated
2455 * are equal.
2456 */
2457 template<typename _RealType1>
2458 friend bool
2459 operator==(const std::gamma_distribution<_RealType1>& __d1,
2460 const std::gamma_distribution<_RealType1>& __d2)
2461 { return (__d1.param() == __d2.param()
2462 && __d1._M_nd == __d2._M_nd); }
2463
e1923769
ESR
2464 /**
2465 * @brief Inserts a %gamma_distribution random number distribution
2466 * @p __x into the output stream @p __os.
2467 *
2468 * @param __os An output stream.
2469 * @param __x A %gamma_distribution random number distribution.
2470 *
2471 * @returns The output stream with the state of @p __x inserted or in
2472 * an error state.
2473 */
2474 template<typename _RealType1, typename _CharT, typename _Traits>
2475 friend std::basic_ostream<_CharT, _Traits>&
2476 operator<<(std::basic_ostream<_CharT, _Traits>&,
2477 const std::gamma_distribution<_RealType1>&);
2478
2479 /**
2480 * @brief Extracts a %gamma_distribution random number distribution
2481 * @p __x from the input stream @p __is.
2482 *
2483 * @param __is An input stream.
2484 * @param __x A %gamma_distribution random number generator engine.
2485 *
2486 * @returns The input stream with @p __x extracted or in an error state.
2487 */
2488 template<typename _RealType1, typename _CharT, typename _Traits>
2489 friend std::basic_istream<_CharT, _Traits>&
2490 operator>>(std::basic_istream<_CharT, _Traits>&,
2491 std::gamma_distribution<_RealType1>&);
2492
f9b09dec
PC
2493 private:
2494 param_type _M_param;
2495
2496 std::normal_distribution<result_type> _M_nd;
2497 };
2498
fc05e1ba
PC
2499 /**
2500 * @brief Return true if two gamma distributions are different.
2501 */
2502 template<typename _RealType>
2503 inline bool
2504 operator!=(const std::gamma_distribution<_RealType>& __d1,
2505 const std::gamma_distribution<_RealType>& __d2)
2506 { return !(__d1 == __d2); }
2507
8e79468d
BK
2508
2509 /**
2510 * @brief A chi_squared_distribution random number distribution.
2511 *
2512 * The formula for the normal probability mass function is
6cc5a790 2513 * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
8e79468d
BK
2514 */
2515 template<typename _RealType = double>
2516 class chi_squared_distribution
2517 {
77e3c516
PC
2518 static_assert(std::is_floating_point<_RealType>::value,
2519 "template argument not a floating point type");
2520
8e79468d
BK
2521 public:
2522 /** The type of the range of the distribution. */
2523 typedef _RealType result_type;
2524 /** Parameter type. */
2525 struct param_type
2526 {
2527 typedef chi_squared_distribution<_RealType> distribution_type;
2528
2529 explicit
2530 param_type(_RealType __n = _RealType(1))
2531 : _M_n(__n)
2532 { }
2533
2534 _RealType
2535 n() const
2536 { return _M_n; }
2537
fc05e1ba
PC
2538 friend bool
2539 operator==(const param_type& __p1, const param_type& __p2)
2540 { return __p1._M_n == __p2._M_n; }
2541
8e79468d
BK
2542 private:
2543 _RealType _M_n;
2544 };
2545
2546 explicit
2547 chi_squared_distribution(_RealType __n = _RealType(1))
f9b09dec 2548 : _M_param(__n), _M_gd(__n / 2)
8e79468d
BK
2549 { }
2550
2551 explicit
2552 chi_squared_distribution(const param_type& __p)
f9b09dec 2553 : _M_param(__p), _M_gd(__p.n() / 2)
8e79468d
BK
2554 { }
2555
2556 /**
2557 * @brief Resets the distribution state.
2558 */
2559 void
2560 reset()
f9b09dec 2561 { _M_gd.reset(); }
8e79468d
BK
2562
2563 /**
2564 *
2565 */
2566 _RealType
2567 n() const
2568 { return _M_param.n(); }
2569
2570 /**
2571 * @brief Returns the parameter set of the distribution.
2572 */
2573 param_type
2574 param() const
2575 { return _M_param; }
2576
2577 /**
2578 * @brief Sets the parameter set of the distribution.
2579 * @param __param The new parameter set of the distribution.
2580 */
2581 void
2582 param(const param_type& __param)
2583 { _M_param = __param; }
2584
2585 /**
2586 * @brief Returns the greatest lower bound value of the distribution.
2587 */
2588 result_type
2589 min() const
2590 { return result_type(0); }
2591
2592 /**
2593 * @brief Returns the least upper bound value of the distribution.
2594 */
2595 result_type
2596 max() const
2597 { return std::numeric_limits<result_type>::max(); }
2598
247d8075
PC
2599 /**
2600 * @brief Generating functions.
2601 */
8e79468d
BK
2602 template<typename _UniformRandomNumberGenerator>
2603 result_type
2604 operator()(_UniformRandomNumberGenerator& __urng)
f9b09dec 2605 { return 2 * _M_gd(__urng); }
8e79468d
BK
2606
2607 template<typename _UniformRandomNumberGenerator>
2608 result_type
2609 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
2610 const param_type& __p)
2611 {
2612 typedef typename std::gamma_distribution<result_type>::param_type
2613 param_type;
2614 return 2 * _M_gd(__urng, param_type(__p.n() / 2));
2615 }
8e79468d 2616
fc05e1ba
PC
2617 /**
2618 * @brief Return true if two Chi-squared distributions have
2619 * the same parameters and the sequences that would be
2620 * generated are equal.
2621 */
2622 template<typename _RealType1>
2623 friend bool
2624 operator==(const std::chi_squared_distribution<_RealType1>& __d1,
2625 const std::chi_squared_distribution<_RealType1>& __d2)
2626 { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
2627
e1923769
ESR
2628 /**
2629 * @brief Inserts a %chi_squared_distribution random number distribution
2630 * @p __x into the output stream @p __os.
2631 *
2632 * @param __os An output stream.
2633 * @param __x A %chi_squared_distribution random number distribution.
2634 *
2635 * @returns The output stream with the state of @p __x inserted or in
2636 * an error state.
2637 */
2638 template<typename _RealType1, typename _CharT, typename _Traits>
2639 friend std::basic_ostream<_CharT, _Traits>&
2640 operator<<(std::basic_ostream<_CharT, _Traits>&,
2641 const std::chi_squared_distribution<_RealType1>&);
2642
2643 /**
2644 * @brief Extracts a %chi_squared_distribution random number distribution
2645 * @p __x from the input stream @p __is.
2646 *
2647 * @param __is An input stream.
2648 * @param __x A %chi_squared_distribution random number
2649 * generator engine.
2650 *
2651 * @returns The input stream with @p __x extracted or in an error state.
2652 */
2653 template<typename _RealType1, typename _CharT, typename _Traits>
2654 friend std::basic_istream<_CharT, _Traits>&
2655 operator>>(std::basic_istream<_CharT, _Traits>&,
2656 std::chi_squared_distribution<_RealType1>&);
2657
8e79468d
BK
2658 private:
2659 param_type _M_param;
f9b09dec
PC
2660
2661 std::gamma_distribution<result_type> _M_gd;
8e79468d
BK
2662 };
2663
fc05e1ba
PC
2664 /**
2665 * @brief Return true if two Chi-squared distributions are different.
2666 */
2667 template<typename _RealType>
2668 inline bool
2669 operator!=(const std::chi_squared_distribution<_RealType>& __d1,
2670 const std::chi_squared_distribution<_RealType>& __d2)
2671 { return !(__d1 == __d2); }
2672
8e79468d
BK
2673
2674 /**
2675 * @brief A cauchy_distribution random number distribution.
2676 *
2677 * The formula for the normal probability mass function is
6cc5a790 2678 * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
8e79468d
BK
2679 */
2680 template<typename _RealType = double>
2681 class cauchy_distribution
2682 {
77e3c516
PC
2683 static_assert(std::is_floating_point<_RealType>::value,
2684 "template argument not a floating point type");
2685
8e79468d
BK
2686 public:
2687 /** The type of the range of the distribution. */
2688 typedef _RealType result_type;
2689 /** Parameter type. */
2690 struct param_type
2691 {
2692 typedef cauchy_distribution<_RealType> distribution_type;
2693
2694 explicit
2695 param_type(_RealType __a = _RealType(0),
2696 _RealType __b = _RealType(1))
2697 : _M_a(__a), _M_b(__b)
2698 { }
2699
2700 _RealType
2701 a() const
2702 { return _M_a; }
2703
2704 _RealType
2705 b() const
2706 { return _M_b; }
2707
fc05e1ba
PC
2708 friend bool
2709 operator==(const param_type& __p1, const param_type& __p2)
2710 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
2711
8e79468d
BK
2712 private:
2713 _RealType _M_a;
2714 _RealType _M_b;
2715 };
2716
2717 explicit
2718 cauchy_distribution(_RealType __a = _RealType(0),
2719 _RealType __b = _RealType(1))
2720 : _M_param(__a, __b)
2721 { }
2722
2723 explicit
2724 cauchy_distribution(const param_type& __p)
2725 : _M_param(__p)
2726 { }
2727
2728 /**
2729 * @brief Resets the distribution state.
2730 */
2731 void
2732 reset()
2733 { }
2734
2735 /**
2736 *
2737 */
2738 _RealType
2739 a() const
2740 { return _M_param.a(); }
2741
2742 _RealType
2743 b() const
2744 { return _M_param.b(); }
2745
2746 /**
2747 * @brief Returns the parameter set of the distribution.
2748 */
2749 param_type
2750 param() const
2751 { return _M_param; }
2752
2753 /**
2754 * @brief Sets the parameter set of the distribution.
2755 * @param __param The new parameter set of the distribution.
2756 */
2757 void
2758 param(const param_type& __param)
2759 { _M_param = __param; }
2760
2761 /**
2762 * @brief Returns the greatest lower bound value of the distribution.
2763 */
2764 result_type
2765 min() const
2766 { return std::numeric_limits<result_type>::min(); }
2767
2768 /**
2769 * @brief Returns the least upper bound value of the distribution.
2770 */
2771 result_type
2772 max() const
2773 { return std::numeric_limits<result_type>::max(); }
2774
247d8075
PC
2775 /**
2776 * @brief Generating functions.
2777 */
8e79468d
BK
2778 template<typename _UniformRandomNumberGenerator>
2779 result_type
2780 operator()(_UniformRandomNumberGenerator& __urng)
2781 { return this->operator()(__urng, this->param()); }
2782
2783 template<typename _UniformRandomNumberGenerator>
2784 result_type
2785 operator()(_UniformRandomNumberGenerator& __urng,
2786 const param_type& __p);
2787
2788 private:
2789 param_type _M_param;
2790 };
2791
fc05e1ba
PC
2792 /**
2793 * @brief Return true if two Cauchy distributions have
2794 * the same parameters.
2795 */
2796 template<typename _RealType>
2797 inline bool
2798 operator==(const std::cauchy_distribution<_RealType>& __d1,
2799 const std::cauchy_distribution<_RealType>& __d2)
2800 { return __d1.param() == __d2.param(); }
2801
2802 /**
2803 * @brief Return true if two Cauchy distributions have
2804 * different parameters.
2805 */
2806 template<typename _RealType>
2807 inline bool
2808 operator!=(const std::cauchy_distribution<_RealType>& __d1,
2809 const std::cauchy_distribution<_RealType>& __d2)
2810 { return !(__d1 == __d2); }
2811
8e79468d
BK
2812 /**
2813 * @brief Inserts a %cauchy_distribution random number distribution
2814 * @p __x into the output stream @p __os.
2815 *
2816 * @param __os An output stream.
2817 * @param __x A %cauchy_distribution random number distribution.
2818 *
2819 * @returns The output stream with the state of @p __x inserted or in
2820 * an error state.
2821 */
2822 template<typename _RealType, typename _CharT, typename _Traits>
2823 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
2824 operator<<(std::basic_ostream<_CharT, _Traits>&,
2825 const std::cauchy_distribution<_RealType>&);
8e79468d
BK
2826
2827 /**
2828 * @brief Extracts a %cauchy_distribution random number distribution
2829 * @p __x from the input stream @p __is.
2830 *
2831 * @param __is An input stream.
2832 * @param __x A %cauchy_distribution random number
2833 * generator engine.
2834 *
2835 * @returns The input stream with @p __x extracted or in an error state.
2836 */
2837 template<typename _RealType, typename _CharT, typename _Traits>
2838 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
2839 operator>>(std::basic_istream<_CharT, _Traits>&,
2840 std::cauchy_distribution<_RealType>&);
8e79468d
BK
2841
2842
2843 /**
2844 * @brief A fisher_f_distribution random number distribution.
2845 *
2846 * The formula for the normal probability mass function is
6cc5a790
BK
2847 * @f[
2848 * p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
04b70271 2849 * (\frac{m}{n})^{m/2} x^{(m/2)-1}
6cc5a790
BK
2850 * (1 + \frac{mx}{n})^{-(m+n)/2}
2851 * @f]
8e79468d
BK
2852 */
2853 template<typename _RealType = double>
2854 class fisher_f_distribution
2855 {
77e3c516
PC
2856 static_assert(std::is_floating_point<_RealType>::value,
2857 "template argument not a floating point type");
2858
8e79468d
BK
2859 public:
2860 /** The type of the range of the distribution. */
2861 typedef _RealType result_type;
2862 /** Parameter type. */
2863 struct param_type
2864 {
2865 typedef fisher_f_distribution<_RealType> distribution_type;
2866
2867 explicit
2868 param_type(_RealType __m = _RealType(1),
2869 _RealType __n = _RealType(1))
2870 : _M_m(__m), _M_n(__n)
2871 { }
2872
2873 _RealType
2874 m() const
2875 { return _M_m; }
2876
2877 _RealType
2878 n() const
2879 { return _M_n; }
2880
fc05e1ba
PC
2881 friend bool
2882 operator==(const param_type& __p1, const param_type& __p2)
2883 { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
2884
8e79468d
BK
2885 private:
2886 _RealType _M_m;
2887 _RealType _M_n;
2888 };
2889
2890 explicit
2891 fisher_f_distribution(_RealType __m = _RealType(1),
2892 _RealType __n = _RealType(1))
f9b09dec 2893 : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
8e79468d
BK
2894 { }
2895
2896 explicit
2897 fisher_f_distribution(const param_type& __p)
f9b09dec 2898 : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
8e79468d
BK
2899 { }
2900
2901 /**
2902 * @brief Resets the distribution state.
2903 */
2904 void
2905 reset()
f9b09dec
PC
2906 {
2907 _M_gd_x.reset();
2908 _M_gd_y.reset();
2909 }
8e79468d
BK
2910
2911 /**
2912 *
2913 */
2914 _RealType
2915 m() const
2916 { return _M_param.m(); }
2917
2918 _RealType
2919 n() const
2920 { return _M_param.n(); }
2921
2922 /**
2923 * @brief Returns the parameter set of the distribution.
2924 */
2925 param_type
2926 param() const
2927 { return _M_param; }
2928
2929 /**
2930 * @brief Sets the parameter set of the distribution.
2931 * @param __param The new parameter set of the distribution.
2932 */
2933 void
2934 param(const param_type& __param)
2935 { _M_param = __param; }
2936
2937 /**
2938 * @brief Returns the greatest lower bound value of the distribution.
2939 */
2940 result_type
2941 min() const
2942 { return result_type(0); }
2943
2944 /**
2945 * @brief Returns the least upper bound value of the distribution.
2946 */
2947 result_type
2948 max() const
2949 { return std::numeric_limits<result_type>::max(); }
2950
247d8075
PC
2951 /**
2952 * @brief Generating functions.
2953 */
8e79468d
BK
2954 template<typename _UniformRandomNumberGenerator>
2955 result_type
2956 operator()(_UniformRandomNumberGenerator& __urng)
f9b09dec 2957 { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
8e79468d
BK
2958
2959 template<typename _UniformRandomNumberGenerator>
2960 result_type
2961 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
2962 const param_type& __p)
2963 {
2964 typedef typename std::gamma_distribution<result_type>::param_type
2965 param_type;
2966 return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
2967 / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
2968 }
8e79468d 2969
fc05e1ba
PC
2970 /**
2971 * @brief Return true if two Fisher f distributions have
2972 * the same parameters and the sequences that would
2973 * be generated are equal.
2974 */
2975 template<typename _RealType1>
2976 friend bool
2977 operator==(const std::fisher_f_distribution<_RealType1>& __d1,
2978 const std::fisher_f_distribution<_RealType1>& __d2)
2979 { return (__d1.param() == __d2.param()
2980 && __d1._M_gd_x == __d2._M_gd_x
2981 && __d1._M_gd_y == __d2._M_gd_y); }
2982
e1923769
ESR
2983 /**
2984 * @brief Inserts a %fisher_f_distribution random number distribution
2985 * @p __x into the output stream @p __os.
2986 *
2987 * @param __os An output stream.
2988 * @param __x A %fisher_f_distribution random number distribution.
2989 *
2990 * @returns The output stream with the state of @p __x inserted or in
2991 * an error state.
2992 */
2993 template<typename _RealType1, typename _CharT, typename _Traits>
2994 friend std::basic_ostream<_CharT, _Traits>&
2995 operator<<(std::basic_ostream<_CharT, _Traits>&,
2996 const std::fisher_f_distribution<_RealType1>&);
2997
2998 /**
2999 * @brief Extracts a %fisher_f_distribution random number distribution
3000 * @p __x from the input stream @p __is.
3001 *
3002 * @param __is An input stream.
3003 * @param __x A %fisher_f_distribution random number
3004 * generator engine.
3005 *
3006 * @returns The input stream with @p __x extracted or in an error state.
3007 */
3008 template<typename _RealType1, typename _CharT, typename _Traits>
3009 friend std::basic_istream<_CharT, _Traits>&
3010 operator>>(std::basic_istream<_CharT, _Traits>&,
3011 std::fisher_f_distribution<_RealType1>&);
3012
8e79468d
BK
3013 private:
3014 param_type _M_param;
f9b09dec
PC
3015
3016 std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
8e79468d
BK
3017 };
3018
fc05e1ba
PC
3019 /**
3020 * @brief Return true if two Fisher f distributions are diferent.
3021 */
3022 template<typename _RealType>
3023 inline bool
3024 operator!=(const std::fisher_f_distribution<_RealType>& __d1,
3025 const std::fisher_f_distribution<_RealType>& __d2)
3026 { return !(__d1 == __d2); }
8e79468d
BK
3027
3028 /**
3029 * @brief A student_t_distribution random number distribution.
3030 *
6cc5a790
BK
3031 * The formula for the normal probability mass function is:
3032 * @f[
3033 * p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
3034 * (1 + \frac{x^2}{n}) ^{-(n+1)/2}
3035 * @f]
8e79468d
BK
3036 */
3037 template<typename _RealType = double>
3038 class student_t_distribution
3039 {
77e3c516
PC
3040 static_assert(std::is_floating_point<_RealType>::value,
3041 "template argument not a floating point type");
3042
8e79468d
BK
3043 public:
3044 /** The type of the range of the distribution. */
3045 typedef _RealType result_type;
3046 /** Parameter type. */
3047 struct param_type
3048 {
3049 typedef student_t_distribution<_RealType> distribution_type;
3050
3051 explicit
3052 param_type(_RealType __n = _RealType(1))
3053 : _M_n(__n)
3054 { }
3055
3056 _RealType
3057 n() const
3058 { return _M_n; }
3059
fc05e1ba
PC
3060 friend bool
3061 operator==(const param_type& __p1, const param_type& __p2)
3062 { return __p1._M_n == __p2._M_n; }
3063
8e79468d
BK
3064 private:
3065 _RealType _M_n;
3066 };
3067
3068 explicit
3069 student_t_distribution(_RealType __n = _RealType(1))
f9b09dec 3070 : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
8e79468d
BK
3071 { }
3072
3073 explicit
3074 student_t_distribution(const param_type& __p)
f9b09dec 3075 : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
8e79468d
BK
3076 { }
3077
3078 /**
3079 * @brief Resets the distribution state.
3080 */
3081 void
3082 reset()
f9b09dec
PC
3083 {
3084 _M_nd.reset();
3085 _M_gd.reset();
3086 }
8e79468d
BK
3087
3088 /**
3089 *
3090 */
3091 _RealType
3092 n() const
3093 { return _M_param.n(); }
3094
3095 /**
3096 * @brief Returns the parameter set of the distribution.
3097 */
3098 param_type
3099 param() const
3100 { return _M_param; }
3101
3102 /**
3103 * @brief Sets the parameter set of the distribution.
3104 * @param __param The new parameter set of the distribution.
3105 */
3106 void
3107 param(const param_type& __param)
3108 { _M_param = __param; }
3109
3110 /**
3111 * @brief Returns the greatest lower bound value of the distribution.
3112 */
3113 result_type
3114 min() const
3115 { return std::numeric_limits<result_type>::min(); }
3116
3117 /**
3118 * @brief Returns the least upper bound value of the distribution.
3119 */
3120 result_type
3121 max() const
3122 { return std::numeric_limits<result_type>::max(); }
3123
247d8075
PC
3124 /**
3125 * @brief Generating functions.
3126 */
8e79468d
BK
3127 template<typename _UniformRandomNumberGenerator>
3128 result_type
f9b09dec
PC
3129 operator()(_UniformRandomNumberGenerator& __urng)
3130 { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
8e79468d
BK
3131
3132 template<typename _UniformRandomNumberGenerator>
3133 result_type
3134 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
3135 const param_type& __p)
3136 {
3137 typedef typename std::gamma_distribution<result_type>::param_type
3138 param_type;
3139
3140 const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
3141 return _M_nd(__urng) * std::sqrt(__p.n() / __g);
3142 }
8e79468d 3143
fc05e1ba
PC
3144 /**
3145 * @brief Return true if two Student t distributions have
3146 * the same parameters and the sequences that would
3147 * be generated are equal.
3148 */
3149 template<typename _RealType1>
3150 friend bool
3151 operator==(const std::student_t_distribution<_RealType1>& __d1,
3152 const std::student_t_distribution<_RealType1>& __d2)
3153 { return (__d1.param() == __d2.param()
3154 && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
3155
e1923769
ESR
3156 /**
3157 * @brief Inserts a %student_t_distribution random number distribution
3158 * @p __x into the output stream @p __os.
3159 *
3160 * @param __os An output stream.
3161 * @param __x A %student_t_distribution random number distribution.
3162 *
3163 * @returns The output stream with the state of @p __x inserted or in
3164 * an error state.
3165 */
3166 template<typename _RealType1, typename _CharT, typename _Traits>
3167 friend std::basic_ostream<_CharT, _Traits>&
3168 operator<<(std::basic_ostream<_CharT, _Traits>&,
3169 const std::student_t_distribution<_RealType1>&);
3170
3171 /**
3172 * @brief Extracts a %student_t_distribution random number distribution
3173 * @p __x from the input stream @p __is.
3174 *
3175 * @param __is An input stream.
3176 * @param __x A %student_t_distribution random number
3177 * generator engine.
3178 *
3179 * @returns The input stream with @p __x extracted or in an error state.
3180 */
3181 template<typename _RealType1, typename _CharT, typename _Traits>
3182 friend std::basic_istream<_CharT, _Traits>&
3183 operator>>(std::basic_istream<_CharT, _Traits>&,
3184 std::student_t_distribution<_RealType1>&);
3185
8e79468d 3186 private:
8e79468d 3187 param_type _M_param;
b01630bb 3188
f9b09dec
PC
3189 std::normal_distribution<result_type> _M_nd;
3190 std::gamma_distribution<result_type> _M_gd;
8e79468d
BK
3191 };
3192
fc05e1ba
PC
3193 /**
3194 * @brief Return true if two Student t distributions are different.
3195 */
3196 template<typename _RealType>
3197 inline bool
3198 operator!=(const std::student_t_distribution<_RealType>& __d1,
3199 const std::student_t_distribution<_RealType>& __d2)
3200 { return !(__d1 == __d2); }
3201
3202
037181bc 3203 /* @} */ // group random_distributions_normal
8e79468d
BK
3204
3205 /**
94a86be0 3206 * @addtogroup random_distributions_bernoulli Bernoulli Distributions
037181bc 3207 * @ingroup random_distributions
8e79468d
BK
3208 * @{
3209 */
3210
3211 /**
3212 * @brief A Bernoulli random number distribution.
3213 *
6cc5a790
BK
3214 * Generates a sequence of true and false values with likelihood @f$p@f$
3215 * that true will come up and @f$(1 - p)@f$ that false will appear.
8e79468d
BK
3216 */
3217 class bernoulli_distribution
3218 {
3219 public:
3220 /** The type of the range of the distribution. */
3221 typedef bool result_type;
3222 /** Parameter type. */
3223 struct param_type
3224 {
3225 typedef bernoulli_distribution distribution_type;
3226
3227 explicit
3228 param_type(double __p = 0.5)
3229 : _M_p(__p)
3230 {
3231 _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
3232 }
3233
3234 double
3235 p() const
3236 { return _M_p; }
3237
fc05e1ba
PC
3238 friend bool
3239 operator==(const param_type& __p1, const param_type& __p2)
3240 { return __p1._M_p == __p2._M_p; }
3241
8e79468d
BK
3242 private:
3243 double _M_p;
3244 };
3245
3246 public:
3247 /**
3248 * @brief Constructs a Bernoulli distribution with likelihood @p p.
3249 *
3250 * @param __p [IN] The likelihood of a true result being returned.
6cc5a790 3251 * Must be in the interval @f$[0, 1]@f$.
8e79468d
BK
3252 */
3253 explicit
3254 bernoulli_distribution(double __p = 0.5)
3255 : _M_param(__p)
3256 { }
3257
3258 explicit
3259 bernoulli_distribution(const param_type& __p)
3260 : _M_param(__p)
3261 { }
3262
3263 /**
3264 * @brief Resets the distribution state.
3265 *
3266 * Does nothing for a Bernoulli distribution.
3267 */
3268 void
3269 reset() { }
3270
3271 /**
3272 * @brief Returns the @p p parameter of the distribution.
3273 */
3274 double
3275 p() const
3276 { return _M_param.p(); }
3277
3278 /**
3279 * @brief Returns the parameter set of the distribution.
3280 */
3281 param_type
3282 param() const
3283 { return _M_param; }
3284
3285 /**
3286 * @brief Sets the parameter set of the distribution.
3287 * @param __param The new parameter set of the distribution.
3288 */
3289 void
3290 param(const param_type& __param)
3291 { _M_param = __param; }
3292
3293 /**
3294 * @brief Returns the greatest lower bound value of the distribution.
3295 */
3296 result_type
3297 min() const
3298 { return std::numeric_limits<result_type>::min(); }
3299
3300 /**
3301 * @brief Returns the least upper bound value of the distribution.
3302 */
3303 result_type
3304 max() const
3305 { return std::numeric_limits<result_type>::max(); }
3306
3307 /**
247d8075 3308 * @brief Generating functions.
8e79468d
BK
3309 */
3310 template<typename _UniformRandomNumberGenerator>
3311 result_type
3312 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 3313 { return this->operator()(__urng, this->param()); }
8e79468d
BK
3314
3315 template<typename _UniformRandomNumberGenerator>
3316 result_type
3317 operator()(_UniformRandomNumberGenerator& __urng,
3318 const param_type& __p)
3319 {
3320 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3321 __aurng(__urng);
3322 if ((__aurng() - __aurng.min())
3323 < __p.p() * (__aurng.max() - __aurng.min()))
3324 return true;
3325 return false;
3326 }
3327
3328 private:
3329 param_type _M_param;
3330 };
3331
fc05e1ba
PC
3332 /**
3333 * @brief Return true if two Bernoulli distributions have
3334 * the same parameters.
3335 */
3336 inline bool
3337 operator==(const std::bernoulli_distribution& __d1,
3338 const std::bernoulli_distribution& __d2)
3339 { return __d1.param() == __d2.param(); }
3340
3341 /**
3342 * @brief Return true if two Bernoulli distributions have
3343 * different parameters.
3344 */
3345 inline bool
3346 operator!=(const std::bernoulli_distribution& __d1,
3347 const std::bernoulli_distribution& __d2)
3348 { return !(__d1 == __d2); }
3349
8e79468d
BK
3350 /**
3351 * @brief Inserts a %bernoulli_distribution random number distribution
3352 * @p __x into the output stream @p __os.
3353 *
3354 * @param __os An output stream.
3355 * @param __x A %bernoulli_distribution random number distribution.
3356 *
3357 * @returns The output stream with the state of @p __x inserted or in
3358 * an error state.
3359 */
3360 template<typename _CharT, typename _Traits>
3361 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
3362 operator<<(std::basic_ostream<_CharT, _Traits>&,
3363 const std::bernoulli_distribution&);
8e79468d
BK
3364
3365 /**
3366 * @brief Extracts a %bernoulli_distribution random number distribution
3367 * @p __x from the input stream @p __is.
3368 *
3369 * @param __is An input stream.
3370 * @param __x A %bernoulli_distribution random number generator engine.
3371 *
3372 * @returns The input stream with @p __x extracted or in an error state.
3373 */
3374 template<typename _CharT, typename _Traits>
3375 std::basic_istream<_CharT, _Traits>&
3376 operator>>(std::basic_istream<_CharT, _Traits>& __is,
94986f6d 3377 std::bernoulli_distribution& __x)
8e79468d
BK
3378 {
3379 double __p;
3380 __is >> __p;
3381 __x.param(bernoulli_distribution::param_type(__p));
3382 return __is;
3383 }
3384
3385
3386 /**
3387 * @brief A discrete binomial random number distribution.
3388 *
3389 * The formula for the binomial probability density function is
6cc5a790
BK
3390 * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3391 * and @f$p@f$ are the parameters of the distribution.
8e79468d
BK
3392 */
3393 template<typename _IntType = int>
3394 class binomial_distribution
3395 {
77e3c516
PC
3396 static_assert(std::is_integral<_IntType>::value,
3397 "template argument not an integral type");
8e79468d
BK
3398
3399 public:
3400 /** The type of the range of the distribution. */
3401 typedef _IntType result_type;
3402 /** Parameter type. */
3403 struct param_type
3404 {
3405 typedef binomial_distribution<_IntType> distribution_type;
3406 friend class binomial_distribution<_IntType>;
3407
3408 explicit
3409 param_type(_IntType __t = _IntType(1), double __p = 0.5)
3410 : _M_t(__t), _M_p(__p)
3411 {
3412 _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
94986f6d
PC
3413 && (_M_p >= 0.0)
3414 && (_M_p <= 1.0));
8e79468d
BK
3415 _M_initialize();
3416 }
3417
3418 _IntType
3419 t() const
3420 { return _M_t; }
3421
3422 double
3423 p() const
3424 { return _M_p; }
3425
fc05e1ba
PC
3426 friend bool
3427 operator==(const param_type& __p1, const param_type& __p2)
3428 { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
3429
8e79468d
BK
3430 private:
3431 void
3432 _M_initialize();
3433
3434 _IntType _M_t;
3435 double _M_p;
3436
3437 double _M_q;
3438#if _GLIBCXX_USE_C99_MATH_TR1
3439 double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
3440 _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
3441#endif
3442 bool _M_easy;
3443 };
3444
3445 // constructors and member function
3446 explicit
3447 binomial_distribution(_IntType __t = _IntType(1),
3448 double __p = 0.5)
3449 : _M_param(__t, __p), _M_nd()
3450 { }
3451
3452 explicit
3453 binomial_distribution(const param_type& __p)
3454 : _M_param(__p), _M_nd()
3455 { }
3456
3457 /**
3458 * @brief Resets the distribution state.
3459 */
3460 void
3461 reset()
3462 { _M_nd.reset(); }
3463
3464 /**
3465 * @brief Returns the distribution @p t parameter.
3466 */
3467 _IntType
3468 t() const
3469 { return _M_param.t(); }
3470
3471 /**
3472 * @brief Returns the distribution @p p parameter.
3473 */
3474 double
3475 p() const
3476 { return _M_param.p(); }
3477
3478 /**
3479 * @brief Returns the parameter set of the distribution.
3480 */
3481 param_type
3482 param() const
3483 { return _M_param; }
3484
3485 /**
3486 * @brief Sets the parameter set of the distribution.
3487 * @param __param The new parameter set of the distribution.
3488 */
3489 void
3490 param(const param_type& __param)
3491 { _M_param = __param; }
3492
3493 /**
3494 * @brief Returns the greatest lower bound value of the distribution.
3495 */
3496 result_type
3497 min() const
3498 { return 0; }
3499
3500 /**
3501 * @brief Returns the least upper bound value of the distribution.
3502 */
3503 result_type
3504 max() const
3505 { return _M_param.t(); }
3506
247d8075
PC
3507 /**
3508 * @brief Generating functions.
3509 */
3510 template<typename _UniformRandomNumberGenerator>
3511 result_type
3512 operator()(_UniformRandomNumberGenerator& __urng)
3513 { return this->operator()(__urng, this->param()); }
3514
3515 template<typename _UniformRandomNumberGenerator>
3516 result_type
3517 operator()(_UniformRandomNumberGenerator& __urng,
3518 const param_type& __p);
3519
fc05e1ba
PC
3520 /**
3521 * @brief Return true if two binomial distributions have
3522 * the same parameters and the sequences that would
3523 * be generated are equal.
3524 */
3525 template<typename _IntType1>
3526 friend bool
3527 operator==(const std::binomial_distribution<_IntType1>& __d1,
3528 const std::binomial_distribution<_IntType1>& __d2)
3529#ifdef _GLIBCXX_USE_C99_MATH_TR1
3530 { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
3531#else
3532 { return __d1.param() == __d2.param(); }
3533#endif
3534
8e79468d
BK
3535 /**
3536 * @brief Inserts a %binomial_distribution random number distribution
3537 * @p __x into the output stream @p __os.
3538 *
3539 * @param __os An output stream.
3540 * @param __x A %binomial_distribution random number distribution.
3541 *
3542 * @returns The output stream with the state of @p __x inserted or in
3543 * an error state.
3544 */
3545 template<typename _IntType1,
3546 typename _CharT, typename _Traits>
3547 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
3548 operator<<(std::basic_ostream<_CharT, _Traits>&,
3549 const std::binomial_distribution<_IntType1>&);
8e79468d
BK
3550
3551 /**
3552 * @brief Extracts a %binomial_distribution random number distribution
3553 * @p __x from the input stream @p __is.
3554 *
3555 * @param __is An input stream.
3556 * @param __x A %binomial_distribution random number generator engine.
3557 *
3558 * @returns The input stream with @p __x extracted or in an error
3559 * state.
3560 */
3561 template<typename _IntType1,
3562 typename _CharT, typename _Traits>
3563 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
3564 operator>>(std::basic_istream<_CharT, _Traits>&,
3565 std::binomial_distribution<_IntType1>&);
8e79468d
BK
3566
3567 private:
3568 template<typename _UniformRandomNumberGenerator>
3569 result_type
3570 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
3571
3572 param_type _M_param;
3573
3574 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
f9b09dec 3575 std::normal_distribution<double> _M_nd;
8e79468d
BK
3576 };
3577
fc05e1ba
PC
3578 /**
3579 * @brief Return true if two binomial distributions are different.
3580 */
3581 template<typename _IntType>
3582 inline bool
3583 operator!=(const std::binomial_distribution<_IntType>& __d1,
3584 const std::binomial_distribution<_IntType>& __d2)
3585 { return !(__d1 == __d2); }
3586
8e79468d
BK
3587
3588 /**
3589 * @brief A discrete geometric random number distribution.
3590 *
3591 * The formula for the geometric probability density function is
6cc5a790 3592 * @f$p(i|p) = (1 - p)p^{i-1}@f$ where @f$p@f$ is the parameter of the
8e79468d
BK
3593 * distribution.
3594 */
3595 template<typename _IntType = int>
3596 class geometric_distribution
3597 {
77e3c516
PC
3598 static_assert(std::is_integral<_IntType>::value,
3599 "template argument not an integral type");
8e79468d
BK
3600
3601 public:
3602 /** The type of the range of the distribution. */
3603 typedef _IntType result_type;
3604 /** Parameter type. */
3605 struct param_type
3606 {
3607 typedef geometric_distribution<_IntType> distribution_type;
3608 friend class geometric_distribution<_IntType>;
3609
3610 explicit
3611 param_type(double __p = 0.5)
3612 : _M_p(__p)
3613 {
3614 _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0)
3615 && (_M_p <= 1.0));
3616 _M_initialize();
3617 }
3618
3619 double
3620 p() const
3621 { return _M_p; }
3622
fc05e1ba
PC
3623 friend bool
3624 operator==(const param_type& __p1, const param_type& __p2)
3625 { return __p1._M_p == __p2._M_p; }
3626
8e79468d
BK
3627 private:
3628 void
3629 _M_initialize()
3630 { _M_log_p = std::log(_M_p); }
3631
3632 double _M_p;
3633
3634 double _M_log_p;
3635 };
3636
3637 // constructors and member function
3638 explicit
3639 geometric_distribution(double __p = 0.5)
3640 : _M_param(__p)
3641 { }
3642
3643 explicit
3644 geometric_distribution(const param_type& __p)
3645 : _M_param(__p)
3646 { }
3647
3648 /**
3649 * @brief Resets the distribution state.
3650 *
3651 * Does nothing for the geometric distribution.
3652 */
3653 void
3654 reset() { }
3655
3656 /**
3657 * @brief Returns the distribution parameter @p p.
3658 */
3659 double
3660 p() const
3661 { return _M_param.p(); }
3662
3663 /**
3664 * @brief Returns the parameter set of the distribution.
3665 */
3666 param_type
3667 param() const
3668 { return _M_param; }
3669
3670 /**
3671 * @brief Sets the parameter set of the distribution.
3672 * @param __param The new parameter set of the distribution.
3673 */
3674 void
3675 param(const param_type& __param)
3676 { _M_param = __param; }
3677
3678 /**
3679 * @brief Returns the greatest lower bound value of the distribution.
3680 */
3681 result_type
3682 min() const
3683 { return 0; }
3684
3685 /**
3686 * @brief Returns the least upper bound value of the distribution.
3687 */
3688 result_type
3689 max() const
3690 { return std::numeric_limits<result_type>::max(); }
3691
247d8075
PC
3692 /**
3693 * @brief Generating functions.
3694 */
8e79468d
BK
3695 template<typename _UniformRandomNumberGenerator>
3696 result_type
3697 operator()(_UniformRandomNumberGenerator& __urng)
3698 { return this->operator()(__urng, this->param()); }
3699
3700 template<typename _UniformRandomNumberGenerator>
3701 result_type
3702 operator()(_UniformRandomNumberGenerator& __urng,
3703 const param_type& __p);
3704
3705 private:
3706 param_type _M_param;
3707 };
3708
fc05e1ba
PC
3709 /**
3710 * @brief Return true if two geometric distributions have
3711 * the same parameters.
3712 */
3713 template<typename _IntType>
3714 inline bool
3715 operator==(const std::geometric_distribution<_IntType>& __d1,
3716 const std::geometric_distribution<_IntType>& __d2)
3717 { return __d1.param() == __d2.param(); }
3718
3719 /**
3720 * @brief Return true if two geometric distributions have
3721 * different parameters.
3722 */
3723 template<typename _IntType>
3724 inline bool
3725 operator!=(const std::geometric_distribution<_IntType>& __d1,
3726 const std::geometric_distribution<_IntType>& __d2)
3727 { return !(__d1 == __d2); }
3728
8e79468d
BK
3729 /**
3730 * @brief Inserts a %geometric_distribution random number distribution
3731 * @p __x into the output stream @p __os.
3732 *
3733 * @param __os An output stream.
3734 * @param __x A %geometric_distribution random number distribution.
3735 *
3736 * @returns The output stream with the state of @p __x inserted or in
3737 * an error state.
3738 */
3739 template<typename _IntType,
3740 typename _CharT, typename _Traits>
3741 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
3742 operator<<(std::basic_ostream<_CharT, _Traits>&,
3743 const std::geometric_distribution<_IntType>&);
8e79468d
BK
3744
3745 /**
3746 * @brief Extracts a %geometric_distribution random number distribution
3747 * @p __x from the input stream @p __is.
3748 *
3749 * @param __is An input stream.
3750 * @param __x A %geometric_distribution random number generator engine.
3751 *
3752 * @returns The input stream with @p __x extracted or in an error state.
3753 */
3754 template<typename _IntType,
3755 typename _CharT, typename _Traits>
3756 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
3757 operator>>(std::basic_istream<_CharT, _Traits>&,
3758 std::geometric_distribution<_IntType>&);
8e79468d
BK
3759
3760
3761 /**
3762 * @brief A negative_binomial_distribution random number distribution.
3763 *
3764 * The formula for the negative binomial probability mass function is
6cc5a790
BK
3765 * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3766 * and @f$p@f$ are the parameters of the distribution.
8e79468d
BK
3767 */
3768 template<typename _IntType = int>
3769 class negative_binomial_distribution
3770 {
77e3c516
PC
3771 static_assert(std::is_integral<_IntType>::value,
3772 "template argument not an integral type");
8e79468d
BK
3773
3774 public:
3775 /** The type of the range of the distribution. */
3776 typedef _IntType result_type;
3777 /** Parameter type. */
3778 struct param_type
3779 {
3780 typedef negative_binomial_distribution<_IntType> distribution_type;
3781
3782 explicit
3783 param_type(_IntType __k = 1, double __p = 0.5)
3784 : _M_k(__k), _M_p(__p)
3785 { }
3786
3787 _IntType
3788 k() const
3789 { return _M_k; }
3790
3791 double
3792 p() const
3793 { return _M_p; }
3794
fc05e1ba
PC
3795 friend bool
3796 operator==(const param_type& __p1, const param_type& __p2)
3797 { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
3798
8e79468d
BK
3799 private:
3800 _IntType _M_k;
3801 double _M_p;
3802 };
3803
3804 explicit
3805 negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
f9b09dec 3806 : _M_param(__k, __p), _M_gd(__k, __p / (1.0 - __p))
8e79468d
BK
3807 { }
3808
3809 explicit
3810 negative_binomial_distribution(const param_type& __p)
f9b09dec 3811 : _M_param(__p), _M_gd(__p.k(), __p.p() / (1.0 - __p.p()))
8e79468d
BK
3812 { }
3813
3814 /**
3815 * @brief Resets the distribution state.
3816 */
3817 void
3818 reset()
f9b09dec 3819 { _M_gd.reset(); }
8e79468d
BK
3820
3821 /**
6cc5a790 3822 * @brief Return the @f$k@f$ parameter of the distribution.
8e79468d
BK
3823 */
3824 _IntType
3825 k() const
3826 { return _M_param.k(); }
3827
3828 /**
6cc5a790 3829 * @brief Return the @f$p@f$ parameter of the distribution.
8e79468d
BK
3830 */
3831 double
3832 p() const
3833 { return _M_param.p(); }
3834
3835 /**
3836 * @brief Returns the parameter set of the distribution.
3837 */
3838 param_type
3839 param() const
3840 { return _M_param; }
3841
3842 /**
3843 * @brief Sets the parameter set of the distribution.
3844 * @param __param The new parameter set of the distribution.
3845 */
3846 void
3847 param(const param_type& __param)
3848 { _M_param = __param; }
3849
3850 /**
3851 * @brief Returns the greatest lower bound value of the distribution.
3852 */
3853 result_type
3854 min() const
3855 { return result_type(0); }
3856
3857 /**
3858 * @brief Returns the least upper bound value of the distribution.
3859 */
3860 result_type
3861 max() const
3862 { return std::numeric_limits<result_type>::max(); }
3863
247d8075
PC
3864 /**
3865 * @brief Generating functions.
3866 */
8e79468d
BK
3867 template<typename _UniformRandomNumberGenerator>
3868 result_type
f9b09dec 3869 operator()(_UniformRandomNumberGenerator& __urng);
8e79468d
BK
3870
3871 template<typename _UniformRandomNumberGenerator>
3872 result_type
3873 operator()(_UniformRandomNumberGenerator& __urng,
3874 const param_type& __p);
3875
fc05e1ba
PC
3876 /**
3877 * @brief Return true if two negative binomial distributions have
3878 * the same parameters and the sequences that would be
3879 * generated are equal.
3880 */
3881 template<typename _IntType1>
3882 friend bool
3883 operator==(const std::negative_binomial_distribution<_IntType1>& __d1,
3884 const std::negative_binomial_distribution<_IntType1>& __d2)
3885 { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
3886
e1923769
ESR
3887 /**
3888 * @brief Inserts a %negative_binomial_distribution random
3889 * number distribution @p __x into the output stream @p __os.
3890 *
3891 * @param __os An output stream.
3892 * @param __x A %negative_binomial_distribution random number
3893 * distribution.
3894 *
3895 * @returns The output stream with the state of @p __x inserted or in
3896 * an error state.
3897 */
3898 template<typename _IntType1, typename _CharT, typename _Traits>
3899 friend std::basic_ostream<_CharT, _Traits>&
3900 operator<<(std::basic_ostream<_CharT, _Traits>&,
3901 const std::negative_binomial_distribution<_IntType1>&);
3902
3903 /**
3904 * @brief Extracts a %negative_binomial_distribution random number
3905 * distribution @p __x from the input stream @p __is.
3906 *
3907 * @param __is An input stream.
3908 * @param __x A %negative_binomial_distribution random number
3909 * generator engine.
3910 *
3911 * @returns The input stream with @p __x extracted or in an error state.
3912 */
3913 template<typename _IntType1, typename _CharT, typename _Traits>
3914 friend std::basic_istream<_CharT, _Traits>&
3915 operator>>(std::basic_istream<_CharT, _Traits>&,
3916 std::negative_binomial_distribution<_IntType1>&);
3917
8e79468d
BK
3918 private:
3919 param_type _M_param;
f9b09dec
PC
3920
3921 std::gamma_distribution<double> _M_gd;
8e79468d
BK
3922 };
3923
fc05e1ba
PC
3924 /**
3925 * @brief Return true if two negative binomial distributions are different.
3926 */
3927 template<typename _IntType>
3928 inline bool
3929 operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
3930 const std::negative_binomial_distribution<_IntType>& __d2)
3931 { return !(__d1 == __d2); }
3932
3933
037181bc 3934 /* @} */ // group random_distributions_bernoulli
8e79468d
BK
3935
3936 /**
94a86be0 3937 * @addtogroup random_distributions_poisson Poisson Distributions
037181bc 3938 * @ingroup random_distributions
8e79468d
BK
3939 * @{
3940 */
3941
3942 /**
3943 * @brief A discrete Poisson random number distribution.
3944 *
3945 * The formula for the Poisson probability density function is
6cc5a790 3946 * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
8e79468d
BK
3947 * parameter of the distribution.
3948 */
3949 template<typename _IntType = int>
3950 class poisson_distribution
3951 {
77e3c516
PC
3952 static_assert(std::is_integral<_IntType>::value,
3953 "template argument not an integral type");
8e79468d
BK
3954
3955 public:
3956 /** The type of the range of the distribution. */
3957 typedef _IntType result_type;
3958 /** Parameter type. */
3959 struct param_type
3960 {
3961 typedef poisson_distribution<_IntType> distribution_type;
3962 friend class poisson_distribution<_IntType>;
3963
3964 explicit
3965 param_type(double __mean = 1.0)
3966 : _M_mean(__mean)
3967 {
3968 _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
3969 _M_initialize();
3970 }
3971
3972 double
3973 mean() const
3974 { return _M_mean; }
3975
fc05e1ba
PC
3976 friend bool
3977 operator==(const param_type& __p1, const param_type& __p2)
3978 { return __p1._M_mean == __p2._M_mean; }
3979
8e79468d
BK
3980 private:
3981 // Hosts either log(mean) or the threshold of the simple method.
3982 void
3983 _M_initialize();
3984
3985 double _M_mean;
3986
3987 double _M_lm_thr;
3988#if _GLIBCXX_USE_C99_MATH_TR1
3989 double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
3990#endif
3991 };
3992
3993 // constructors and member function
3994 explicit
3995 poisson_distribution(double __mean = 1.0)
3996 : _M_param(__mean), _M_nd()
3997 { }
3998
3999 explicit
4000 poisson_distribution(const param_type& __p)
4001 : _M_param(__p), _M_nd()
4002 { }
4003
4004 /**
4005 * @brief Resets the distribution state.
4006 */
4007 void
4008 reset()
4009 { _M_nd.reset(); }
4010
4011 /**
4012 * @brief Returns the distribution parameter @p mean.
4013 */
4014 double
4015 mean() const
4016 { return _M_param.mean(); }
4017
4018 /**
4019 * @brief Returns the parameter set of the distribution.
4020 */
4021 param_type
4022 param() const
4023 { return _M_param; }
4024
4025 /**
4026 * @brief Sets the parameter set of the distribution.
4027 * @param __param The new parameter set of the distribution.
4028 */
4029 void
4030 param(const param_type& __param)
4031 { _M_param = __param; }
4032
4033 /**
4034 * @brief Returns the greatest lower bound value of the distribution.
4035 */
4036 result_type
4037 min() const
4038 { return 0; }
4039
4040 /**
4041 * @brief Returns the least upper bound value of the distribution.
4042 */
4043 result_type
4044 max() const
4045 { return std::numeric_limits<result_type>::max(); }
4046
247d8075
PC
4047 /**
4048 * @brief Generating functions.
4049 */
8e79468d
BK
4050 template<typename _UniformRandomNumberGenerator>
4051 result_type
4052 operator()(_UniformRandomNumberGenerator& __urng)
4053 { return this->operator()(__urng, this->param()); }
4054
4055 template<typename _UniformRandomNumberGenerator>
4056 result_type
4057 operator()(_UniformRandomNumberGenerator& __urng,
4058 const param_type& __p);
4059
fc05e1ba
PC
4060 /**
4061 * @brief Return true if two Poisson distributions have the same
4062 * parameters and the sequences that would be generated
4063 * are equal.
4064 */
4065 template<typename _IntType1>
4066 friend bool
4067 operator==(const std::poisson_distribution<_IntType1>& __d1,
4068 const std::poisson_distribution<_IntType1>& __d2)
4069#ifdef _GLIBCXX_USE_C99_MATH_TR1
4070 { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
4071#else
4072 { return __d1.param() == __d2.param(); }
4073#endif
4074
8e79468d
BK
4075 /**
4076 * @brief Inserts a %poisson_distribution random number distribution
4077 * @p __x into the output stream @p __os.
4078 *
4079 * @param __os An output stream.
4080 * @param __x A %poisson_distribution random number distribution.
4081 *
4082 * @returns The output stream with the state of @p __x inserted or in
4083 * an error state.
4084 */
4085 template<typename _IntType1, typename _CharT, typename _Traits>
4086 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
4087 operator<<(std::basic_ostream<_CharT, _Traits>&,
4088 const std::poisson_distribution<_IntType1>&);
8e79468d
BK
4089
4090 /**
4091 * @brief Extracts a %poisson_distribution random number distribution
4092 * @p __x from the input stream @p __is.
4093 *
4094 * @param __is An input stream.
4095 * @param __x A %poisson_distribution random number generator engine.
4096 *
4097 * @returns The input stream with @p __x extracted or in an error
4098 * state.
4099 */
4100 template<typename _IntType1, typename _CharT, typename _Traits>
4101 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
4102 operator>>(std::basic_istream<_CharT, _Traits>&,
4103 std::poisson_distribution<_IntType1>&);
8e79468d
BK
4104
4105 private:
4106 param_type _M_param;
4107
4108 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
f9b09dec 4109 std::normal_distribution<double> _M_nd;
8e79468d
BK
4110 };
4111
fc05e1ba
PC
4112 /**
4113 * @brief Return true if two Poisson distributions are different.
4114 */
4115 template<typename _IntType>
4116 inline bool
4117 operator!=(const std::poisson_distribution<_IntType>& __d1,
4118 const std::poisson_distribution<_IntType>& __d2)
4119 { return !(__d1 == __d2); }
4120
4121
8e79468d
BK
4122 /**
4123 * @brief An exponential continuous distribution for random numbers.
4124 *
4125 * The formula for the exponential probability density function is
6cc5a790 4126 * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
8e79468d
BK
4127 *
4128 * <table border=1 cellpadding=10 cellspacing=0>
4129 * <caption align=top>Distribution Statistics</caption>
6cc5a790
BK
4130 * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4131 * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
4132 * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
8e79468d 4133 * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
6cc5a790 4134 * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
8e79468d
BK
4135 * </table>
4136 */
4137 template<typename _RealType = double>
4138 class exponential_distribution
4139 {
77e3c516
PC
4140 static_assert(std::is_floating_point<_RealType>::value,
4141 "template argument not a floating point type");
4142
8e79468d
BK
4143 public:
4144 /** The type of the range of the distribution. */
4145 typedef _RealType result_type;
4146 /** Parameter type. */
4147 struct param_type
4148 {
4149 typedef exponential_distribution<_RealType> distribution_type;
4150
4151 explicit
4152 param_type(_RealType __lambda = _RealType(1))
4153 : _M_lambda(__lambda)
4154 {
4155 _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
4156 }
4157
4158 _RealType
4159 lambda() const
4160 { return _M_lambda; }
4161
fc05e1ba
PC
4162 friend bool
4163 operator==(const param_type& __p1, const param_type& __p2)
4164 { return __p1._M_lambda == __p2._M_lambda; }
4165
8e79468d
BK
4166 private:
4167 _RealType _M_lambda;
4168 };
4169
4170 public:
4171 /**
4172 * @brief Constructs an exponential distribution with inverse scale
6cc5a790 4173 * parameter @f$\lambda@f$.
8e79468d
BK
4174 */
4175 explicit
4176 exponential_distribution(const result_type& __lambda = result_type(1))
4177 : _M_param(__lambda)
4178 { }
4179
4180 explicit
4181 exponential_distribution(const param_type& __p)
4182 : _M_param(__p)
4183 { }
4184
4185 /**
4186 * @brief Resets the distribution state.
4187 *
4188 * Has no effect on exponential distributions.
4189 */
4190 void
4191 reset() { }
4192
4193 /**
4194 * @brief Returns the inverse scale parameter of the distribution.
4195 */
4196 _RealType
4197 lambda() const
4198 { return _M_param.lambda(); }
4199
4200 /**
4201 * @brief Returns the parameter set of the distribution.
4202 */
4203 param_type
4204 param() const
4205 { return _M_param; }
4206
4207 /**
4208 * @brief Sets the parameter set of the distribution.
4209 * @param __param The new parameter set of the distribution.
4210 */
4211 void
4212 param(const param_type& __param)
4213 { _M_param = __param; }
4214
4215 /**
4216 * @brief Returns the greatest lower bound value of the distribution.
4217 */
4218 result_type
4219 min() const
4220 { return result_type(0); }
4221
4222 /**
4223 * @brief Returns the least upper bound value of the distribution.
4224 */
4225 result_type
4226 max() const
4227 { return std::numeric_limits<result_type>::max(); }
4228
247d8075
PC
4229 /**
4230 * @brief Generating functions.
4231 */
8e79468d
BK
4232 template<typename _UniformRandomNumberGenerator>
4233 result_type
4234 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 4235 { return this->operator()(__urng, this->param()); }
8e79468d
BK
4236
4237 template<typename _UniformRandomNumberGenerator>
4238 result_type
4239 operator()(_UniformRandomNumberGenerator& __urng,
4240 const param_type& __p)
4241 {
4242 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
4243 __aurng(__urng);
4244 return -std::log(__aurng()) / __p.lambda();
4245 }
4246
4247 private:
4248 param_type _M_param;
4249 };
4250
fc05e1ba
PC
4251 /**
4252 * @brief Return true if two exponential distributions have the same
4253 * parameters.
4254 */
4255 template<typename _RealType>
4256 inline bool
4257 operator==(const std::exponential_distribution<_RealType>& __d1,
4258 const std::exponential_distribution<_RealType>& __d2)
4259 { return __d1.param() == __d2.param(); }
4260
4261 /**
4262 * @brief Return true if two exponential distributions have different
4263 * parameters.
4264 */
4265 template<typename _RealType>
4266 inline bool
4267 operator!=(const std::exponential_distribution<_RealType>& __d1,
4268 const std::exponential_distribution<_RealType>& __d2)
4269 { return !(__d1 == __d2); }
4270
8e79468d
BK
4271 /**
4272 * @brief Inserts a %exponential_distribution random number distribution
4273 * @p __x into the output stream @p __os.
4274 *
4275 * @param __os An output stream.
4276 * @param __x A %exponential_distribution random number distribution.
4277 *
4278 * @returns The output stream with the state of @p __x inserted or in
4279 * an error state.
4280 */
4281 template<typename _RealType, typename _CharT, typename _Traits>
4282 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
4283 operator<<(std::basic_ostream<_CharT, _Traits>&,
4284 const std::exponential_distribution<_RealType>&);
8e79468d
BK
4285
4286 /**
4287 * @brief Extracts a %exponential_distribution random number distribution
4288 * @p __x from the input stream @p __is.
4289 *
4290 * @param __is An input stream.
4291 * @param __x A %exponential_distribution random number
4292 * generator engine.
4293 *
4294 * @returns The input stream with @p __x extracted or in an error state.
4295 */
4296 template<typename _RealType, typename _CharT, typename _Traits>
4297 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
4298 operator>>(std::basic_istream<_CharT, _Traits>&,
4299 std::exponential_distribution<_RealType>&);
8e79468d
BK
4300
4301
8e79468d
BK
4302 /**
4303 * @brief A weibull_distribution random number distribution.
4304 *
6cc5a790
BK
4305 * The formula for the normal probability density function is:
4306 * @f[
4307 * p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
4308 * \exp{(-(\frac{x}{\beta})^\alpha)}
4309 * @f]
8e79468d
BK
4310 */
4311 template<typename _RealType = double>
4312 class weibull_distribution
4313 {
77e3c516
PC
4314 static_assert(std::is_floating_point<_RealType>::value,
4315 "template argument not a floating point type");
4316
8e79468d
BK
4317 public:
4318 /** The type of the range of the distribution. */
4319 typedef _RealType result_type;
4320 /** Parameter type. */
4321 struct param_type
4322 {
4323 typedef weibull_distribution<_RealType> distribution_type;
4324
4325 explicit
4326 param_type(_RealType __a = _RealType(1),
4327 _RealType __b = _RealType(1))
4328 : _M_a(__a), _M_b(__b)
4329 { }
4330
4331 _RealType
4332 a() const
4333 { return _M_a; }
4334
4335 _RealType
4336 b() const
4337 { return _M_b; }
4338
fc05e1ba
PC
4339 friend bool
4340 operator==(const param_type& __p1, const param_type& __p2)
4341 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4342
8e79468d
BK
4343 private:
4344 _RealType _M_a;
4345 _RealType _M_b;
4346 };
4347
4348 explicit
4349 weibull_distribution(_RealType __a = _RealType(1),
4350 _RealType __b = _RealType(1))
4351 : _M_param(__a, __b)
4352 { }
4353
4354 explicit
4355 weibull_distribution(const param_type& __p)
4356 : _M_param(__p)
4357 { }
4358
4359 /**
4360 * @brief Resets the distribution state.
4361 */
4362 void
4363 reset()
4364 { }
4365
4366 /**
6cc5a790 4367 * @brief Return the @f$a@f$ parameter of the distribution.
8e79468d
BK
4368 */
4369 _RealType
4370 a() const
4371 { return _M_param.a(); }
4372
4373 /**
6cc5a790 4374 * @brief Return the @f$b@f$ parameter of the distribution.
8e79468d
BK
4375 */
4376 _RealType
4377 b() const
4378 { return _M_param.b(); }
4379
4380 /**
4381 * @brief Returns the parameter set of the distribution.
4382 */
4383 param_type
4384 param() const
4385 { return _M_param; }
4386
4387 /**
4388 * @brief Sets the parameter set of the distribution.
4389 * @param __param The new parameter set of the distribution.
4390 */
4391 void
4392 param(const param_type& __param)
4393 { _M_param = __param; }
4394
4395 /**
4396 * @brief Returns the greatest lower bound value of the distribution.
4397 */
4398 result_type
4399 min() const
4400 { return result_type(0); }
4401
4402 /**
4403 * @brief Returns the least upper bound value of the distribution.
4404 */
4405 result_type
4406 max() const
4407 { return std::numeric_limits<result_type>::max(); }
4408
247d8075
PC
4409 /**
4410 * @brief Generating functions.
4411 */
8e79468d
BK
4412 template<typename _UniformRandomNumberGenerator>
4413 result_type
4414 operator()(_UniformRandomNumberGenerator& __urng)
4415 { return this->operator()(__urng, this->param()); }
4416
4417 template<typename _UniformRandomNumberGenerator>
4418 result_type
4419 operator()(_UniformRandomNumberGenerator& __urng,
b01630bb 4420 const param_type& __p);
8e79468d
BK
4421
4422 private:
4423 param_type _M_param;
4424 };
4425
fc05e1ba
PC
4426 /**
4427 * @brief Return true if two Weibull distributions have the same
4428 * parameters.
4429 */
4430 template<typename _RealType>
4431 inline bool
4432 operator==(const std::weibull_distribution<_RealType>& __d1,
4433 const std::weibull_distribution<_RealType>& __d2)
4434 { return __d1.param() == __d2.param(); }
4435
4436 /**
4437 * @brief Return true if two Weibull distributions have different
4438 * parameters.
4439 */
4440 template<typename _RealType>
4441 inline bool
4442 operator!=(const std::weibull_distribution<_RealType>& __d1,
4443 const std::weibull_distribution<_RealType>& __d2)
4444 { return !(__d1 == __d2); }
4445
8e79468d
BK
4446 /**
4447 * @brief Inserts a %weibull_distribution random number distribution
4448 * @p __x into the output stream @p __os.
4449 *
4450 * @param __os An output stream.
4451 * @param __x A %weibull_distribution random number distribution.
4452 *
4453 * @returns The output stream with the state of @p __x inserted or in
4454 * an error state.
4455 */
4456 template<typename _RealType, typename _CharT, typename _Traits>
4457 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
4458 operator<<(std::basic_ostream<_CharT, _Traits>&,
4459 const std::weibull_distribution<_RealType>&);
8e79468d
BK
4460
4461 /**
4462 * @brief Extracts a %weibull_distribution random number distribution
4463 * @p __x from the input stream @p __is.
4464 *
4465 * @param __is An input stream.
4466 * @param __x A %weibull_distribution random number
4467 * generator engine.
4468 *
4469 * @returns The input stream with @p __x extracted or in an error state.
4470 */
4471 template<typename _RealType, typename _CharT, typename _Traits>
4472 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
4473 operator>>(std::basic_istream<_CharT, _Traits>&,
4474 std::weibull_distribution<_RealType>&);
8e79468d
BK
4475
4476
4477 /**
4478 * @brief A extreme_value_distribution random number distribution.
4479 *
4480 * The formula for the normal probability mass function is
6cc5a790
BK
4481 * @f[
4482 * p(x|a,b) = \frac{1}{b}
4483 * \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b}))
4484 * @f]
8e79468d
BK
4485 */
4486 template<typename _RealType = double>
4487 class extreme_value_distribution
4488 {
77e3c516
PC
4489 static_assert(std::is_floating_point<_RealType>::value,
4490 "template argument not a floating point type");
4491
8e79468d
BK
4492 public:
4493 /** The type of the range of the distribution. */
4494 typedef _RealType result_type;
4495 /** Parameter type. */
4496 struct param_type
4497 {
4498 typedef extreme_value_distribution<_RealType> distribution_type;
4499
4500 explicit
4501 param_type(_RealType __a = _RealType(0),
4502 _RealType __b = _RealType(1))
4503 : _M_a(__a), _M_b(__b)
4504 { }
4505
4506 _RealType
4507 a() const
4508 { return _M_a; }
4509
4510 _RealType
4511 b() const
4512 { return _M_b; }
4513
fc05e1ba
PC
4514 friend bool
4515 operator==(const param_type& __p1, const param_type& __p2)
4516 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4517
8e79468d
BK
4518 private:
4519 _RealType _M_a;
4520 _RealType _M_b;
4521 };
4522
4523 explicit
4524 extreme_value_distribution(_RealType __a = _RealType(0),
4525 _RealType __b = _RealType(1))
4526 : _M_param(__a, __b)
4527 { }
4528
4529 explicit
4530 extreme_value_distribution(const param_type& __p)
4531 : _M_param(__p)
4532 { }
4533
4534 /**
4535 * @brief Resets the distribution state.
4536 */
4537 void
4538 reset()
4539 { }
4540
4541 /**
6cc5a790 4542 * @brief Return the @f$a@f$ parameter of the distribution.
8e79468d
BK
4543 */
4544 _RealType
4545 a() const
4546 { return _M_param.a(); }
4547
4548 /**
6cc5a790 4549 * @brief Return the @f$b@f$ parameter of the distribution.
8e79468d
BK
4550 */
4551 _RealType
4552 b() const
4553 { return _M_param.b(); }
4554
4555 /**
4556 * @brief Returns the parameter set of the distribution.
4557 */
4558 param_type
4559 param() const
4560 { return _M_param; }
4561
4562 /**
4563 * @brief Sets the parameter set of the distribution.
4564 * @param __param The new parameter set of the distribution.
4565 */
4566 void
4567 param(const param_type& __param)
4568 { _M_param = __param; }
4569
4570 /**
4571 * @brief Returns the greatest lower bound value of the distribution.
4572 */
4573 result_type
4574 min() const
4575 { return std::numeric_limits<result_type>::min(); }
4576
4577 /**
4578 * @brief Returns the least upper bound value of the distribution.
4579 */
4580 result_type
4581 max() const
4582 { return std::numeric_limits<result_type>::max(); }
4583
247d8075
PC
4584 /**
4585 * @brief Generating functions.
4586 */
8e79468d
BK
4587 template<typename _UniformRandomNumberGenerator>
4588 result_type
4589 operator()(_UniformRandomNumberGenerator& __urng)
4590 { return this->operator()(__urng, this->param()); }
4591
4592 template<typename _UniformRandomNumberGenerator>
4593 result_type
4594 operator()(_UniformRandomNumberGenerator& __urng,
4595 const param_type& __p);
4596
4597 private:
4598 param_type _M_param;
4599 };
4600
fc05e1ba
PC
4601 /**
4602 * @brief Return true if two extreme value distributions have the same
4603 * parameters.
4604 */
4605 template<typename _RealType>
4606 inline bool
4607 operator==(const std::extreme_value_distribution<_RealType>& __d1,
4608 const std::extreme_value_distribution<_RealType>& __d2)
4609 { return __d1.param() == __d2.param(); }
4610
4611 /**
4612 * @brief Return true if two extreme value distributions have different
4613 * parameters.
4614 */
4615 template<typename _RealType>
4616 inline bool
4617 operator!=(const std::extreme_value_distribution<_RealType>& __d1,
4618 const std::extreme_value_distribution<_RealType>& __d2)
4619 { return !(__d1 == __d2); }
4620
8e79468d
BK
4621 /**
4622 * @brief Inserts a %extreme_value_distribution random number distribution
4623 * @p __x into the output stream @p __os.
4624 *
4625 * @param __os An output stream.
4626 * @param __x A %extreme_value_distribution random number distribution.
4627 *
4628 * @returns The output stream with the state of @p __x inserted or in
4629 * an error state.
4630 */
4631 template<typename _RealType, typename _CharT, typename _Traits>
4632 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
4633 operator<<(std::basic_ostream<_CharT, _Traits>&,
4634 const std::extreme_value_distribution<_RealType>&);
8e79468d
BK
4635
4636 /**
4637 * @brief Extracts a %extreme_value_distribution random number
4638 * distribution @p __x from the input stream @p __is.
4639 *
4640 * @param __is An input stream.
4641 * @param __x A %extreme_value_distribution random number
4642 * generator engine.
4643 *
4644 * @returns The input stream with @p __x extracted or in an error state.
4645 */
4646 template<typename _RealType, typename _CharT, typename _Traits>
4647 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
4648 operator>>(std::basic_istream<_CharT, _Traits>&,
4649 std::extreme_value_distribution<_RealType>&);
8e79468d
BK
4650
4651
4652 /**
4653 * @brief A discrete_distribution random number distribution.
4654 *
4655 * The formula for the discrete probability mass function is
4656 *
4657 */
4658 template<typename _IntType = int>
4659 class discrete_distribution
4660 {
77e3c516
PC
4661 static_assert(std::is_integral<_IntType>::value,
4662 "template argument not an integral type");
8e79468d
BK
4663
4664 public:
4665 /** The type of the range of the distribution. */
4666 typedef _IntType result_type;
4667 /** Parameter type. */
4668 struct param_type
4669 {
4670 typedef discrete_distribution<_IntType> distribution_type;
4671 friend class discrete_distribution<_IntType>;
4672
4673 param_type()
879b9073 4674 : _M_prob(), _M_cp()
ce9555cb 4675 { }
8e79468d
BK
4676
4677 template<typename _InputIterator>
4678 param_type(_InputIterator __wbegin,
4679 _InputIterator __wend)
4680 : _M_prob(__wbegin, __wend), _M_cp()
4681 { _M_initialize(); }
4682
4683 param_type(initializer_list<double> __wil)
4684 : _M_prob(__wil.begin(), __wil.end()), _M_cp()
4685 { _M_initialize(); }
4686
4687 template<typename _Func>
4688 param_type(size_t __nw, double __xmin, double __xmax,
4689 _Func __fw);
4690
ce9555cb
PC
4691 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
4692 param_type(const param_type&) = default;
4693 param_type& operator=(const param_type&) = default;
4694
8e79468d
BK
4695 std::vector<double>
4696 probabilities() const
879b9073 4697 { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
8e79468d 4698
fc05e1ba
PC
4699 friend bool
4700 operator==(const param_type& __p1, const param_type& __p2)
4701 { return __p1._M_prob == __p2._M_prob; }
4702
8e79468d
BK
4703 private:
4704 void
4705 _M_initialize();
4706
4707 std::vector<double> _M_prob;
4708 std::vector<double> _M_cp;
4709 };
4710
4711 discrete_distribution()
4712 : _M_param()
4713 { }
4714
4715 template<typename _InputIterator>
4716 discrete_distribution(_InputIterator __wbegin,
4717 _InputIterator __wend)
4718 : _M_param(__wbegin, __wend)
4719 { }
4720
f8dd9e0d
PC
4721 discrete_distribution(initializer_list<double> __wl)
4722 : _M_param(__wl)
8e79468d
BK
4723 { }
4724
4725 template<typename _Func>
4726 discrete_distribution(size_t __nw, double __xmin, double __xmax,
4727 _Func __fw)
4728 : _M_param(__nw, __xmin, __xmax, __fw)
4729 { }
4730
4731 explicit
4732 discrete_distribution(const param_type& __p)
4733 : _M_param(__p)
4734 { }
4735
4736 /**
4737 * @brief Resets the distribution state.
4738 */
4739 void
4740 reset()
4741 { }
4742
4743 /**
4744 * @brief Returns the probabilities of the distribution.
4745 */
4746 std::vector<double>
4747 probabilities() const
879b9073
PC
4748 {
4749 return _M_param._M_prob.empty()
4750 ? std::vector<double>(1, 1.0) : _M_param._M_prob;
4751 }
8e79468d
BK
4752
4753 /**
4754 * @brief Returns the parameter set of the distribution.
4755 */
4756 param_type
4757 param() const
4758 { return _M_param; }
4759
4760 /**
4761 * @brief Sets the parameter set of the distribution.
4762 * @param __param The new parameter set of the distribution.
4763 */
4764 void
4765 param(const param_type& __param)
4766 { _M_param = __param; }
4767
4768 /**
4769 * @brief Returns the greatest lower bound value of the distribution.
4770 */
4771 result_type
4772 min() const
4773 { return result_type(0); }
4774
4775 /**
4776 * @brief Returns the least upper bound value of the distribution.
4777 */
4778 result_type
4779 max() const
879b9073
PC
4780 {
4781 return _M_param._M_prob.empty()
4782 ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
4783 }
8e79468d 4784
247d8075
PC
4785 /**
4786 * @brief Generating functions.
4787 */
8e79468d
BK
4788 template<typename _UniformRandomNumberGenerator>
4789 result_type
4790 operator()(_UniformRandomNumberGenerator& __urng)
4791 { return this->operator()(__urng, this->param()); }
4792
4793 template<typename _UniformRandomNumberGenerator>
4794 result_type
4795 operator()(_UniformRandomNumberGenerator& __urng,
4796 const param_type& __p);
4797
4798 /**
4799 * @brief Inserts a %discrete_distribution random number distribution
4800 * @p __x into the output stream @p __os.
4801 *
4802 * @param __os An output stream.
4803 * @param __x A %discrete_distribution random number distribution.
4804 *
4805 * @returns The output stream with the state of @p __x inserted or in
4806 * an error state.
4807 */
4808 template<typename _IntType1, typename _CharT, typename _Traits>
4809 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
4810 operator<<(std::basic_ostream<_CharT, _Traits>&,
4811 const std::discrete_distribution<_IntType1>&);
8e79468d
BK
4812
4813 /**
4814 * @brief Extracts a %discrete_distribution random number distribution
4815 * @p __x from the input stream @p __is.
4816 *
4817 * @param __is An input stream.
4818 * @param __x A %discrete_distribution random number
4819 * generator engine.
4820 *
4821 * @returns The input stream with @p __x extracted or in an error
4822 * state.
4823 */
4824 template<typename _IntType1, typename _CharT, typename _Traits>
4825 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
4826 operator>>(std::basic_istream<_CharT, _Traits>&,
4827 std::discrete_distribution<_IntType1>&);
8e79468d
BK
4828
4829 private:
4830 param_type _M_param;
4831 };
4832
fc05e1ba
PC
4833 /**
4834 * @brief Return true if two discrete distributions have the same
4835 * parameters.
4836 */
4837 template<typename _IntType>
4838 inline bool
4839 operator==(const std::discrete_distribution<_IntType>& __d1,
4840 const std::discrete_distribution<_IntType>& __d2)
4841 { return __d1.param() == __d2.param(); }
4842
4843 /**
4844 * @brief Return true if two discrete distributions have different
4845 * parameters.
4846 */
4847 template<typename _IntType>
4848 inline bool
4849 operator!=(const std::discrete_distribution<_IntType>& __d1,
4850 const std::discrete_distribution<_IntType>& __d2)
4851 { return !(__d1 == __d2); }
4852
8e79468d
BK
4853
4854 /**
4855 * @brief A piecewise_constant_distribution random number distribution.
4856 *
4857 * The formula for the piecewise constant probability mass function is
4858 *
4859 */
4860 template<typename _RealType = double>
4861 class piecewise_constant_distribution
4862 {
77e3c516
PC
4863 static_assert(std::is_floating_point<_RealType>::value,
4864 "template argument not a floating point type");
4865
8e79468d
BK
4866 public:
4867 /** The type of the range of the distribution. */
4868 typedef _RealType result_type;
4869 /** Parameter type. */
4870 struct param_type
4871 {
4872 typedef piecewise_constant_distribution<_RealType> distribution_type;
4873 friend class piecewise_constant_distribution<_RealType>;
4874
b01630bb 4875 param_type()
879b9073
PC
4876 : _M_int(), _M_den(), _M_cp()
4877 { }
8e79468d
BK
4878
4879 template<typename _InputIteratorB, typename _InputIteratorW>
4880 param_type(_InputIteratorB __bfirst,
4881 _InputIteratorB __bend,
4882 _InputIteratorW __wbegin);
4883
4884 template<typename _Func>
f8dd9e0d 4885 param_type(initializer_list<_RealType> __bi, _Func __fw);
8e79468d
BK
4886
4887 template<typename _Func>
4888 param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
4889 _Func __fw);
4890
ce9555cb
PC
4891 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
4892 param_type(const param_type&) = default;
4893 param_type& operator=(const param_type&) = default;
4894
8e79468d
BK
4895 std::vector<_RealType>
4896 intervals() const
879b9073
PC
4897 {
4898 if (_M_int.empty())
4899 {
4900 std::vector<_RealType> __tmp(2);
4901 __tmp[1] = _RealType(1);
4902 return __tmp;
4903 }
4904 else
4905 return _M_int;
4906 }
8e79468d
BK
4907
4908 std::vector<double>
4909 densities() const
879b9073 4910 { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
8e79468d 4911
fc05e1ba
PC
4912 friend bool
4913 operator==(const param_type& __p1, const param_type& __p2)
4914 { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
4915
8e79468d
BK
4916 private:
4917 void
4918 _M_initialize();
4919
4920 std::vector<_RealType> _M_int;
4921 std::vector<double> _M_den;
4922 std::vector<double> _M_cp;
4923 };
4924
4925 explicit
4926 piecewise_constant_distribution()
4927 : _M_param()
4928 { }
4929
4930 template<typename _InputIteratorB, typename _InputIteratorW>
4931 piecewise_constant_distribution(_InputIteratorB __bfirst,
4932 _InputIteratorB __bend,
4933 _InputIteratorW __wbegin)
4934 : _M_param(__bfirst, __bend, __wbegin)
4935 { }
4936
4937 template<typename _Func>
f8dd9e0d 4938 piecewise_constant_distribution(initializer_list<_RealType> __bl,
8e79468d 4939 _Func __fw)
f8dd9e0d 4940 : _M_param(__bl, __fw)
8e79468d
BK
4941 { }
4942
4943 template<typename _Func>
4944 piecewise_constant_distribution(size_t __nw,
4945 _RealType __xmin, _RealType __xmax,
4946 _Func __fw)
4947 : _M_param(__nw, __xmin, __xmax, __fw)
4948 { }
4949
4950 explicit
4951 piecewise_constant_distribution(const param_type& __p)
4952 : _M_param(__p)
4953 { }
4954
4955 /**
4956 * @brief Resets the distribution state.
4957 */
4958 void
4959 reset()
4960 { }
4961
4962 /**
4963 * @brief Returns a vector of the intervals.
4964 */
4965 std::vector<_RealType>
4966 intervals() const
879b9073
PC
4967 {
4968 if (_M_param._M_int.empty())
4969 {
4970 std::vector<_RealType> __tmp(2);
4971 __tmp[1] = _RealType(1);
4972 return __tmp;
4973 }
4974 else
4975 return _M_param._M_int;
4976 }
8e79468d
BK
4977
4978 /**
4979 * @brief Returns a vector of the probability densities.
4980 */
4981 std::vector<double>
4982 densities() const
879b9073
PC
4983 {
4984 return _M_param._M_den.empty()
4985 ? std::vector<double>(1, 1.0) : _M_param._M_den;
4986 }
8e79468d
BK
4987
4988 /**
4989 * @brief Returns the parameter set of the distribution.
4990 */
4991 param_type
4992 param() const
4993 { return _M_param; }
4994
4995 /**
4996 * @brief Sets the parameter set of the distribution.
4997 * @param __param The new parameter set of the distribution.
4998 */
4999 void
5000 param(const param_type& __param)
5001 { _M_param = __param; }
5002
5003 /**
5004 * @brief Returns the greatest lower bound value of the distribution.
5005 */
5006 result_type
5007 min() const
879b9073
PC
5008 {
5009 return _M_param._M_int.empty()
5010 ? result_type(0) : _M_param._M_int.front();
5011 }
8e79468d
BK
5012
5013 /**
5014 * @brief Returns the least upper bound value of the distribution.
5015 */
5016 result_type
5017 max() const
879b9073
PC
5018 {
5019 return _M_param._M_int.empty()
5020 ? result_type(1) : _M_param._M_int.back();
5021 }
8e79468d 5022
247d8075
PC
5023 /**
5024 * @brief Generating functions.
5025 */
8e79468d
BK
5026 template<typename _UniformRandomNumberGenerator>
5027 result_type
5028 operator()(_UniformRandomNumberGenerator& __urng)
5029 { return this->operator()(__urng, this->param()); }
5030
5031 template<typename _UniformRandomNumberGenerator>
5032 result_type
5033 operator()(_UniformRandomNumberGenerator& __urng,
5034 const param_type& __p);
5035
5036 /**
5037 * @brief Inserts a %piecewise_constan_distribution random
5038 * number distribution @p __x into the output stream @p __os.
5039 *
5040 * @param __os An output stream.
5041 * @param __x A %piecewise_constan_distribution random number
5042 * distribution.
5043 *
5044 * @returns The output stream with the state of @p __x inserted or in
5045 * an error state.
5046 */
5047 template<typename _RealType1, typename _CharT, typename _Traits>
5048 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
5049 operator<<(std::basic_ostream<_CharT, _Traits>&,
5050 const std::piecewise_constant_distribution<_RealType1>&);
8e79468d
BK
5051
5052 /**
5053 * @brief Extracts a %piecewise_constan_distribution random
5054 * number distribution @p __x from the input stream @p __is.
5055 *
5056 * @param __is An input stream.
5057 * @param __x A %piecewise_constan_distribution random number
5058 * generator engine.
5059 *
5060 * @returns The input stream with @p __x extracted or in an error
5061 * state.
5062 */
5063 template<typename _RealType1, typename _CharT, typename _Traits>
5064 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
5065 operator>>(std::basic_istream<_CharT, _Traits>&,
5066 std::piecewise_constant_distribution<_RealType1>&);
8e79468d
BK
5067
5068 private:
5069 param_type _M_param;
5070 };
5071
fc05e1ba
PC
5072 /**
5073 * @brief Return true if two piecewise constant distributions have the
5074 * same parameters.
5075 */
5076 template<typename _RealType>
5077 inline bool
5078 operator==(const std::piecewise_constant_distribution<_RealType>& __d1,
5079 const std::piecewise_constant_distribution<_RealType>& __d2)
5080 { return __d1.param() == __d2.param(); }
5081
5082 /**
5083 * @brief Return true if two piecewise constant distributions have
5084 * different parameters.
5085 */
5086 template<typename _RealType>
5087 inline bool
5088 operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
5089 const std::piecewise_constant_distribution<_RealType>& __d2)
5090 { return !(__d1 == __d2); }
5091
8e79468d
BK
5092
5093 /**
5094 * @brief A piecewise_linear_distribution random number distribution.
5095 *
5096 * The formula for the piecewise linear probability mass function is
5097 *
5098 */
5099 template<typename _RealType = double>
5100 class piecewise_linear_distribution
5101 {
77e3c516
PC
5102 static_assert(std::is_floating_point<_RealType>::value,
5103 "template argument not a floating point type");
5104
8e79468d
BK
5105 public:
5106 /** The type of the range of the distribution. */
5107 typedef _RealType result_type;
5108 /** Parameter type. */
5109 struct param_type
5110 {
5111 typedef piecewise_linear_distribution<_RealType> distribution_type;
5112 friend class piecewise_linear_distribution<_RealType>;
5113
f8dd9e0d 5114 param_type()
879b9073
PC
5115 : _M_int(), _M_den(), _M_cp(), _M_m()
5116 { }
8e79468d
BK
5117
5118 template<typename _InputIteratorB, typename _InputIteratorW>
5119 param_type(_InputIteratorB __bfirst,
5120 _InputIteratorB __bend,
5121 _InputIteratorW __wbegin);
5122
5123 template<typename _Func>
f8dd9e0d 5124 param_type(initializer_list<_RealType> __bl, _Func __fw);
8e79468d
BK
5125
5126 template<typename _Func>
5127 param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5128 _Func __fw);
5129
ce9555cb
PC
5130 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5131 param_type(const param_type&) = default;
5132 param_type& operator=(const param_type&) = default;
5133
8e79468d
BK
5134 std::vector<_RealType>
5135 intervals() const
879b9073
PC
5136 {
5137 if (_M_int.empty())
5138 {
5139 std::vector<_RealType> __tmp(2);
5140 __tmp[1] = _RealType(1);
5141 return __tmp;
5142 }
5143 else
5144 return _M_int;
5145 }
8e79468d
BK
5146
5147 std::vector<double>
5148 densities() const
879b9073 5149 { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
8e79468d 5150
fc05e1ba
PC
5151 friend bool
5152 operator==(const param_type& __p1, const param_type& __p2)
5153 { return (__p1._M_int == __p2._M_int
5154 && __p1._M_den == __p2._M_den); }
5155
8e79468d
BK
5156 private:
5157 void
5158 _M_initialize();
5159
5160 std::vector<_RealType> _M_int;
5161 std::vector<double> _M_den;
5162 std::vector<double> _M_cp;
5163 std::vector<double> _M_m;
5164 };
5165
5166 explicit
5167 piecewise_linear_distribution()
5168 : _M_param()
5169 { }
5170
5171 template<typename _InputIteratorB, typename _InputIteratorW>
5172 piecewise_linear_distribution(_InputIteratorB __bfirst,
5173 _InputIteratorB __bend,
5174 _InputIteratorW __wbegin)
5175 : _M_param(__bfirst, __bend, __wbegin)
5176 { }
5177
5178 template<typename _Func>
f8dd9e0d 5179 piecewise_linear_distribution(initializer_list<_RealType> __bl,
8e79468d 5180 _Func __fw)
f8dd9e0d 5181 : _M_param(__bl, __fw)
8e79468d
BK
5182 { }
5183
5184 template<typename _Func>
5185 piecewise_linear_distribution(size_t __nw,
5186 _RealType __xmin, _RealType __xmax,
5187 _Func __fw)
5188 : _M_param(__nw, __xmin, __xmax, __fw)
5189 { }
5190
5191 explicit
5192 piecewise_linear_distribution(const param_type& __p)
5193 : _M_param(__p)
5194 { }
5195
5196 /**
5197 * Resets the distribution state.
5198 */
5199 void
5200 reset()
5201 { }
5202
5203 /**
5204 * @brief Return the intervals of the distribution.
5205 */
5206 std::vector<_RealType>
5207 intervals() const
879b9073
PC
5208 {
5209 if (_M_param._M_int.empty())
5210 {
5211 std::vector<_RealType> __tmp(2);
5212 __tmp[1] = _RealType(1);
5213 return __tmp;
5214 }
5215 else
5216 return _M_param._M_int;
5217 }
8e79468d
BK
5218
5219 /**
5220 * @brief Return a vector of the probability densities of the
5221 * distribution.
5222 */
5223 std::vector<double>
5224 densities() const
879b9073
PC
5225 {
5226 return _M_param._M_den.empty()
5227 ? std::vector<double>(2, 1.0) : _M_param._M_den;
5228 }
8e79468d
BK
5229
5230 /**
5231 * @brief Returns the parameter set of the distribution.
5232 */
5233 param_type
5234 param() const
5235 { return _M_param; }
5236
5237 /**
5238 * @brief Sets the parameter set of the distribution.
5239 * @param __param The new parameter set of the distribution.
5240 */
5241 void
5242 param(const param_type& __param)
5243 { _M_param = __param; }
5244
5245 /**
5246 * @brief Returns the greatest lower bound value of the distribution.
5247 */
5248 result_type
5249 min() const
879b9073
PC
5250 {
5251 return _M_param._M_int.empty()
5252 ? result_type(0) : _M_param._M_int.front();
5253 }
8e79468d
BK
5254
5255 /**
5256 * @brief Returns the least upper bound value of the distribution.
5257 */
5258 result_type
5259 max() const
879b9073
PC
5260 {
5261 return _M_param._M_int.empty()
5262 ? result_type(1) : _M_param._M_int.back();
5263 }
8e79468d 5264
247d8075
PC
5265 /**
5266 * @brief Generating functions.
5267 */
8e79468d
BK
5268 template<typename _UniformRandomNumberGenerator>
5269 result_type
5270 operator()(_UniformRandomNumberGenerator& __urng)
5271 { return this->operator()(__urng, this->param()); }
5272
5273 template<typename _UniformRandomNumberGenerator>
5274 result_type
5275 operator()(_UniformRandomNumberGenerator& __urng,
5276 const param_type& __p);
5277
5278 /**
5279 * @brief Inserts a %piecewise_linear_distribution random number
5280 * distribution @p __x into the output stream @p __os.
5281 *
5282 * @param __os An output stream.
5283 * @param __x A %piecewise_linear_distribution random number
5284 * distribution.
5285 *
5286 * @returns The output stream with the state of @p __x inserted or in
5287 * an error state.
5288 */
5289 template<typename _RealType1, typename _CharT, typename _Traits>
5290 friend std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
5291 operator<<(std::basic_ostream<_CharT, _Traits>&,
5292 const std::piecewise_linear_distribution<_RealType1>&);
8e79468d
BK
5293
5294 /**
5295 * @brief Extracts a %piecewise_linear_distribution random number
5296 * distribution @p __x from the input stream @p __is.
5297 *
5298 * @param __is An input stream.
5299 * @param __x A %piecewise_linear_distribution random number
5300 * generator engine.
5301 *
5302 * @returns The input stream with @p __x extracted or in an error
5303 * state.
5304 */
5305 template<typename _RealType1, typename _CharT, typename _Traits>
5306 friend std::basic_istream<_CharT, _Traits>&
94986f6d
PC
5307 operator>>(std::basic_istream<_CharT, _Traits>&,
5308 std::piecewise_linear_distribution<_RealType1>&);
8e79468d
BK
5309
5310 private:
5311 param_type _M_param;
5312 };
5313
fc05e1ba
PC
5314 /**
5315 * @brief Return true if two piecewise linear distributions have the
5316 * same parameters.
5317 */
5318 template<typename _RealType>
5319 inline bool
5320 operator==(const std::piecewise_linear_distribution<_RealType>& __d1,
5321 const std::piecewise_linear_distribution<_RealType>& __d2)
5322 { return __d1.param() == __d2.param(); }
5323
5324 /**
5325 * @brief Return true if two piecewise linear distributions have
5326 * different parameters.
5327 */
5328 template<typename _RealType>
5329 inline bool
5330 operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
5331 const std::piecewise_linear_distribution<_RealType>& __d2)
5332 { return !(__d1 == __d2); }
5333
8e79468d 5334
037181bc 5335 /* @} */ // group random_distributions_poisson
8e79468d 5336
037181bc 5337 /* @} */ // group random_distributions
8e79468d
BK
5338
5339 /**
037181bc
BK
5340 * @addtogroup random_utilities Random Number Utilities
5341 * @ingroup random
8e79468d
BK
5342 * @{
5343 */
5344
5345 /**
5346 * @brief The seed_seq class generates sequences of seeds for random
5347 * number generators.
5348 */
5349 class seed_seq
5350 {
5351
5352 public:
5353 /** The type of the seed vales. */
5354 typedef uint_least32_t result_type;
5355
5356 /** Default constructor. */
5357 seed_seq()
5358 : _M_v()
5359 { }
5360
5361 template<typename _IntType>
5362 seed_seq(std::initializer_list<_IntType> il);
5363
5364 template<typename _InputIterator>
5365 seed_seq(_InputIterator __begin, _InputIterator __end);
5366
5367 // generating functions
5368 template<typename _RandomAccessIterator>
5369 void
5370 generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
5371
5372 // property functions
5373 size_t size() const
5374 { return _M_v.size(); }
5375
5376 template<typename OutputIterator>
5377 void
5378 param(OutputIterator __dest) const
5379 { std::copy(_M_v.begin(), _M_v.end(), __dest); }
5380
5381 private:
5382 ///
94986f6d 5383 std::vector<result_type> _M_v;
8e79468d
BK
5384 };
5385
037181bc 5386 /* @} */ // group random_utilities
8e79468d 5387
037181bc 5388 /* @} */ // group random
12ffa228
BK
5389
5390_GLIBCXX_END_NAMESPACE_VERSION
5391} // namespace std
8e79468d 5392
06f29237 5393#endif