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