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