]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/random.h
force-parallel-6.c: Adjust the loops.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / random.h
CommitLineData
8e79468d
BK
1// random number generation -*- C++ -*-
2
d9c257a7 3// Copyright (C) 2009, 2010, 2011, 2012 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 {
8e79468d 1641 FILE* _M_file;
8e79468d 1642 mt19937 _M_mt;
a8c3f4c9 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)
b01630bb 1770 { return this->operator()(__urng, this->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)
1782 { this->__generate(__f, __t, __urng, this->param()); }
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
1799 private:
1800 template<typename _ForwardIterator,
1801 typename _UniformRandomNumberGenerator>
1802 void
1803 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1804 _UniformRandomNumberGenerator& __urng,
1805 const param_type& __p);
1806
8e79468d
BK
1807 param_type _M_param;
1808 };
1809
fc05e1ba
PC
1810 /**
1811 * @brief Return true if two uniform integer distributions have
1812 * the same parameters.
1813 */
1814 template<typename _IntType>
1815 inline bool
1816 operator==(const std::uniform_int_distribution<_IntType>& __d1,
1817 const std::uniform_int_distribution<_IntType>& __d2)
1818 { return __d1.param() == __d2.param(); }
1819
1820 /**
1821 * @brief Return true if two uniform integer distributions have
1822 * different parameters.
1823 */
1824 template<typename _IntType>
1825 inline bool
1826 operator!=(const std::uniform_int_distribution<_IntType>& __d1,
1827 const std::uniform_int_distribution<_IntType>& __d2)
1828 { return !(__d1 == __d2); }
1829
8e79468d
BK
1830 /**
1831 * @brief Inserts a %uniform_int_distribution random number
1832 * distribution @p __x into the output stream @p os.
1833 *
1834 * @param __os An output stream.
1835 * @param __x A %uniform_int_distribution random number distribution.
1836 *
1837 * @returns The output stream with the state of @p __x inserted or in
1838 * an error state.
1839 */
1840 template<typename _IntType, typename _CharT, typename _Traits>
1841 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
1842 operator<<(std::basic_ostream<_CharT, _Traits>&,
1843 const std::uniform_int_distribution<_IntType>&);
8e79468d
BK
1844
1845 /**
1846 * @brief Extracts a %uniform_int_distribution random number distribution
1847 * @p __x from the input stream @p __is.
1848 *
1849 * @param __is An input stream.
1850 * @param __x A %uniform_int_distribution random number generator engine.
1851 *
1852 * @returns The input stream with @p __x extracted or in an error state.
1853 */
1854 template<typename _IntType, typename _CharT, typename _Traits>
1855 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
1856 operator>>(std::basic_istream<_CharT, _Traits>&,
1857 std::uniform_int_distribution<_IntType>&);
8e79468d
BK
1858
1859
1860 /**
1861 * @brief Uniform continuous distribution for random numbers.
1862 *
1863 * A continuous random distribution on the range [min, max) with equal
1864 * probability throughout the range. The URNG should be real-valued and
1865 * deliver number in the range [0, 1).
1866 */
1867 template<typename _RealType = double>
1868 class uniform_real_distribution
1869 {
77e3c516
PC
1870 static_assert(std::is_floating_point<_RealType>::value,
1871 "template argument not a floating point type");
1872
8e79468d
BK
1873 public:
1874 /** The type of the range of the distribution. */
1875 typedef _RealType result_type;
1876 /** Parameter type. */
1877 struct param_type
1878 {
1879 typedef uniform_real_distribution<_RealType> distribution_type;
1880
1881 explicit
1882 param_type(_RealType __a = _RealType(0),
1883 _RealType __b = _RealType(1))
1884 : _M_a(__a), _M_b(__b)
1885 {
1886 _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1887 }
1888
1889 result_type
1890 a() const
1891 { return _M_a; }
1892
1893 result_type
1894 b() const
1895 { return _M_b; }
1896
fc05e1ba
PC
1897 friend bool
1898 operator==(const param_type& __p1, const param_type& __p2)
1899 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1900
8e79468d
BK
1901 private:
1902 _RealType _M_a;
1903 _RealType _M_b;
1904 };
1905
1906 public:
1907 /**
1908 * @brief Constructs a uniform_real_distribution object.
1909 *
93c66bc6
BK
1910 * @param __a [IN] The lower bound of the distribution.
1911 * @param __b [IN] The upper bound of the distribution.
8e79468d
BK
1912 */
1913 explicit
1914 uniform_real_distribution(_RealType __a = _RealType(0),
1915 _RealType __b = _RealType(1))
1916 : _M_param(__a, __b)
1917 { }
1918
1919 explicit
1920 uniform_real_distribution(const param_type& __p)
1921 : _M_param(__p)
1922 { }
1923
1924 /**
1925 * @brief Resets the distribution state.
1926 *
1927 * Does nothing for the uniform real distribution.
1928 */
1929 void
1930 reset() { }
1931
1932 result_type
1933 a() const
1934 { return _M_param.a(); }
1935
1936 result_type
1937 b() const
1938 { return _M_param.b(); }
1939
247d8075
PC
1940 /**
1941 * @brief Returns the parameter set of the distribution.
1942 */
1943 param_type
1944 param() const
1945 { return _M_param; }
1946
1947 /**
1948 * @brief Sets the parameter set of the distribution.
1949 * @param __param The new parameter set of the distribution.
1950 */
1951 void
1952 param(const param_type& __param)
1953 { _M_param = __param; }
1954
8e79468d
BK
1955 /**
1956 * @brief Returns the inclusive lower bound of the distribution range.
1957 */
1958 result_type
1959 min() const
1960 { return this->a(); }
1961
1962 /**
1963 * @brief Returns the inclusive upper bound of the distribution range.
1964 */
1965 result_type
1966 max() const
1967 { return this->b(); }
1968
1969 /**
247d8075 1970 * @brief Generating functions.
8e79468d 1971 */
8e79468d
BK
1972 template<typename _UniformRandomNumberGenerator>
1973 result_type
1974 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 1975 { return this->operator()(__urng, this->param()); }
8e79468d
BK
1976
1977 template<typename _UniformRandomNumberGenerator>
1978 result_type
1979 operator()(_UniformRandomNumberGenerator& __urng,
1980 const param_type& __p)
1981 {
1982 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1983 __aurng(__urng);
1984 return (__aurng() * (__p.b() - __p.a())) + __p.a();
1985 }
1986
7b93bdde
UD
1987 template<typename _ForwardIterator,
1988 typename _UniformRandomNumberGenerator>
1989 void
1990 __generate(_ForwardIterator __f, _ForwardIterator __t,
1991 _UniformRandomNumberGenerator& __urng)
1992 { this->__generate(__f, __t, __urng, this->param()); }
1993
1994 template<typename _ForwardIterator,
1995 typename _UniformRandomNumberGenerator>
1996 void
1997 __generate(_ForwardIterator __f, _ForwardIterator __t,
1998 _UniformRandomNumberGenerator& __urng,
1999 const param_type& __p)
2000 { this->__generate_impl(__f, __t, __urng, __p); }
2001
2002 template<typename _UniformRandomNumberGenerator>
2003 void
2004 __generate(result_type* __f, result_type* __t,
2005 _UniformRandomNumberGenerator& __urng,
2006 const param_type& __p)
2007 { this->__generate_impl(__f, __t, __urng, __p); }
2008
8e79468d 2009 private:
7b93bdde
UD
2010 template<typename _ForwardIterator,
2011 typename _UniformRandomNumberGenerator>
2012 void
2013 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2014 _UniformRandomNumberGenerator& __urng,
2015 const param_type& __p);
2016
8e79468d
BK
2017 param_type _M_param;
2018 };
2019
fc05e1ba
PC
2020 /**
2021 * @brief Return true if two uniform real distributions have
2022 * the same parameters.
2023 */
2024 template<typename _IntType>
2025 inline bool
2026 operator==(const std::uniform_real_distribution<_IntType>& __d1,
2027 const std::uniform_real_distribution<_IntType>& __d2)
2028 { return __d1.param() == __d2.param(); }
2029
2030 /**
2031 * @brief Return true if two uniform real distributions have
2032 * different parameters.
2033 */
2034 template<typename _IntType>
2035 inline bool
2036 operator!=(const std::uniform_real_distribution<_IntType>& __d1,
2037 const std::uniform_real_distribution<_IntType>& __d2)
2038 { return !(__d1 == __d2); }
2039
8e79468d
BK
2040 /**
2041 * @brief Inserts a %uniform_real_distribution random number
2042 * distribution @p __x into the output stream @p __os.
2043 *
2044 * @param __os An output stream.
2045 * @param __x A %uniform_real_distribution random number distribution.
2046 *
2047 * @returns The output stream with the state of @p __x inserted or in
2048 * an error state.
2049 */
2050 template<typename _RealType, typename _CharT, typename _Traits>
2051 std::basic_ostream<_CharT, _Traits>&
94986f6d
PC
2052 operator<<(std::basic_ostream<_CharT, _Traits>&,
2053 const std::uniform_real_distribution<_RealType>&);
8e79468d
BK
2054
2055 /**
2056 * @brief Extracts a %uniform_real_distribution random number distribution
2057 * @p __x from the input stream @p __is.
2058 *
2059 * @param __is An input stream.
2060 * @param __x A %uniform_real_distribution random number generator engine.
2061 *
2062 * @returns The input stream with @p __x extracted or in an error state.
2063 */
2064 template<typename _RealType, typename _CharT, typename _Traits>
2065 std::basic_istream<_CharT, _Traits>&
94986f6d
PC
2066 operator>>(std::basic_istream<_CharT, _Traits>&,
2067 std::uniform_real_distribution<_RealType>&);
8e79468d 2068
037181bc 2069 /* @} */ // group random_distributions_uniform
8e79468d
BK
2070
2071 /**
94a86be0 2072 * @addtogroup random_distributions_normal Normal Distributions
037181bc 2073 * @ingroup random_distributions
8e79468d
BK
2074 * @{
2075 */
2076
2077 /**
2078 * @brief A normal continuous distribution for random numbers.
2079 *
2080 * The formula for the normal probability density function is
6cc5a790
BK
2081 * @f[
2082 * p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
2083 * e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} }
2084 * @f]
8e79468d
BK
2085 */
2086 template<typename _RealType = double>
2087 class normal_distribution
2088 {
77e3c516
PC
2089 static_assert(std::is_floating_point<_RealType>::value,
2090 "template argument not a floating point type");
2091
8e79468d
BK
2092 public:
2093 /** The type of the range of the distribution. */
2094 typedef _RealType result_type;
2095 /** Parameter type. */
2096 struct param_type
2097 {
2098 typedef normal_distribution<_RealType> distribution_type;
2099
2100 explicit
2101 param_type(_RealType __mean = _RealType(0),
2102 _RealType __stddev = _RealType(1))
2103 : _M_mean(__mean), _M_stddev(__stddev)
2104 {
2105 _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
2106 }
2107
2108 _RealType
2109 mean() const
2110 { return _M_mean; }
2111
2112 _RealType
2113 stddev() const
2114 { return _M_stddev; }
2115
fc05e1ba
PC
2116 friend bool
2117 operator==(const param_type& __p1, const param_type& __p2)
2118 { return (__p1._M_mean == __p2._M_mean
2119 && __p1._M_stddev == __p2._M_stddev); }
2120
8e79468d
BK
2121 private:
2122 _RealType _M_mean;
2123 _RealType _M_stddev;
2124 };
2125
2126 public:
2127 /**
6cc5a790 2128 * Constructs a normal distribution with parameters @f$mean@f$ and
8e79468d
BK
2129 * standard deviation.
2130 */
2131 explicit
2132 normal_distribution(result_type __mean = result_type(0),
2133 result_type __stddev = result_type(1))
2134 : _M_param(__mean, __stddev), _M_saved_available(false)
2135 { }
2136
2137 explicit
2138 normal_distribution(const param_type& __p)
2139 : _M_param(__p), _M_saved_available(false)
2140 { }
2141
2142 /**
2143 * @brief Resets the distribution state.
2144 */
2145 void
2146 reset()
2147 { _M_saved_available = false; }
2148
2149 /**
2150 * @brief Returns the mean of the distribution.
2151 */
2152 _RealType
2153 mean() const
2154 { return _M_param.mean(); }
2155
2156 /**
2157 * @brief Returns the standard deviation of the distribution.
2158 */
2159 _RealType
2160 stddev() const
2161 { return _M_param.stddev(); }
2162
2163 /**
2164 * @brief Returns the parameter set of the distribution.
2165 */
2166 param_type
2167 param() const
2168 { return _M_param; }
2169
2170 /**
2171 * @brief Sets the parameter set of the distribution.
2172 * @param __param The new parameter set of the distribution.
2173 */
2174 void
2175 param(const param_type& __param)
2176 { _M_param = __param; }
2177
2178 /**
2179 * @brief Returns the greatest lower bound value of the distribution.
2180 */
2181 result_type
2182 min() const
2183 { return std::numeric_limits<result_type>::min(); }
2184
2185 /**
2186 * @brief Returns the least upper bound value of the distribution.
2187 */
2188 result_type
2189 max() const
2190 { return std::numeric_limits<result_type>::max(); }
2191
247d8075
PC
2192 /**
2193 * @brief Generating functions.
2194 */
8e79468d
BK
2195 template<typename _UniformRandomNumberGenerator>
2196 result_type
2197 operator()(_UniformRandomNumberGenerator& __urng)
2198 { return this->operator()(__urng, this->param()); }
2199
2200 template<typename _UniformRandomNumberGenerator>
2201 result_type
2202 operator()(_UniformRandomNumberGenerator& __urng,
2203 const param_type& __p);
2204
7b93bdde
UD
2205 template<typename _ForwardIterator,
2206 typename _UniformRandomNumberGenerator>
2207 void
2208 __generate(_ForwardIterator __f, _ForwardIterator __t,
2209 _UniformRandomNumberGenerator& __urng)
2210 { this->__generate(__f, __t, __urng, this->param()); }
2211
2212 template<typename _ForwardIterator,
2213 typename _UniformRandomNumberGenerator>
2214 void
2215 __generate(_ForwardIterator __f, _ForwardIterator __t,
2216 _UniformRandomNumberGenerator& __urng,
2217 const param_type& __p)
2218 { this->__generate_impl(__f, __t, __urng, __p); }
2219
2220 template<typename _UniformRandomNumberGenerator>
2221 void
2222 __generate(result_type* __f, result_type* __t,
2223 _UniformRandomNumberGenerator& __urng,
2224 const param_type& __p)
2225 { this->__generate_impl(__f, __t, __urng, __p); }
2226
fc05e1ba
PC
2227 /**
2228 * @brief Return true if two normal distributions have
2229 * the same parameters and the sequences that would
2230 * be generated are equal.
2231 */
2232 template<typename _RealType1>
2233 friend bool
2234 operator==(const std::normal_distribution<_RealType1>& __d1,
2235 const std::normal_distribution<_RealType1>& __d2);
2236
8e79468d
BK
2237 /**
2238 * @brief Inserts a %normal_distribution random number distribution
2239 * @p __x into the output stream @p __os.
2240 *
2241 * @param __os An output stream.
2242 * @param __x A %normal_distribution random number distribution.
2243 *
2244 * @returns The output stream with the state of @p __x inserted or in
2245 * an error state.
2246 */
2247 template<typename _RealType1, typename _CharT, typename _Traits>
2248 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
2249 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2250 const std::normal_distribution<_RealType1>& __x);
8e79468d
BK
2251
2252 /**
2253 * @brief Extracts a %normal_distribution random number distribution
2254 * @p __x from the input stream @p __is.
2255 *
2256 * @param __is An input stream.
2257 * @param __x A %normal_distribution random number generator engine.
2258 *
2259 * @returns The input stream with @p __x extracted or in an error
2260 * state.
2261 */
2262 template<typename _RealType1, typename _CharT, typename _Traits>
2263 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
2264 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2265 std::normal_distribution<_RealType1>& __x);
8e79468d
BK
2266
2267 private:
7b93bdde
UD
2268 template<typename _ForwardIterator,
2269 typename _UniformRandomNumberGenerator>
2270 void
2271 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2272 _UniformRandomNumberGenerator& __urng,
2273 const param_type& __p);
2274
8e79468d
BK
2275 param_type _M_param;
2276 result_type _M_saved;
2277 bool _M_saved_available;
2278 };
2279
fc05e1ba
PC
2280 /**
2281 * @brief Return true if two normal distributions are different.
2282 */
2283 template<typename _RealType>
2284 inline bool
2285 operator!=(const std::normal_distribution<_RealType>& __d1,
2286 const std::normal_distribution<_RealType>& __d2)
2287 { return !(__d1 == __d2); }
2288
8e79468d
BK
2289
2290 /**
2291 * @brief A lognormal_distribution random number distribution.
2292 *
2293 * The formula for the normal probability mass function is
6cc5a790
BK
2294 * @f[
2295 * p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
2296 * \exp{-\frac{(\ln{x} - m)^2}{2s^2}}
2297 * @f]
8e79468d
BK
2298 */
2299 template<typename _RealType = double>
2300 class lognormal_distribution
2301 {
77e3c516
PC
2302 static_assert(std::is_floating_point<_RealType>::value,
2303 "template argument not a floating point type");
2304
8e79468d
BK
2305 public:
2306 /** The type of the range of the distribution. */
2307 typedef _RealType result_type;
2308 /** Parameter type. */
2309 struct param_type
2310 {
2311 typedef lognormal_distribution<_RealType> distribution_type;
2312
2313 explicit
2314 param_type(_RealType __m = _RealType(0),
2315 _RealType __s = _RealType(1))
2316 : _M_m(__m), _M_s(__s)
2317 { }
2318
2319 _RealType
2320 m() const
2321 { return _M_m; }
2322
2323 _RealType
2324 s() const
2325 { return _M_s; }
2326
fc05e1ba
PC
2327 friend bool
2328 operator==(const param_type& __p1, const param_type& __p2)
2329 { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
2330
8e79468d
BK
2331 private:
2332 _RealType _M_m;
2333 _RealType _M_s;
2334 };
2335
2336 explicit
2337 lognormal_distribution(_RealType __m = _RealType(0),
2338 _RealType __s = _RealType(1))
b01630bb 2339 : _M_param(__m, __s), _M_nd()
8e79468d
BK
2340 { }
2341
2342 explicit
2343 lognormal_distribution(const param_type& __p)
b01630bb 2344 : _M_param(__p), _M_nd()
8e79468d
BK
2345 { }
2346
2347 /**
2348 * Resets the distribution state.
2349 */
2350 void
2351 reset()
b01630bb 2352 { _M_nd.reset(); }
8e79468d
BK
2353
2354 /**
2355 *
2356 */
2357 _RealType
2358 m() const
2359 { return _M_param.m(); }
2360
2361 _RealType
2362 s() const
2363 { return _M_param.s(); }
2364
2365 /**
2366 * @brief Returns the parameter set of the distribution.
2367 */
2368 param_type
2369 param() const
2370 { return _M_param; }
2371
2372 /**
2373 * @brief Sets the parameter set of the distribution.
2374 * @param __param The new parameter set of the distribution.
2375 */
2376 void
2377 param(const param_type& __param)
2378 { _M_param = __param; }
2379
2380 /**
2381 * @brief Returns the greatest lower bound value of the distribution.
2382 */
2383 result_type
2384 min() const
2385 { return result_type(0); }
2386
2387 /**
2388 * @brief Returns the least upper bound value of the distribution.
2389 */
2390 result_type
2391 max() const
2392 { return std::numeric_limits<result_type>::max(); }
2393
247d8075
PC
2394 /**
2395 * @brief Generating functions.
2396 */
8e79468d
BK
2397 template<typename _UniformRandomNumberGenerator>
2398 result_type
2399 operator()(_UniformRandomNumberGenerator& __urng)
2400 { return this->operator()(__urng, this->param()); }
2401
2402 template<typename _UniformRandomNumberGenerator>
2403 result_type
2404 operator()(_UniformRandomNumberGenerator& __urng,
b01630bb
PC
2405 const param_type& __p)
2406 { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
8e79468d 2407
7b93bdde
UD
2408 template<typename _ForwardIterator,
2409 typename _UniformRandomNumberGenerator>
2410 void
2411 __generate(_ForwardIterator __f, _ForwardIterator __t,
2412 _UniformRandomNumberGenerator& __urng)
2413 { this->__generate(__f, __t, __urng, this->param()); }
2414
2415 template<typename _ForwardIterator,
2416 typename _UniformRandomNumberGenerator>
2417 void
2418 __generate(_ForwardIterator __f, _ForwardIterator __t,
2419 _UniformRandomNumberGenerator& __urng,
2420 const param_type& __p)
2421 { this->__generate_impl(__f, __t, __urng, __p); }
2422
2423 template<typename _UniformRandomNumberGenerator>
2424 void
2425 __generate(result_type* __f, result_type* __t,
2426 _UniformRandomNumberGenerator& __urng,
2427 const param_type& __p)
2428 { this->__generate_impl(__f, __t, __urng, __p); }
2429
fc05e1ba
PC
2430 /**
2431 * @brief Return true if two lognormal distributions have
2432 * the same parameters and the sequences that would
2433 * be generated are equal.
2434 */
a30e18c1
MG
2435 friend bool
2436 operator==(const lognormal_distribution& __d1,
2437 const lognormal_distribution& __d2)
2438 { return (__d1.param() == __d2.param()
2439 && __d1._M_nd == __d2._M_nd); }
fc05e1ba 2440
e1923769
ESR
2441 /**
2442 * @brief Inserts a %lognormal_distribution random number distribution
2443 * @p __x into the output stream @p __os.
2444 *
2445 * @param __os An output stream.
2446 * @param __x A %lognormal_distribution random number distribution.
2447 *
2448 * @returns The output stream with the state of @p __x inserted or in
2449 * an error state.
2450 */
2451 template<typename _RealType1, typename _CharT, typename _Traits>
2452 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
2453 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2454 const std::lognormal_distribution<_RealType1>& __x);
e1923769
ESR
2455
2456 /**
2457 * @brief Extracts a %lognormal_distribution random number distribution
2458 * @p __x from the input stream @p __is.
2459 *
2460 * @param __is An input stream.
2461 * @param __x A %lognormal_distribution random number
2462 * generator engine.
2463 *
2464 * @returns The input stream with @p __x extracted or in an error state.
2465 */
2466 template<typename _RealType1, typename _CharT, typename _Traits>
2467 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
2468 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2469 std::lognormal_distribution<_RealType1>& __x);
e1923769 2470
8e79468d 2471 private:
7b93bdde
UD
2472 template<typename _ForwardIterator,
2473 typename _UniformRandomNumberGenerator>
2474 void
2475 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2476 _UniformRandomNumberGenerator& __urng,
2477 const param_type& __p);
2478
8e79468d 2479 param_type _M_param;
b01630bb 2480
f9b09dec 2481 std::normal_distribution<result_type> _M_nd;
8e79468d
BK
2482 };
2483
fc05e1ba
PC
2484 /**
2485 * @brief Return true if two lognormal distributions are different.
2486 */
2487 template<typename _RealType>
2488 inline bool
2489 operator!=(const std::lognormal_distribution<_RealType>& __d1,
2490 const std::lognormal_distribution<_RealType>& __d2)
2491 { return !(__d1 == __d2); }
2492
2493
f9b09dec
PC
2494 /**
2495 * @brief A gamma continuous distribution for random numbers.
2496 *
6cc5a790
BK
2497 * The formula for the gamma probability density function is:
2498 * @f[
2499 * p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
2500 * (x/\beta)^{\alpha - 1} e^{-x/\beta}
2501 * @f]
f9b09dec
PC
2502 */
2503 template<typename _RealType = double>
2504 class gamma_distribution
2505 {
77e3c516
PC
2506 static_assert(std::is_floating_point<_RealType>::value,
2507 "template argument not a floating point type");
2508
f9b09dec
PC
2509 public:
2510 /** The type of the range of the distribution. */
2511 typedef _RealType result_type;
2512 /** Parameter type. */
2513 struct param_type
2514 {
2515 typedef gamma_distribution<_RealType> distribution_type;
2516 friend class gamma_distribution<_RealType>;
2517
2518 explicit
2519 param_type(_RealType __alpha_val = _RealType(1),
2520 _RealType __beta_val = _RealType(1))
2521 : _M_alpha(__alpha_val), _M_beta(__beta_val)
2522 {
2523 _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
2524 _M_initialize();
2525 }
2526
2527 _RealType
2528 alpha() const
2529 { return _M_alpha; }
2530
2531 _RealType
2532 beta() const
2533 { return _M_beta; }
2534
fc05e1ba
PC
2535 friend bool
2536 operator==(const param_type& __p1, const param_type& __p2)
2537 { return (__p1._M_alpha == __p2._M_alpha
2538 && __p1._M_beta == __p2._M_beta); }
2539
f9b09dec
PC
2540 private:
2541 void
2542 _M_initialize();
2543
2544 _RealType _M_alpha;
2545 _RealType _M_beta;
2546
2547 _RealType _M_malpha, _M_a2;
2548 };
2549
2550 public:
2551 /**
2552 * @brief Constructs a gamma distribution with parameters
6cc5a790 2553 * @f$\alpha@f$ and @f$\beta@f$.
f9b09dec
PC
2554 */
2555 explicit
2556 gamma_distribution(_RealType __alpha_val = _RealType(1),
2557 _RealType __beta_val = _RealType(1))
2558 : _M_param(__alpha_val, __beta_val), _M_nd()
2559 { }
2560
2561 explicit
2562 gamma_distribution(const param_type& __p)
2563 : _M_param(__p), _M_nd()
2564 { }
2565
2566 /**
2567 * @brief Resets the distribution state.
2568 */
2569 void
2570 reset()
2571 { _M_nd.reset(); }
2572
2573 /**
6cc5a790 2574 * @brief Returns the @f$\alpha@f$ of the distribution.
f9b09dec
PC
2575 */
2576 _RealType
2577 alpha() const
2578 { return _M_param.alpha(); }
2579
2580 /**
6cc5a790 2581 * @brief Returns the @f$\beta@f$ of the distribution.
f9b09dec
PC
2582 */
2583 _RealType
2584 beta() const
2585 { return _M_param.beta(); }
2586
2587 /**
2588 * @brief Returns the parameter set of the distribution.
2589 */
2590 param_type
2591 param() const
2592 { return _M_param; }
2593
2594 /**
2595 * @brief Sets the parameter set of the distribution.
2596 * @param __param The new parameter set of the distribution.
2597 */
2598 void
2599 param(const param_type& __param)
2600 { _M_param = __param; }
2601
2602 /**
2603 * @brief Returns the greatest lower bound value of the distribution.
2604 */
2605 result_type
2606 min() const
2607 { return result_type(0); }
2608
2609 /**
2610 * @brief Returns the least upper bound value of the distribution.
2611 */
2612 result_type
2613 max() const
2614 { return std::numeric_limits<result_type>::max(); }
2615
247d8075
PC
2616 /**
2617 * @brief Generating functions.
2618 */
f9b09dec
PC
2619 template<typename _UniformRandomNumberGenerator>
2620 result_type
2621 operator()(_UniformRandomNumberGenerator& __urng)
2622 { return this->operator()(__urng, this->param()); }
2623
2624 template<typename _UniformRandomNumberGenerator>
2625 result_type
2626 operator()(_UniformRandomNumberGenerator& __urng,
2627 const param_type& __p);
2628
7b93bdde
UD
2629 template<typename _ForwardIterator,
2630 typename _UniformRandomNumberGenerator>
2631 void
2632 __generate(_ForwardIterator __f, _ForwardIterator __t,
2633 _UniformRandomNumberGenerator& __urng)
2634 { this->__generate(__f, __t, __urng, this->param()); }
2635
2636 template<typename _ForwardIterator,
2637 typename _UniformRandomNumberGenerator>
2638 void
2639 __generate(_ForwardIterator __f, _ForwardIterator __t,
2640 _UniformRandomNumberGenerator& __urng,
2641 const param_type& __p)
2642 { this->__generate_impl(__f, __t, __urng, __p); }
2643
2644 template<typename _UniformRandomNumberGenerator>
2645 void
2646 __generate(result_type* __f, result_type* __t,
2647 _UniformRandomNumberGenerator& __urng,
2648 const param_type& __p)
2649 { this->__generate_impl(__f, __t, __urng, __p); }
2650
fc05e1ba
PC
2651 /**
2652 * @brief Return true if two gamma distributions have the same
2653 * parameters and the sequences that would be generated
2654 * are equal.
2655 */
a30e18c1
MG
2656 friend bool
2657 operator==(const gamma_distribution& __d1,
2658 const gamma_distribution& __d2)
2659 { return (__d1.param() == __d2.param()
2660 && __d1._M_nd == __d2._M_nd); }
fc05e1ba 2661
e1923769
ESR
2662 /**
2663 * @brief Inserts a %gamma_distribution random number distribution
2664 * @p __x into the output stream @p __os.
2665 *
2666 * @param __os An output stream.
2667 * @param __x A %gamma_distribution random number distribution.
2668 *
2669 * @returns The output stream with the state of @p __x inserted or in
2670 * an error state.
2671 */
2672 template<typename _RealType1, typename _CharT, typename _Traits>
2673 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
2674 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2675 const std::gamma_distribution<_RealType1>& __x);
e1923769
ESR
2676
2677 /**
2678 * @brief Extracts a %gamma_distribution random number distribution
2679 * @p __x from the input stream @p __is.
2680 *
2681 * @param __is An input stream.
2682 * @param __x A %gamma_distribution random number generator engine.
2683 *
2684 * @returns The input stream with @p __x extracted or in an error state.
2685 */
2686 template<typename _RealType1, typename _CharT, typename _Traits>
2687 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
2688 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2689 std::gamma_distribution<_RealType1>& __x);
e1923769 2690
f9b09dec 2691 private:
7b93bdde
UD
2692 template<typename _ForwardIterator,
2693 typename _UniformRandomNumberGenerator>
2694 void
2695 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2696 _UniformRandomNumberGenerator& __urng,
2697 const param_type& __p);
2698
f9b09dec
PC
2699 param_type _M_param;
2700
2701 std::normal_distribution<result_type> _M_nd;
2702 };
2703
fc05e1ba
PC
2704 /**
2705 * @brief Return true if two gamma distributions are different.
2706 */
2707 template<typename _RealType>
a30e18c1 2708 inline bool
fc05e1ba
PC
2709 operator!=(const std::gamma_distribution<_RealType>& __d1,
2710 const std::gamma_distribution<_RealType>& __d2)
2711 { return !(__d1 == __d2); }
2712
8e79468d
BK
2713
2714 /**
2715 * @brief A chi_squared_distribution random number distribution.
2716 *
2717 * The formula for the normal probability mass function is
6cc5a790 2718 * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
8e79468d
BK
2719 */
2720 template<typename _RealType = double>
2721 class chi_squared_distribution
2722 {
77e3c516
PC
2723 static_assert(std::is_floating_point<_RealType>::value,
2724 "template argument not a floating point type");
2725
8e79468d
BK
2726 public:
2727 /** The type of the range of the distribution. */
2728 typedef _RealType result_type;
2729 /** Parameter type. */
2730 struct param_type
2731 {
2732 typedef chi_squared_distribution<_RealType> distribution_type;
2733
2734 explicit
2735 param_type(_RealType __n = _RealType(1))
2736 : _M_n(__n)
2737 { }
2738
2739 _RealType
2740 n() const
2741 { return _M_n; }
2742
fc05e1ba
PC
2743 friend bool
2744 operator==(const param_type& __p1, const param_type& __p2)
2745 { return __p1._M_n == __p2._M_n; }
2746
8e79468d
BK
2747 private:
2748 _RealType _M_n;
2749 };
2750
2751 explicit
2752 chi_squared_distribution(_RealType __n = _RealType(1))
f9b09dec 2753 : _M_param(__n), _M_gd(__n / 2)
8e79468d
BK
2754 { }
2755
2756 explicit
2757 chi_squared_distribution(const param_type& __p)
f9b09dec 2758 : _M_param(__p), _M_gd(__p.n() / 2)
8e79468d
BK
2759 { }
2760
2761 /**
2762 * @brief Resets the distribution state.
2763 */
2764 void
2765 reset()
f9b09dec 2766 { _M_gd.reset(); }
8e79468d
BK
2767
2768 /**
2769 *
2770 */
2771 _RealType
2772 n() const
2773 { return _M_param.n(); }
2774
2775 /**
2776 * @brief Returns the parameter set of the distribution.
2777 */
2778 param_type
2779 param() const
2780 { return _M_param; }
2781
2782 /**
2783 * @brief Sets the parameter set of the distribution.
2784 * @param __param The new parameter set of the distribution.
2785 */
2786 void
2787 param(const param_type& __param)
2788 { _M_param = __param; }
2789
2790 /**
2791 * @brief Returns the greatest lower bound value of the distribution.
2792 */
2793 result_type
2794 min() const
2795 { return result_type(0); }
2796
2797 /**
2798 * @brief Returns the least upper bound value of the distribution.
2799 */
2800 result_type
2801 max() const
2802 { return std::numeric_limits<result_type>::max(); }
2803
247d8075
PC
2804 /**
2805 * @brief Generating functions.
2806 */
8e79468d
BK
2807 template<typename _UniformRandomNumberGenerator>
2808 result_type
2809 operator()(_UniformRandomNumberGenerator& __urng)
f9b09dec 2810 { return 2 * _M_gd(__urng); }
8e79468d
BK
2811
2812 template<typename _UniformRandomNumberGenerator>
2813 result_type
2814 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
2815 const param_type& __p)
2816 {
2817 typedef typename std::gamma_distribution<result_type>::param_type
2818 param_type;
2819 return 2 * _M_gd(__urng, param_type(__p.n() / 2));
2820 }
8e79468d 2821
7b93bdde
UD
2822 template<typename _ForwardIterator,
2823 typename _UniformRandomNumberGenerator>
2824 void
2825 __generate(_ForwardIterator __f, _ForwardIterator __t,
2826 _UniformRandomNumberGenerator& __urng)
2827 { this->__generate_impl(__f, __t, __urng, _M_gd.param()); }
2828
2829 template<typename _ForwardIterator,
2830 typename _UniformRandomNumberGenerator>
2831 void
2832 __generate(_ForwardIterator __f, _ForwardIterator __t,
2833 _UniformRandomNumberGenerator& __urng,
2834 const param_type& __p)
2835 { typename std::gamma_distribution<result_type>::param_type
2836 __p2(__p.n() / 2);
2837 this->__generate_impl(__f, __t, __urng, __p2); }
2838
2839 template<typename _UniformRandomNumberGenerator>
2840 void
2841 __generate(result_type* __f, result_type* __t,
2842 _UniformRandomNumberGenerator& __urng)
2843 { typename std::gamma_distribution<result_type>::param_type
2844 __p2(_M_gd.param());
2845 this->__generate_impl(__f, __t, __urng, __p2); }
2846
2847 template<typename _UniformRandomNumberGenerator>
2848 void
2849 __generate(result_type* __f, result_type* __t,
2850 _UniformRandomNumberGenerator& __urng,
2851 const param_type& __p)
2852 { typename std::gamma_distribution<result_type>::param_type
2853 __p2(__p.n() / 2);
2854 this->__generate_impl(__f, __t, __urng, __p2); }
2855
fc05e1ba
PC
2856 /**
2857 * @brief Return true if two Chi-squared distributions have
2858 * the same parameters and the sequences that would be
2859 * generated are equal.
2860 */
a30e18c1
MG
2861 friend bool
2862 operator==(const chi_squared_distribution& __d1,
2863 const chi_squared_distribution& __d2)
2864 { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
fc05e1ba 2865
e1923769
ESR
2866 /**
2867 * @brief Inserts a %chi_squared_distribution random number distribution
2868 * @p __x into the output stream @p __os.
2869 *
2870 * @param __os An output stream.
2871 * @param __x A %chi_squared_distribution random number distribution.
2872 *
2873 * @returns The output stream with the state of @p __x inserted or in
2874 * an error state.
2875 */
2876 template<typename _RealType1, typename _CharT, typename _Traits>
2877 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
2878 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2879 const std::chi_squared_distribution<_RealType1>& __x);
e1923769
ESR
2880
2881 /**
2882 * @brief Extracts a %chi_squared_distribution random number distribution
2883 * @p __x from the input stream @p __is.
2884 *
2885 * @param __is An input stream.
2886 * @param __x A %chi_squared_distribution random number
2887 * generator engine.
2888 *
2889 * @returns The input stream with @p __x extracted or in an error state.
2890 */
2891 template<typename _RealType1, typename _CharT, typename _Traits>
2892 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
2893 operator>>(std::basic_istream<_CharT, _Traits>& __is,
2894 std::chi_squared_distribution<_RealType1>& __x);
e1923769 2895
8e79468d 2896 private:
7b93bdde
UD
2897 template<typename _ForwardIterator,
2898 typename _UniformRandomNumberGenerator>
2899 void
2900 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2901 _UniformRandomNumberGenerator& __urng,
2902 typename std::gamma_distribution<result_type>::param_type&
2903 __p);
2904
8e79468d 2905 param_type _M_param;
f9b09dec
PC
2906
2907 std::gamma_distribution<result_type> _M_gd;
8e79468d
BK
2908 };
2909
fc05e1ba
PC
2910 /**
2911 * @brief Return true if two Chi-squared distributions are different.
2912 */
2913 template<typename _RealType>
2914 inline bool
2915 operator!=(const std::chi_squared_distribution<_RealType>& __d1,
2916 const std::chi_squared_distribution<_RealType>& __d2)
2917 { return !(__d1 == __d2); }
2918
8e79468d
BK
2919
2920 /**
2921 * @brief A cauchy_distribution random number distribution.
2922 *
2923 * The formula for the normal probability mass function is
6cc5a790 2924 * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
8e79468d
BK
2925 */
2926 template<typename _RealType = double>
2927 class cauchy_distribution
2928 {
77e3c516
PC
2929 static_assert(std::is_floating_point<_RealType>::value,
2930 "template argument not a floating point type");
2931
8e79468d
BK
2932 public:
2933 /** The type of the range of the distribution. */
2934 typedef _RealType result_type;
2935 /** Parameter type. */
2936 struct param_type
2937 {
2938 typedef cauchy_distribution<_RealType> distribution_type;
2939
2940 explicit
2941 param_type(_RealType __a = _RealType(0),
2942 _RealType __b = _RealType(1))
2943 : _M_a(__a), _M_b(__b)
2944 { }
2945
2946 _RealType
2947 a() const
2948 { return _M_a; }
2949
2950 _RealType
2951 b() const
2952 { return _M_b; }
2953
fc05e1ba
PC
2954 friend bool
2955 operator==(const param_type& __p1, const param_type& __p2)
2956 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
2957
8e79468d
BK
2958 private:
2959 _RealType _M_a;
2960 _RealType _M_b;
2961 };
2962
2963 explicit
2964 cauchy_distribution(_RealType __a = _RealType(0),
2965 _RealType __b = _RealType(1))
2966 : _M_param(__a, __b)
2967 { }
2968
2969 explicit
2970 cauchy_distribution(const param_type& __p)
2971 : _M_param(__p)
2972 { }
2973
2974 /**
2975 * @brief Resets the distribution state.
2976 */
2977 void
2978 reset()
2979 { }
2980
2981 /**
2982 *
2983 */
2984 _RealType
2985 a() const
2986 { return _M_param.a(); }
2987
2988 _RealType
2989 b() const
2990 { return _M_param.b(); }
2991
2992 /**
2993 * @brief Returns the parameter set of the distribution.
2994 */
2995 param_type
2996 param() const
2997 { return _M_param; }
2998
2999 /**
3000 * @brief Sets the parameter set of the distribution.
3001 * @param __param The new parameter set of the distribution.
3002 */
3003 void
3004 param(const param_type& __param)
3005 { _M_param = __param; }
3006
3007 /**
3008 * @brief Returns the greatest lower bound value of the distribution.
3009 */
3010 result_type
3011 min() const
3012 { return std::numeric_limits<result_type>::min(); }
3013
3014 /**
3015 * @brief Returns the least upper bound value of the distribution.
3016 */
3017 result_type
3018 max() const
3019 { return std::numeric_limits<result_type>::max(); }
3020
247d8075
PC
3021 /**
3022 * @brief Generating functions.
3023 */
8e79468d
BK
3024 template<typename _UniformRandomNumberGenerator>
3025 result_type
3026 operator()(_UniformRandomNumberGenerator& __urng)
3027 { return this->operator()(__urng, this->param()); }
3028
3029 template<typename _UniformRandomNumberGenerator>
3030 result_type
3031 operator()(_UniformRandomNumberGenerator& __urng,
3032 const param_type& __p);
3033
7b93bdde
UD
3034 template<typename _ForwardIterator,
3035 typename _UniformRandomNumberGenerator>
3036 void
3037 __generate(_ForwardIterator __f, _ForwardIterator __t,
3038 _UniformRandomNumberGenerator& __urng)
3039 { this->__generate(__f, __t, __urng, this->param()); }
3040
3041 template<typename _ForwardIterator,
3042 typename _UniformRandomNumberGenerator>
3043 void
3044 __generate(_ForwardIterator __f, _ForwardIterator __t,
3045 _UniformRandomNumberGenerator& __urng,
3046 const param_type& __p)
3047 { this->__generate_impl(__f, __t, __urng, __p); }
3048
3049 template<typename _UniformRandomNumberGenerator>
3050 void
3051 __generate(result_type* __f, result_type* __t,
3052 _UniformRandomNumberGenerator& __urng,
3053 const param_type& __p)
3054 { this->__generate_impl(__f, __t, __urng, __p); }
3055
8e79468d 3056 private:
7b93bdde
UD
3057 template<typename _ForwardIterator,
3058 typename _UniformRandomNumberGenerator>
3059 void
3060 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3061 _UniformRandomNumberGenerator& __urng,
3062 const param_type& __p);
3063
8e79468d
BK
3064 param_type _M_param;
3065 };
3066
fc05e1ba
PC
3067 /**
3068 * @brief Return true if two Cauchy distributions have
3069 * the same parameters.
3070 */
3071 template<typename _RealType>
3072 inline bool
3073 operator==(const std::cauchy_distribution<_RealType>& __d1,
3074 const std::cauchy_distribution<_RealType>& __d2)
3075 { return __d1.param() == __d2.param(); }
3076
3077 /**
3078 * @brief Return true if two Cauchy distributions have
3079 * different parameters.
3080 */
3081 template<typename _RealType>
3082 inline bool
3083 operator!=(const std::cauchy_distribution<_RealType>& __d1,
3084 const std::cauchy_distribution<_RealType>& __d2)
3085 { return !(__d1 == __d2); }
3086
8e79468d
BK
3087 /**
3088 * @brief Inserts a %cauchy_distribution random number distribution
3089 * @p __x into the output stream @p __os.
3090 *
3091 * @param __os An output stream.
3092 * @param __x A %cauchy_distribution random number distribution.
3093 *
3094 * @returns The output stream with the state of @p __x inserted or in
3095 * an error state.
3096 */
3097 template<typename _RealType, typename _CharT, typename _Traits>
3098 std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
3099 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3100 const std::cauchy_distribution<_RealType>& __x);
8e79468d
BK
3101
3102 /**
3103 * @brief Extracts a %cauchy_distribution random number distribution
3104 * @p __x from the input stream @p __is.
3105 *
3106 * @param __is An input stream.
3107 * @param __x A %cauchy_distribution random number
3108 * generator engine.
3109 *
3110 * @returns The input stream with @p __x extracted or in an error state.
3111 */
3112 template<typename _RealType, typename _CharT, typename _Traits>
3113 std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
3114 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3115 std::cauchy_distribution<_RealType>& __x);
8e79468d
BK
3116
3117
3118 /**
3119 * @brief A fisher_f_distribution random number distribution.
3120 *
3121 * The formula for the normal probability mass function is
6cc5a790
BK
3122 * @f[
3123 * p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
04b70271 3124 * (\frac{m}{n})^{m/2} x^{(m/2)-1}
6cc5a790
BK
3125 * (1 + \frac{mx}{n})^{-(m+n)/2}
3126 * @f]
8e79468d
BK
3127 */
3128 template<typename _RealType = double>
3129 class fisher_f_distribution
3130 {
77e3c516
PC
3131 static_assert(std::is_floating_point<_RealType>::value,
3132 "template argument not a floating point type");
3133
8e79468d
BK
3134 public:
3135 /** The type of the range of the distribution. */
3136 typedef _RealType result_type;
3137 /** Parameter type. */
3138 struct param_type
3139 {
3140 typedef fisher_f_distribution<_RealType> distribution_type;
3141
3142 explicit
3143 param_type(_RealType __m = _RealType(1),
3144 _RealType __n = _RealType(1))
3145 : _M_m(__m), _M_n(__n)
3146 { }
3147
3148 _RealType
3149 m() const
3150 { return _M_m; }
3151
3152 _RealType
3153 n() const
3154 { return _M_n; }
3155
fc05e1ba
PC
3156 friend bool
3157 operator==(const param_type& __p1, const param_type& __p2)
3158 { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
3159
8e79468d
BK
3160 private:
3161 _RealType _M_m;
3162 _RealType _M_n;
3163 };
3164
3165 explicit
3166 fisher_f_distribution(_RealType __m = _RealType(1),
3167 _RealType __n = _RealType(1))
f9b09dec 3168 : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
8e79468d
BK
3169 { }
3170
3171 explicit
3172 fisher_f_distribution(const param_type& __p)
f9b09dec 3173 : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
8e79468d
BK
3174 { }
3175
3176 /**
3177 * @brief Resets the distribution state.
3178 */
3179 void
3180 reset()
f9b09dec
PC
3181 {
3182 _M_gd_x.reset();
3183 _M_gd_y.reset();
3184 }
8e79468d
BK
3185
3186 /**
3187 *
3188 */
3189 _RealType
3190 m() const
3191 { return _M_param.m(); }
3192
3193 _RealType
3194 n() const
3195 { return _M_param.n(); }
3196
3197 /**
3198 * @brief Returns the parameter set of the distribution.
3199 */
3200 param_type
3201 param() const
3202 { return _M_param; }
3203
3204 /**
3205 * @brief Sets the parameter set of the distribution.
3206 * @param __param The new parameter set of the distribution.
3207 */
3208 void
3209 param(const param_type& __param)
3210 { _M_param = __param; }
3211
3212 /**
3213 * @brief Returns the greatest lower bound value of the distribution.
3214 */
3215 result_type
3216 min() const
3217 { return result_type(0); }
3218
3219 /**
3220 * @brief Returns the least upper bound value of the distribution.
3221 */
3222 result_type
3223 max() const
3224 { return std::numeric_limits<result_type>::max(); }
3225
247d8075
PC
3226 /**
3227 * @brief Generating functions.
3228 */
8e79468d
BK
3229 template<typename _UniformRandomNumberGenerator>
3230 result_type
3231 operator()(_UniformRandomNumberGenerator& __urng)
f9b09dec 3232 { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
8e79468d
BK
3233
3234 template<typename _UniformRandomNumberGenerator>
3235 result_type
3236 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
3237 const param_type& __p)
3238 {
3239 typedef typename std::gamma_distribution<result_type>::param_type
3240 param_type;
3241 return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
3242 / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
3243 }
8e79468d 3244
7b93bdde
UD
3245 template<typename _ForwardIterator,
3246 typename _UniformRandomNumberGenerator>
3247 void
3248 __generate(_ForwardIterator __f, _ForwardIterator __t,
3249 _UniformRandomNumberGenerator& __urng)
3250 { this->__generate_impl(__f, __t, __urng); }
3251
3252 template<typename _ForwardIterator,
3253 typename _UniformRandomNumberGenerator>
3254 void
3255 __generate(_ForwardIterator __f, _ForwardIterator __t,
3256 _UniformRandomNumberGenerator& __urng,
3257 const param_type& __p)
3258 { this->__generate_impl(__f, __t, __urng, __p); }
3259
3260 template<typename _UniformRandomNumberGenerator>
3261 void
3262 __generate(result_type* __f, result_type* __t,
3263 _UniformRandomNumberGenerator& __urng)
3264 { this->__generate_impl(__f, __t, __urng); }
3265
3266 template<typename _UniformRandomNumberGenerator>
3267 void
3268 __generate(result_type* __f, result_type* __t,
3269 _UniformRandomNumberGenerator& __urng,
3270 const param_type& __p)
3271 { this->__generate_impl(__f, __t, __urng, __p); }
3272
fc05e1ba
PC
3273 /**
3274 * @brief Return true if two Fisher f distributions have
3275 * the same parameters and the sequences that would
3276 * be generated are equal.
3277 */
a30e18c1
MG
3278 friend bool
3279 operator==(const fisher_f_distribution& __d1,
3280 const fisher_f_distribution& __d2)
3281 { return (__d1.param() == __d2.param()
3282 && __d1._M_gd_x == __d2._M_gd_x
3283 && __d1._M_gd_y == __d2._M_gd_y); }
fc05e1ba 3284
e1923769
ESR
3285 /**
3286 * @brief Inserts a %fisher_f_distribution random number distribution
3287 * @p __x into the output stream @p __os.
3288 *
3289 * @param __os An output stream.
3290 * @param __x A %fisher_f_distribution random number distribution.
3291 *
3292 * @returns The output stream with the state of @p __x inserted or in
3293 * an error state.
3294 */
3295 template<typename _RealType1, typename _CharT, typename _Traits>
3296 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
3297 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3298 const std::fisher_f_distribution<_RealType1>& __x);
e1923769
ESR
3299
3300 /**
3301 * @brief Extracts a %fisher_f_distribution random number distribution
3302 * @p __x from the input stream @p __is.
3303 *
3304 * @param __is An input stream.
3305 * @param __x A %fisher_f_distribution random number
3306 * generator engine.
3307 *
3308 * @returns The input stream with @p __x extracted or in an error state.
3309 */
3310 template<typename _RealType1, typename _CharT, typename _Traits>
3311 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
3312 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3313 std::fisher_f_distribution<_RealType1>& __x);
e1923769 3314
8e79468d 3315 private:
7b93bdde
UD
3316 template<typename _ForwardIterator,
3317 typename _UniformRandomNumberGenerator>
3318 void
3319 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3320 _UniformRandomNumberGenerator& __urng);
3321
3322 template<typename _ForwardIterator,
3323 typename _UniformRandomNumberGenerator>
3324 void
3325 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3326 _UniformRandomNumberGenerator& __urng,
3327 const param_type& __p);
3328
8e79468d 3329 param_type _M_param;
f9b09dec
PC
3330
3331 std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
8e79468d
BK
3332 };
3333
fc05e1ba
PC
3334 /**
3335 * @brief Return true if two Fisher f distributions are diferent.
3336 */
3337 template<typename _RealType>
3338 inline bool
3339 operator!=(const std::fisher_f_distribution<_RealType>& __d1,
3340 const std::fisher_f_distribution<_RealType>& __d2)
3341 { return !(__d1 == __d2); }
8e79468d
BK
3342
3343 /**
3344 * @brief A student_t_distribution random number distribution.
3345 *
6cc5a790
BK
3346 * The formula for the normal probability mass function is:
3347 * @f[
3348 * p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
3349 * (1 + \frac{x^2}{n}) ^{-(n+1)/2}
3350 * @f]
8e79468d
BK
3351 */
3352 template<typename _RealType = double>
3353 class student_t_distribution
3354 {
77e3c516
PC
3355 static_assert(std::is_floating_point<_RealType>::value,
3356 "template argument not a floating point type");
3357
8e79468d
BK
3358 public:
3359 /** The type of the range of the distribution. */
3360 typedef _RealType result_type;
3361 /** Parameter type. */
3362 struct param_type
3363 {
3364 typedef student_t_distribution<_RealType> distribution_type;
3365
3366 explicit
3367 param_type(_RealType __n = _RealType(1))
3368 : _M_n(__n)
3369 { }
3370
3371 _RealType
3372 n() const
3373 { return _M_n; }
3374
fc05e1ba
PC
3375 friend bool
3376 operator==(const param_type& __p1, const param_type& __p2)
3377 { return __p1._M_n == __p2._M_n; }
3378
8e79468d
BK
3379 private:
3380 _RealType _M_n;
3381 };
3382
3383 explicit
3384 student_t_distribution(_RealType __n = _RealType(1))
f9b09dec 3385 : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
8e79468d
BK
3386 { }
3387
3388 explicit
3389 student_t_distribution(const param_type& __p)
f9b09dec 3390 : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
8e79468d
BK
3391 { }
3392
3393 /**
3394 * @brief Resets the distribution state.
3395 */
3396 void
3397 reset()
f9b09dec
PC
3398 {
3399 _M_nd.reset();
3400 _M_gd.reset();
3401 }
8e79468d
BK
3402
3403 /**
3404 *
3405 */
3406 _RealType
3407 n() const
3408 { return _M_param.n(); }
3409
3410 /**
3411 * @brief Returns the parameter set of the distribution.
3412 */
3413 param_type
3414 param() const
3415 { return _M_param; }
3416
3417 /**
3418 * @brief Sets the parameter set of the distribution.
3419 * @param __param The new parameter set of the distribution.
3420 */
3421 void
3422 param(const param_type& __param)
3423 { _M_param = __param; }
3424
3425 /**
3426 * @brief Returns the greatest lower bound value of the distribution.
3427 */
3428 result_type
3429 min() const
3430 { return std::numeric_limits<result_type>::min(); }
3431
3432 /**
3433 * @brief Returns the least upper bound value of the distribution.
3434 */
3435 result_type
3436 max() const
3437 { return std::numeric_limits<result_type>::max(); }
3438
247d8075
PC
3439 /**
3440 * @brief Generating functions.
3441 */
8e79468d
BK
3442 template<typename _UniformRandomNumberGenerator>
3443 result_type
f9b09dec
PC
3444 operator()(_UniformRandomNumberGenerator& __urng)
3445 { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
8e79468d
BK
3446
3447 template<typename _UniformRandomNumberGenerator>
3448 result_type
3449 operator()(_UniformRandomNumberGenerator& __urng,
f9b09dec
PC
3450 const param_type& __p)
3451 {
3452 typedef typename std::gamma_distribution<result_type>::param_type
3453 param_type;
3454
3455 const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
3456 return _M_nd(__urng) * std::sqrt(__p.n() / __g);
3457 }
8e79468d 3458
7b93bdde
UD
3459 template<typename _ForwardIterator,
3460 typename _UniformRandomNumberGenerator>
3461 void
3462 __generate(_ForwardIterator __f, _ForwardIterator __t,
3463 _UniformRandomNumberGenerator& __urng)
3464 { this->__generate_impl(__f, __t, __urng); }
3465
3466 template<typename _ForwardIterator,
3467 typename _UniformRandomNumberGenerator>
3468 void
3469 __generate(_ForwardIterator __f, _ForwardIterator __t,
3470 _UniformRandomNumberGenerator& __urng,
3471 const param_type& __p)
3472 { this->__generate_impl(__f, __t, __urng, __p); }
3473
3474 template<typename _UniformRandomNumberGenerator>
3475 void
3476 __generate(result_type* __f, result_type* __t,
3477 _UniformRandomNumberGenerator& __urng)
3478 { this->__generate_impl(__f, __t, __urng); }
3479
3480 template<typename _UniformRandomNumberGenerator>
3481 void
3482 __generate(result_type* __f, result_type* __t,
3483 _UniformRandomNumberGenerator& __urng,
3484 const param_type& __p)
3485 { this->__generate_impl(__f, __t, __urng, __p); }
3486
fc05e1ba
PC
3487 /**
3488 * @brief Return true if two Student t distributions have
3489 * the same parameters and the sequences that would
3490 * be generated are equal.
3491 */
a30e18c1
MG
3492 friend bool
3493 operator==(const student_t_distribution& __d1,
3494 const student_t_distribution& __d2)
3495 { return (__d1.param() == __d2.param()
3496 && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
fc05e1ba 3497
e1923769
ESR
3498 /**
3499 * @brief Inserts a %student_t_distribution random number distribution
3500 * @p __x into the output stream @p __os.
3501 *
3502 * @param __os An output stream.
3503 * @param __x A %student_t_distribution random number distribution.
3504 *
3505 * @returns The output stream with the state of @p __x inserted or in
3506 * an error state.
3507 */
3508 template<typename _RealType1, typename _CharT, typename _Traits>
3509 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
3510 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3511 const std::student_t_distribution<_RealType1>& __x);
e1923769
ESR
3512
3513 /**
3514 * @brief Extracts a %student_t_distribution random number distribution
3515 * @p __x from the input stream @p __is.
3516 *
3517 * @param __is An input stream.
3518 * @param __x A %student_t_distribution random number
3519 * generator engine.
3520 *
3521 * @returns The input stream with @p __x extracted or in an error state.
3522 */
3523 template<typename _RealType1, typename _CharT, typename _Traits>
3524 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
3525 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3526 std::student_t_distribution<_RealType1>& __x);
e1923769 3527
8e79468d 3528 private:
7b93bdde
UD
3529 template<typename _ForwardIterator,
3530 typename _UniformRandomNumberGenerator>
3531 void
3532 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3533 _UniformRandomNumberGenerator& __urng);
3534 template<typename _ForwardIterator,
3535 typename _UniformRandomNumberGenerator>
3536 void
3537 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3538 _UniformRandomNumberGenerator& __urng,
3539 const param_type& __p);
3540
8e79468d 3541 param_type _M_param;
b01630bb 3542
f9b09dec
PC
3543 std::normal_distribution<result_type> _M_nd;
3544 std::gamma_distribution<result_type> _M_gd;
8e79468d
BK
3545 };
3546
fc05e1ba
PC
3547 /**
3548 * @brief Return true if two Student t distributions are different.
3549 */
3550 template<typename _RealType>
3551 inline bool
3552 operator!=(const std::student_t_distribution<_RealType>& __d1,
3553 const std::student_t_distribution<_RealType>& __d2)
3554 { return !(__d1 == __d2); }
3555
3556
037181bc 3557 /* @} */ // group random_distributions_normal
8e79468d
BK
3558
3559 /**
94a86be0 3560 * @addtogroup random_distributions_bernoulli Bernoulli Distributions
037181bc 3561 * @ingroup random_distributions
8e79468d
BK
3562 * @{
3563 */
3564
3565 /**
3566 * @brief A Bernoulli random number distribution.
3567 *
6cc5a790
BK
3568 * Generates a sequence of true and false values with likelihood @f$p@f$
3569 * that true will come up and @f$(1 - p)@f$ that false will appear.
8e79468d
BK
3570 */
3571 class bernoulli_distribution
3572 {
3573 public:
3574 /** The type of the range of the distribution. */
3575 typedef bool result_type;
3576 /** Parameter type. */
3577 struct param_type
3578 {
3579 typedef bernoulli_distribution distribution_type;
3580
3581 explicit
3582 param_type(double __p = 0.5)
3583 : _M_p(__p)
3584 {
3585 _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
3586 }
3587
3588 double
3589 p() const
3590 { return _M_p; }
3591
fc05e1ba
PC
3592 friend bool
3593 operator==(const param_type& __p1, const param_type& __p2)
3594 { return __p1._M_p == __p2._M_p; }
3595
8e79468d
BK
3596 private:
3597 double _M_p;
3598 };
3599
3600 public:
3601 /**
3602 * @brief Constructs a Bernoulli distribution with likelihood @p p.
3603 *
3604 * @param __p [IN] The likelihood of a true result being returned.
6cc5a790 3605 * Must be in the interval @f$[0, 1]@f$.
8e79468d
BK
3606 */
3607 explicit
3608 bernoulli_distribution(double __p = 0.5)
3609 : _M_param(__p)
3610 { }
3611
3612 explicit
3613 bernoulli_distribution(const param_type& __p)
3614 : _M_param(__p)
3615 { }
3616
3617 /**
3618 * @brief Resets the distribution state.
3619 *
3620 * Does nothing for a Bernoulli distribution.
3621 */
3622 void
3623 reset() { }
3624
3625 /**
3626 * @brief Returns the @p p parameter of the distribution.
3627 */
3628 double
3629 p() const
3630 { return _M_param.p(); }
3631
3632 /**
3633 * @brief Returns the parameter set of the distribution.
3634 */
3635 param_type
3636 param() const
3637 { return _M_param; }
3638
3639 /**
3640 * @brief Sets the parameter set of the distribution.
3641 * @param __param The new parameter set of the distribution.
3642 */
3643 void
3644 param(const param_type& __param)
3645 { _M_param = __param; }
3646
3647 /**
3648 * @brief Returns the greatest lower bound value of the distribution.
3649 */
3650 result_type
3651 min() const
3652 { return std::numeric_limits<result_type>::min(); }
3653
3654 /**
3655 * @brief Returns the least upper bound value of the distribution.
3656 */
3657 result_type
3658 max() const
3659 { return std::numeric_limits<result_type>::max(); }
3660
3661 /**
247d8075 3662 * @brief Generating functions.
8e79468d
BK
3663 */
3664 template<typename _UniformRandomNumberGenerator>
3665 result_type
3666 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 3667 { return this->operator()(__urng, this->param()); }
8e79468d
BK
3668
3669 template<typename _UniformRandomNumberGenerator>
3670 result_type
3671 operator()(_UniformRandomNumberGenerator& __urng,
3672 const param_type& __p)
3673 {
3674 __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3675 __aurng(__urng);
3676 if ((__aurng() - __aurng.min())
3677 < __p.p() * (__aurng.max() - __aurng.min()))
3678 return true;
3679 return false;
3680 }
3681
7b93bdde
UD
3682 template<typename _ForwardIterator,
3683 typename _UniformRandomNumberGenerator>
3684 void
3685 __generate(_ForwardIterator __f, _ForwardIterator __t,
3686 _UniformRandomNumberGenerator& __urng)
3687 { this->__generate(__f, __t, __urng, this->param()); }
3688
3689 template<typename _ForwardIterator,
3690 typename _UniformRandomNumberGenerator>
3691 void
3692 __generate(_ForwardIterator __f, _ForwardIterator __t,
3693 _UniformRandomNumberGenerator& __urng, const param_type& __p)
3694 { this->__generate_impl(__f, __t, __urng, __p); }
3695
3696 template<typename _UniformRandomNumberGenerator>
3697 void
3698 __generate(result_type* __f, result_type* __t,
3699 _UniformRandomNumberGenerator& __urng,
3700 const param_type& __p)
3701 { this->__generate_impl(__f, __t, __urng, __p); }
3702
8e79468d 3703 private:
7b93bdde
UD
3704 template<typename _ForwardIterator,
3705 typename _UniformRandomNumberGenerator>
3706 void
3707 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3708 _UniformRandomNumberGenerator& __urng,
3709 const param_type& __p);
3710
8e79468d
BK
3711 param_type _M_param;
3712 };
3713
fc05e1ba
PC
3714 /**
3715 * @brief Return true if two Bernoulli distributions have
3716 * the same parameters.
3717 */
3718 inline bool
3719 operator==(const std::bernoulli_distribution& __d1,
3720 const std::bernoulli_distribution& __d2)
3721 { return __d1.param() == __d2.param(); }
3722
3723 /**
3724 * @brief Return true if two Bernoulli distributions have
3725 * different parameters.
3726 */
3727 inline bool
3728 operator!=(const std::bernoulli_distribution& __d1,
3729 const std::bernoulli_distribution& __d2)
3730 { return !(__d1 == __d2); }
3731
8e79468d
BK
3732 /**
3733 * @brief Inserts a %bernoulli_distribution random number distribution
3734 * @p __x into the output stream @p __os.
3735 *
3736 * @param __os An output stream.
3737 * @param __x A %bernoulli_distribution random number distribution.
3738 *
3739 * @returns The output stream with the state of @p __x inserted or in
3740 * an error state.
3741 */
3742 template<typename _CharT, typename _Traits>
3743 std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
3744 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3745 const std::bernoulli_distribution& __x);
8e79468d
BK
3746
3747 /**
3748 * @brief Extracts a %bernoulli_distribution random number distribution
3749 * @p __x from the input stream @p __is.
3750 *
3751 * @param __is An input stream.
3752 * @param __x A %bernoulli_distribution random number generator engine.
3753 *
3754 * @returns The input stream with @p __x extracted or in an error state.
3755 */
3756 template<typename _CharT, typename _Traits>
3757 std::basic_istream<_CharT, _Traits>&
3758 operator>>(std::basic_istream<_CharT, _Traits>& __is,
94986f6d 3759 std::bernoulli_distribution& __x)
8e79468d
BK
3760 {
3761 double __p;
3762 __is >> __p;
3763 __x.param(bernoulli_distribution::param_type(__p));
3764 return __is;
3765 }
3766
3767
3768 /**
3769 * @brief A discrete binomial random number distribution.
3770 *
3771 * The formula for the binomial probability density function is
6cc5a790
BK
3772 * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3773 * and @f$p@f$ are the parameters of the distribution.
8e79468d
BK
3774 */
3775 template<typename _IntType = int>
3776 class binomial_distribution
3777 {
77e3c516
PC
3778 static_assert(std::is_integral<_IntType>::value,
3779 "template argument not an integral type");
8e79468d
BK
3780
3781 public:
3782 /** The type of the range of the distribution. */
3783 typedef _IntType result_type;
3784 /** Parameter type. */
3785 struct param_type
3786 {
3787 typedef binomial_distribution<_IntType> distribution_type;
3788 friend class binomial_distribution<_IntType>;
3789
3790 explicit
3791 param_type(_IntType __t = _IntType(1), double __p = 0.5)
3792 : _M_t(__t), _M_p(__p)
3793 {
3794 _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
94986f6d
PC
3795 && (_M_p >= 0.0)
3796 && (_M_p <= 1.0));
8e79468d
BK
3797 _M_initialize();
3798 }
3799
3800 _IntType
3801 t() const
3802 { return _M_t; }
3803
3804 double
3805 p() const
3806 { return _M_p; }
3807
fc05e1ba
PC
3808 friend bool
3809 operator==(const param_type& __p1, const param_type& __p2)
3810 { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
3811
8e79468d
BK
3812 private:
3813 void
3814 _M_initialize();
3815
3816 _IntType _M_t;
3817 double _M_p;
3818
3819 double _M_q;
3820#if _GLIBCXX_USE_C99_MATH_TR1
3821 double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
3822 _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
3823#endif
3824 bool _M_easy;
3825 };
3826
3827 // constructors and member function
3828 explicit
3829 binomial_distribution(_IntType __t = _IntType(1),
3830 double __p = 0.5)
3831 : _M_param(__t, __p), _M_nd()
3832 { }
3833
3834 explicit
3835 binomial_distribution(const param_type& __p)
3836 : _M_param(__p), _M_nd()
3837 { }
3838
3839 /**
3840 * @brief Resets the distribution state.
3841 */
3842 void
3843 reset()
3844 { _M_nd.reset(); }
3845
3846 /**
3847 * @brief Returns the distribution @p t parameter.
3848 */
3849 _IntType
3850 t() const
3851 { return _M_param.t(); }
3852
3853 /**
3854 * @brief Returns the distribution @p p parameter.
3855 */
3856 double
3857 p() const
3858 { return _M_param.p(); }
3859
3860 /**
3861 * @brief Returns the parameter set of the distribution.
3862 */
3863 param_type
3864 param() const
3865 { return _M_param; }
3866
3867 /**
3868 * @brief Sets the parameter set of the distribution.
3869 * @param __param The new parameter set of the distribution.
3870 */
3871 void
3872 param(const param_type& __param)
3873 { _M_param = __param; }
3874
3875 /**
3876 * @brief Returns the greatest lower bound value of the distribution.
3877 */
3878 result_type
3879 min() const
3880 { return 0; }
3881
3882 /**
3883 * @brief Returns the least upper bound value of the distribution.
3884 */
3885 result_type
3886 max() const
3887 { return _M_param.t(); }
3888
247d8075
PC
3889 /**
3890 * @brief Generating functions.
3891 */
3892 template<typename _UniformRandomNumberGenerator>
3893 result_type
3894 operator()(_UniformRandomNumberGenerator& __urng)
3895 { return this->operator()(__urng, this->param()); }
3896
3897 template<typename _UniformRandomNumberGenerator>
3898 result_type
3899 operator()(_UniformRandomNumberGenerator& __urng,
3900 const param_type& __p);
3901
7b93bdde
UD
3902 template<typename _ForwardIterator,
3903 typename _UniformRandomNumberGenerator>
3904 void
3905 __generate(_ForwardIterator __f, _ForwardIterator __t,
3906 _UniformRandomNumberGenerator& __urng)
3907 { this->__generate(__f, __t, __urng, this->param()); }
3908
3909 template<typename _ForwardIterator,
3910 typename _UniformRandomNumberGenerator>
3911 void
3912 __generate(_ForwardIterator __f, _ForwardIterator __t,
3913 _UniformRandomNumberGenerator& __urng,
3914 const param_type& __p)
3915 { this->__generate_impl(__f, __t, __urng, __p); }
3916
3917 template<typename _UniformRandomNumberGenerator>
3918 void
3919 __generate(result_type* __f, result_type* __t,
3920 _UniformRandomNumberGenerator& __urng,
3921 const param_type& __p)
3922 { this->__generate_impl(__f, __t, __urng, __p); }
3923
fc05e1ba
PC
3924 /**
3925 * @brief Return true if two binomial distributions have
3926 * the same parameters and the sequences that would
3927 * be generated are equal.
3928 */
fc05e1ba 3929 friend bool
a30e18c1
MG
3930 operator==(const binomial_distribution& __d1,
3931 const binomial_distribution& __d2)
fc05e1ba
PC
3932#ifdef _GLIBCXX_USE_C99_MATH_TR1
3933 { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
3934#else
3935 { return __d1.param() == __d2.param(); }
3936#endif
3937
8e79468d
BK
3938 /**
3939 * @brief Inserts a %binomial_distribution random number distribution
3940 * @p __x into the output stream @p __os.
3941 *
3942 * @param __os An output stream.
3943 * @param __x A %binomial_distribution random number distribution.
3944 *
3945 * @returns The output stream with the state of @p __x inserted or in
3946 * an error state.
3947 */
3948 template<typename _IntType1,
3949 typename _CharT, typename _Traits>
3950 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
3951 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3952 const std::binomial_distribution<_IntType1>& __x);
8e79468d
BK
3953
3954 /**
3955 * @brief Extracts a %binomial_distribution random number distribution
3956 * @p __x from the input stream @p __is.
3957 *
3958 * @param __is An input stream.
3959 * @param __x A %binomial_distribution random number generator engine.
3960 *
3961 * @returns The input stream with @p __x extracted or in an error
3962 * state.
3963 */
3964 template<typename _IntType1,
3965 typename _CharT, typename _Traits>
3966 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
3967 operator>>(std::basic_istream<_CharT, _Traits>& __is,
3968 std::binomial_distribution<_IntType1>& __x);
8e79468d
BK
3969
3970 private:
7b93bdde
UD
3971 template<typename _ForwardIterator,
3972 typename _UniformRandomNumberGenerator>
3973 void
3974 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3975 _UniformRandomNumberGenerator& __urng,
3976 const param_type& __p);
3977
8e79468d
BK
3978 template<typename _UniformRandomNumberGenerator>
3979 result_type
3980 _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
3981
3982 param_type _M_param;
3983
3984 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
f9b09dec 3985 std::normal_distribution<double> _M_nd;
8e79468d
BK
3986 };
3987
fc05e1ba
PC
3988 /**
3989 * @brief Return true if two binomial distributions are different.
3990 */
3991 template<typename _IntType>
3992 inline bool
3993 operator!=(const std::binomial_distribution<_IntType>& __d1,
3994 const std::binomial_distribution<_IntType>& __d2)
3995 { return !(__d1 == __d2); }
3996
8e79468d
BK
3997
3998 /**
3999 * @brief A discrete geometric random number distribution.
4000 *
4001 * The formula for the geometric probability density function is
d8d4db33 4002 * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
8e79468d
BK
4003 * distribution.
4004 */
4005 template<typename _IntType = int>
4006 class geometric_distribution
4007 {
77e3c516
PC
4008 static_assert(std::is_integral<_IntType>::value,
4009 "template argument not an integral type");
8e79468d
BK
4010
4011 public:
4012 /** The type of the range of the distribution. */
4013 typedef _IntType result_type;
4014 /** Parameter type. */
4015 struct param_type
4016 {
4017 typedef geometric_distribution<_IntType> distribution_type;
4018 friend class geometric_distribution<_IntType>;
4019
4020 explicit
4021 param_type(double __p = 0.5)
4022 : _M_p(__p)
4023 {
113b21bd 4024 _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
8e79468d
BK
4025 _M_initialize();
4026 }
4027
4028 double
4029 p() const
4030 { return _M_p; }
4031
fc05e1ba
PC
4032 friend bool
4033 operator==(const param_type& __p1, const param_type& __p2)
4034 { return __p1._M_p == __p2._M_p; }
4035
8e79468d
BK
4036 private:
4037 void
4038 _M_initialize()
d8d4db33 4039 { _M_log_1_p = std::log(1.0 - _M_p); }
8e79468d
BK
4040
4041 double _M_p;
4042
d8d4db33 4043 double _M_log_1_p;
8e79468d
BK
4044 };
4045
4046 // constructors and member function
4047 explicit
4048 geometric_distribution(double __p = 0.5)
4049 : _M_param(__p)
4050 { }
4051
4052 explicit
4053 geometric_distribution(const param_type& __p)
4054 : _M_param(__p)
4055 { }
4056
4057 /**
4058 * @brief Resets the distribution state.
4059 *
4060 * Does nothing for the geometric distribution.
4061 */
4062 void
4063 reset() { }
4064
4065 /**
4066 * @brief Returns the distribution parameter @p p.
4067 */
4068 double
4069 p() const
4070 { return _M_param.p(); }
4071
4072 /**
4073 * @brief Returns the parameter set of the distribution.
4074 */
4075 param_type
4076 param() const
4077 { return _M_param; }
4078
4079 /**
4080 * @brief Sets the parameter set of the distribution.
4081 * @param __param The new parameter set of the distribution.
4082 */
4083 void
4084 param(const param_type& __param)
4085 { _M_param = __param; }
4086
4087 /**
4088 * @brief Returns the greatest lower bound value of the distribution.
4089 */
4090 result_type
4091 min() const
4092 { return 0; }
4093
4094 /**
4095 * @brief Returns the least upper bound value of the distribution.
4096 */
4097 result_type
4098 max() const
4099 { return std::numeric_limits<result_type>::max(); }
4100
247d8075
PC
4101 /**
4102 * @brief Generating functions.
4103 */
8e79468d
BK
4104 template<typename _UniformRandomNumberGenerator>
4105 result_type
4106 operator()(_UniformRandomNumberGenerator& __urng)
4107 { return this->operator()(__urng, this->param()); }
4108
4109 template<typename _UniformRandomNumberGenerator>
4110 result_type
4111 operator()(_UniformRandomNumberGenerator& __urng,
4112 const param_type& __p);
4113
7b93bdde
UD
4114 template<typename _ForwardIterator,
4115 typename _UniformRandomNumberGenerator>
4116 void
4117 __generate(_ForwardIterator __f, _ForwardIterator __t,
4118 _UniformRandomNumberGenerator& __urng)
4119 { this->__generate(__f, __t, __urng, this->param()); }
4120
4121 template<typename _ForwardIterator,
4122 typename _UniformRandomNumberGenerator>
4123 void
4124 __generate(_ForwardIterator __f, _ForwardIterator __t,
4125 _UniformRandomNumberGenerator& __urng,
4126 const param_type& __p)
4127 { this->__generate_impl(__f, __t, __urng, __p); }
4128
4129 template<typename _UniformRandomNumberGenerator>
4130 void
4131 __generate(result_type* __f, result_type* __t,
4132 _UniformRandomNumberGenerator& __urng,
4133 const param_type& __p)
4134 { this->__generate_impl(__f, __t, __urng, __p); }
4135
8e79468d 4136 private:
7b93bdde
UD
4137 template<typename _ForwardIterator,
4138 typename _UniformRandomNumberGenerator>
4139 void
4140 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4141 _UniformRandomNumberGenerator& __urng,
4142 const param_type& __p);
4143
8e79468d
BK
4144 param_type _M_param;
4145 };
4146
fc05e1ba
PC
4147 /**
4148 * @brief Return true if two geometric distributions have
4149 * the same parameters.
4150 */
4151 template<typename _IntType>
4152 inline bool
4153 operator==(const std::geometric_distribution<_IntType>& __d1,
4154 const std::geometric_distribution<_IntType>& __d2)
4155 { return __d1.param() == __d2.param(); }
4156
4157 /**
4158 * @brief Return true if two geometric distributions have
4159 * different parameters.
4160 */
4161 template<typename _IntType>
4162 inline bool
4163 operator!=(const std::geometric_distribution<_IntType>& __d1,
4164 const std::geometric_distribution<_IntType>& __d2)
4165 { return !(__d1 == __d2); }
4166
8e79468d
BK
4167 /**
4168 * @brief Inserts a %geometric_distribution random number distribution
4169 * @p __x into the output stream @p __os.
4170 *
4171 * @param __os An output stream.
4172 * @param __x A %geometric_distribution random number distribution.
4173 *
4174 * @returns The output stream with the state of @p __x inserted or in
4175 * an error state.
4176 */
4177 template<typename _IntType,
4178 typename _CharT, typename _Traits>
4179 std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
4180 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4181 const std::geometric_distribution<_IntType>& __x);
8e79468d
BK
4182
4183 /**
4184 * @brief Extracts a %geometric_distribution random number distribution
4185 * @p __x from the input stream @p __is.
4186 *
4187 * @param __is An input stream.
4188 * @param __x A %geometric_distribution random number generator engine.
4189 *
4190 * @returns The input stream with @p __x extracted or in an error state.
4191 */
4192 template<typename _IntType,
4193 typename _CharT, typename _Traits>
4194 std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
4195 operator>>(std::basic_istream<_CharT, _Traits>& __is,
4196 std::geometric_distribution<_IntType>& __x);
8e79468d
BK
4197
4198
4199 /**
4200 * @brief A negative_binomial_distribution random number distribution.
4201 *
4202 * The formula for the negative binomial probability mass function is
6cc5a790
BK
4203 * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
4204 * and @f$p@f$ are the parameters of the distribution.
8e79468d
BK
4205 */
4206 template<typename _IntType = int>
4207 class negative_binomial_distribution
4208 {
77e3c516
PC
4209 static_assert(std::is_integral<_IntType>::value,
4210 "template argument not an integral type");
8e79468d
BK
4211
4212 public:
4213 /** The type of the range of the distribution. */
4214 typedef _IntType result_type;
4215 /** Parameter type. */
4216 struct param_type
4217 {
4218 typedef negative_binomial_distribution<_IntType> distribution_type;
4219
4220 explicit
4221 param_type(_IntType __k = 1, double __p = 0.5)
4222 : _M_k(__k), _M_p(__p)
113b21bd
PC
4223 {
4224 _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
4225 }
8e79468d
BK
4226
4227 _IntType
4228 k() const
4229 { return _M_k; }
4230
4231 double
4232 p() const
4233 { return _M_p; }
4234
fc05e1ba
PC
4235 friend bool
4236 operator==(const param_type& __p1, const param_type& __p2)
4237 { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
4238
8e79468d
BK
4239 private:
4240 _IntType _M_k;
4241 double _M_p;
4242 };
4243
4244 explicit
4245 negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
ff2e697a 4246 : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
8e79468d
BK
4247 { }
4248
4249 explicit
4250 negative_binomial_distribution(const param_type& __p)
ff2e697a 4251 : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
8e79468d
BK
4252 { }
4253
4254 /**
4255 * @brief Resets the distribution state.
4256 */
4257 void
4258 reset()
f9b09dec 4259 { _M_gd.reset(); }
8e79468d
BK
4260
4261 /**
6cc5a790 4262 * @brief Return the @f$k@f$ parameter of the distribution.
8e79468d
BK
4263 */
4264 _IntType
4265 k() const
4266 { return _M_param.k(); }
4267
4268 /**
6cc5a790 4269 * @brief Return the @f$p@f$ parameter of the distribution.
8e79468d
BK
4270 */
4271 double
4272 p() const
4273 { return _M_param.p(); }
4274
4275 /**
4276 * @brief Returns the parameter set of the distribution.
4277 */
4278 param_type
4279 param() const
4280 { return _M_param; }
4281
4282 /**
4283 * @brief Sets the parameter set of the distribution.
4284 * @param __param The new parameter set of the distribution.
4285 */
4286 void
4287 param(const param_type& __param)
4288 { _M_param = __param; }
4289
4290 /**
4291 * @brief Returns the greatest lower bound value of the distribution.
4292 */
4293 result_type
4294 min() const
4295 { return result_type(0); }
4296
4297 /**
4298 * @brief Returns the least upper bound value of the distribution.
4299 */
4300 result_type
4301 max() const
4302 { return std::numeric_limits<result_type>::max(); }
4303
247d8075
PC
4304 /**
4305 * @brief Generating functions.
4306 */
8e79468d
BK
4307 template<typename _UniformRandomNumberGenerator>
4308 result_type
f9b09dec 4309 operator()(_UniformRandomNumberGenerator& __urng);
8e79468d
BK
4310
4311 template<typename _UniformRandomNumberGenerator>
4312 result_type
4313 operator()(_UniformRandomNumberGenerator& __urng,
4314 const param_type& __p);
4315
7b93bdde
UD
4316 template<typename _ForwardIterator,
4317 typename _UniformRandomNumberGenerator>
4318 void
4319 __generate(_ForwardIterator __f, _ForwardIterator __t,
4320 _UniformRandomNumberGenerator& __urng)
4321 { this->__generate_impl(__f, __t, __urng); }
4322
4323 template<typename _ForwardIterator,
4324 typename _UniformRandomNumberGenerator>
4325 void
4326 __generate(_ForwardIterator __f, _ForwardIterator __t,
4327 _UniformRandomNumberGenerator& __urng,
4328 const param_type& __p)
4329 { this->__generate_impl(__f, __t, __urng, __p); }
4330
4331 template<typename _UniformRandomNumberGenerator>
4332 void
4333 __generate(result_type* __f, result_type* __t,
4334 _UniformRandomNumberGenerator& __urng)
4335 { this->__generate_impl(__f, __t, __urng); }
4336
4337 template<typename _UniformRandomNumberGenerator>
4338 void
4339 __generate(result_type* __f, result_type* __t,
4340 _UniformRandomNumberGenerator& __urng,
4341 const param_type& __p)
4342 { this->__generate_impl(__f, __t, __urng, __p); }
4343
fc05e1ba
PC
4344 /**
4345 * @brief Return true if two negative binomial distributions have
4346 * the same parameters and the sequences that would be
4347 * generated are equal.
4348 */
a30e18c1
MG
4349 friend bool
4350 operator==(const negative_binomial_distribution& __d1,
4351 const negative_binomial_distribution& __d2)
4352 { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
fc05e1ba 4353
e1923769
ESR
4354 /**
4355 * @brief Inserts a %negative_binomial_distribution random
4356 * number distribution @p __x into the output stream @p __os.
4357 *
4358 * @param __os An output stream.
4359 * @param __x A %negative_binomial_distribution random number
4360 * distribution.
4361 *
4362 * @returns The output stream with the state of @p __x inserted or in
4363 * an error state.
4364 */
4365 template<typename _IntType1, typename _CharT, typename _Traits>
4366 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
4367 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4368 const std::negative_binomial_distribution<_IntType1>& __x);
e1923769
ESR
4369
4370 /**
4371 * @brief Extracts a %negative_binomial_distribution random number
4372 * distribution @p __x from the input stream @p __is.
4373 *
4374 * @param __is An input stream.
4375 * @param __x A %negative_binomial_distribution random number
4376 * generator engine.
4377 *
4378 * @returns The input stream with @p __x extracted or in an error state.
4379 */
4380 template<typename _IntType1, typename _CharT, typename _Traits>
4381 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
4382 operator>>(std::basic_istream<_CharT, _Traits>& __is,
4383 std::negative_binomial_distribution<_IntType1>& __x);
e1923769 4384
8e79468d 4385 private:
7b93bdde
UD
4386 template<typename _ForwardIterator,
4387 typename _UniformRandomNumberGenerator>
4388 void
4389 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4390 _UniformRandomNumberGenerator& __urng);
4391 template<typename _ForwardIterator,
4392 typename _UniformRandomNumberGenerator>
4393 void
4394 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4395 _UniformRandomNumberGenerator& __urng,
4396 const param_type& __p);
4397
8e79468d 4398 param_type _M_param;
f9b09dec
PC
4399
4400 std::gamma_distribution<double> _M_gd;
8e79468d
BK
4401 };
4402
fc05e1ba
PC
4403 /**
4404 * @brief Return true if two negative binomial distributions are different.
4405 */
4406 template<typename _IntType>
4407 inline bool
4408 operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
4409 const std::negative_binomial_distribution<_IntType>& __d2)
4410 { return !(__d1 == __d2); }
4411
4412
037181bc 4413 /* @} */ // group random_distributions_bernoulli
8e79468d
BK
4414
4415 /**
94a86be0 4416 * @addtogroup random_distributions_poisson Poisson Distributions
037181bc 4417 * @ingroup random_distributions
8e79468d
BK
4418 * @{
4419 */
4420
4421 /**
4422 * @brief A discrete Poisson random number distribution.
4423 *
4424 * The formula for the Poisson probability density function is
6cc5a790 4425 * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
8e79468d
BK
4426 * parameter of the distribution.
4427 */
4428 template<typename _IntType = int>
4429 class poisson_distribution
4430 {
77e3c516
PC
4431 static_assert(std::is_integral<_IntType>::value,
4432 "template argument not an integral type");
8e79468d
BK
4433
4434 public:
4435 /** The type of the range of the distribution. */
4436 typedef _IntType result_type;
4437 /** Parameter type. */
4438 struct param_type
4439 {
4440 typedef poisson_distribution<_IntType> distribution_type;
4441 friend class poisson_distribution<_IntType>;
4442
4443 explicit
4444 param_type(double __mean = 1.0)
4445 : _M_mean(__mean)
4446 {
4447 _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
4448 _M_initialize();
4449 }
4450
4451 double
4452 mean() const
4453 { return _M_mean; }
4454
fc05e1ba
PC
4455 friend bool
4456 operator==(const param_type& __p1, const param_type& __p2)
4457 { return __p1._M_mean == __p2._M_mean; }
4458
8e79468d
BK
4459 private:
4460 // Hosts either log(mean) or the threshold of the simple method.
4461 void
4462 _M_initialize();
4463
4464 double _M_mean;
4465
4466 double _M_lm_thr;
4467#if _GLIBCXX_USE_C99_MATH_TR1
4468 double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
4469#endif
4470 };
4471
4472 // constructors and member function
4473 explicit
4474 poisson_distribution(double __mean = 1.0)
4475 : _M_param(__mean), _M_nd()
4476 { }
4477
4478 explicit
4479 poisson_distribution(const param_type& __p)
4480 : _M_param(__p), _M_nd()
4481 { }
4482
4483 /**
4484 * @brief Resets the distribution state.
4485 */
4486 void
4487 reset()
4488 { _M_nd.reset(); }
4489
4490 /**
4491 * @brief Returns the distribution parameter @p mean.
4492 */
4493 double
4494 mean() const
4495 { return _M_param.mean(); }
4496
4497 /**
4498 * @brief Returns the parameter set of the distribution.
4499 */
4500 param_type
4501 param() const
4502 { return _M_param; }
4503
4504 /**
4505 * @brief Sets the parameter set of the distribution.
4506 * @param __param The new parameter set of the distribution.
4507 */
4508 void
4509 param(const param_type& __param)
4510 { _M_param = __param; }
4511
4512 /**
4513 * @brief Returns the greatest lower bound value of the distribution.
4514 */
4515 result_type
4516 min() const
4517 { return 0; }
4518
4519 /**
4520 * @brief Returns the least upper bound value of the distribution.
4521 */
4522 result_type
4523 max() const
4524 { return std::numeric_limits<result_type>::max(); }
4525
247d8075
PC
4526 /**
4527 * @brief Generating functions.
4528 */
8e79468d
BK
4529 template<typename _UniformRandomNumberGenerator>
4530 result_type
4531 operator()(_UniformRandomNumberGenerator& __urng)
4532 { return this->operator()(__urng, this->param()); }
4533
4534 template<typename _UniformRandomNumberGenerator>
4535 result_type
4536 operator()(_UniformRandomNumberGenerator& __urng,
4537 const param_type& __p);
4538
7b93bdde
UD
4539 template<typename _ForwardIterator,
4540 typename _UniformRandomNumberGenerator>
4541 void
4542 __generate(_ForwardIterator __f, _ForwardIterator __t,
4543 _UniformRandomNumberGenerator& __urng)
4544 { this->__generate(__f, __t, __urng, this->param()); }
4545
4546 template<typename _ForwardIterator,
4547 typename _UniformRandomNumberGenerator>
4548 void
4549 __generate(_ForwardIterator __f, _ForwardIterator __t,
4550 _UniformRandomNumberGenerator& __urng,
4551 const param_type& __p)
4552 { this->__generate_impl(__f, __t, __urng, __p); }
4553
4554 template<typename _UniformRandomNumberGenerator>
4555 void
4556 __generate(result_type* __f, result_type* __t,
4557 _UniformRandomNumberGenerator& __urng,
4558 const param_type& __p)
4559 { this->__generate_impl(__f, __t, __urng, __p); }
4560
fc05e1ba
PC
4561 /**
4562 * @brief Return true if two Poisson distributions have the same
4563 * parameters and the sequences that would be generated
4564 * are equal.
4565 */
a30e18c1
MG
4566 friend bool
4567 operator==(const poisson_distribution& __d1,
4568 const poisson_distribution& __d2)
fc05e1ba 4569#ifdef _GLIBCXX_USE_C99_MATH_TR1
a30e18c1 4570 { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
fc05e1ba 4571#else
a30e18c1 4572 { return __d1.param() == __d2.param(); }
fc05e1ba
PC
4573#endif
4574
8e79468d
BK
4575 /**
4576 * @brief Inserts a %poisson_distribution random number distribution
4577 * @p __x into the output stream @p __os.
4578 *
4579 * @param __os An output stream.
4580 * @param __x A %poisson_distribution random number distribution.
4581 *
4582 * @returns The output stream with the state of @p __x inserted or in
4583 * an error state.
4584 */
4585 template<typename _IntType1, typename _CharT, typename _Traits>
4586 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
4587 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4588 const std::poisson_distribution<_IntType1>& __x);
8e79468d
BK
4589
4590 /**
4591 * @brief Extracts a %poisson_distribution random number distribution
4592 * @p __x from the input stream @p __is.
4593 *
4594 * @param __is An input stream.
4595 * @param __x A %poisson_distribution random number generator engine.
4596 *
4597 * @returns The input stream with @p __x extracted or in an error
4598 * state.
4599 */
4600 template<typename _IntType1, typename _CharT, typename _Traits>
4601 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
4602 operator>>(std::basic_istream<_CharT, _Traits>& __is,
4603 std::poisson_distribution<_IntType1>& __x);
8e79468d
BK
4604
4605 private:
7b93bdde
UD
4606 template<typename _ForwardIterator,
4607 typename _UniformRandomNumberGenerator>
4608 void
4609 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4610 _UniformRandomNumberGenerator& __urng,
4611 const param_type& __p);
4612
8e79468d
BK
4613 param_type _M_param;
4614
4615 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
f9b09dec 4616 std::normal_distribution<double> _M_nd;
8e79468d
BK
4617 };
4618
fc05e1ba
PC
4619 /**
4620 * @brief Return true if two Poisson distributions are different.
4621 */
4622 template<typename _IntType>
4623 inline bool
4624 operator!=(const std::poisson_distribution<_IntType>& __d1,
4625 const std::poisson_distribution<_IntType>& __d2)
4626 { return !(__d1 == __d2); }
4627
4628
8e79468d
BK
4629 /**
4630 * @brief An exponential continuous distribution for random numbers.
4631 *
4632 * The formula for the exponential probability density function is
6cc5a790 4633 * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
8e79468d
BK
4634 *
4635 * <table border=1 cellpadding=10 cellspacing=0>
4636 * <caption align=top>Distribution Statistics</caption>
6cc5a790
BK
4637 * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4638 * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
4639 * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
8e79468d 4640 * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
6cc5a790 4641 * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
8e79468d
BK
4642 * </table>
4643 */
4644 template<typename _RealType = double>
4645 class exponential_distribution
4646 {
77e3c516
PC
4647 static_assert(std::is_floating_point<_RealType>::value,
4648 "template argument not a floating point type");
4649
8e79468d
BK
4650 public:
4651 /** The type of the range of the distribution. */
4652 typedef _RealType result_type;
4653 /** Parameter type. */
4654 struct param_type
4655 {
4656 typedef exponential_distribution<_RealType> distribution_type;
4657
4658 explicit
4659 param_type(_RealType __lambda = _RealType(1))
4660 : _M_lambda(__lambda)
4661 {
4662 _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
4663 }
4664
4665 _RealType
4666 lambda() const
4667 { return _M_lambda; }
4668
fc05e1ba
PC
4669 friend bool
4670 operator==(const param_type& __p1, const param_type& __p2)
4671 { return __p1._M_lambda == __p2._M_lambda; }
4672
8e79468d
BK
4673 private:
4674 _RealType _M_lambda;
4675 };
4676
4677 public:
4678 /**
4679 * @brief Constructs an exponential distribution with inverse scale
6cc5a790 4680 * parameter @f$\lambda@f$.
8e79468d
BK
4681 */
4682 explicit
4683 exponential_distribution(const result_type& __lambda = result_type(1))
4684 : _M_param(__lambda)
4685 { }
4686
4687 explicit
4688 exponential_distribution(const param_type& __p)
4689 : _M_param(__p)
4690 { }
4691
4692 /**
4693 * @brief Resets the distribution state.
4694 *
4695 * Has no effect on exponential distributions.
4696 */
4697 void
4698 reset() { }
4699
4700 /**
4701 * @brief Returns the inverse scale parameter of the distribution.
4702 */
4703 _RealType
4704 lambda() const
4705 { return _M_param.lambda(); }
4706
4707 /**
4708 * @brief Returns the parameter set of the distribution.
4709 */
4710 param_type
4711 param() const
4712 { return _M_param; }
4713
4714 /**
4715 * @brief Sets the parameter set of the distribution.
4716 * @param __param The new parameter set of the distribution.
4717 */
4718 void
4719 param(const param_type& __param)
4720 { _M_param = __param; }
4721
4722 /**
4723 * @brief Returns the greatest lower bound value of the distribution.
4724 */
4725 result_type
4726 min() const
4727 { return result_type(0); }
4728
4729 /**
4730 * @brief Returns the least upper bound value of the distribution.
4731 */
4732 result_type
4733 max() const
4734 { return std::numeric_limits<result_type>::max(); }
4735
247d8075
PC
4736 /**
4737 * @brief Generating functions.
4738 */
8e79468d
BK
4739 template<typename _UniformRandomNumberGenerator>
4740 result_type
4741 operator()(_UniformRandomNumberGenerator& __urng)
b01630bb 4742 { return this->operator()(__urng, this->param()); }
8e79468d
BK
4743
4744 template<typename _UniformRandomNumberGenerator>
4745 result_type
4746 operator()(_UniformRandomNumberGenerator& __urng,
4747 const param_type& __p)
4748 {
4749 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
4750 __aurng(__urng);
4751 return -std::log(__aurng()) / __p.lambda();
4752 }
4753
7b93bdde
UD
4754 template<typename _ForwardIterator,
4755 typename _UniformRandomNumberGenerator>
4756 void
4757 __generate(_ForwardIterator __f, _ForwardIterator __t,
4758 _UniformRandomNumberGenerator& __urng)
4759 { this->__generate(__f, __t, __urng, this->param()); }
4760
4761 template<typename _ForwardIterator,
4762 typename _UniformRandomNumberGenerator>
4763 void
4764 __generate(_ForwardIterator __f, _ForwardIterator __t,
4765 _UniformRandomNumberGenerator& __urng,
4766 const param_type& __p)
4767 { this->__generate_impl(__f, __t, __urng, __p); }
4768
4769 template<typename _UniformRandomNumberGenerator>
4770 void
4771 __generate(result_type* __f, result_type* __t,
4772 _UniformRandomNumberGenerator& __urng,
4773 const param_type& __p)
4774 { this->__generate_impl(__f, __t, __urng, __p); }
4775
8e79468d 4776 private:
7b93bdde
UD
4777 template<typename _ForwardIterator,
4778 typename _UniformRandomNumberGenerator>
4779 void
4780 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4781 _UniformRandomNumberGenerator& __urng,
4782 const param_type& __p);
4783
8e79468d
BK
4784 param_type _M_param;
4785 };
4786
fc05e1ba
PC
4787 /**
4788 * @brief Return true if two exponential distributions have the same
4789 * parameters.
4790 */
4791 template<typename _RealType>
4792 inline bool
4793 operator==(const std::exponential_distribution<_RealType>& __d1,
4794 const std::exponential_distribution<_RealType>& __d2)
4795 { return __d1.param() == __d2.param(); }
4796
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)
4951 { return this->operator()(__urng, this->param()); }
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)
4963 { this->__generate(__f, __t, __urng, this->param()); }
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
8e79468d 4980 private:
7b93bdde
UD
4981 template<typename _ForwardIterator,
4982 typename _UniformRandomNumberGenerator>
4983 void
4984 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4985 _UniformRandomNumberGenerator& __urng,
4986 const param_type& __p);
4987
8e79468d
BK
4988 param_type _M_param;
4989 };
4990
fc05e1ba
PC
4991 /**
4992 * @brief Return true if two Weibull distributions have the same
4993 * parameters.
4994 */
4995 template<typename _RealType>
4996 inline bool
4997 operator==(const std::weibull_distribution<_RealType>& __d1,
4998 const std::weibull_distribution<_RealType>& __d2)
4999 { return __d1.param() == __d2.param(); }
5000
5001 /**
5002 * @brief Return true if two Weibull distributions have different
5003 * parameters.
5004 */
5005 template<typename _RealType>
5006 inline bool
5007 operator!=(const std::weibull_distribution<_RealType>& __d1,
5008 const std::weibull_distribution<_RealType>& __d2)
5009 { return !(__d1 == __d2); }
5010
8e79468d
BK
5011 /**
5012 * @brief Inserts a %weibull_distribution random number distribution
5013 * @p __x into the output stream @p __os.
5014 *
5015 * @param __os An output stream.
5016 * @param __x A %weibull_distribution random number distribution.
5017 *
5018 * @returns The output stream with the state of @p __x inserted or in
5019 * an error state.
5020 */
5021 template<typename _RealType, typename _CharT, typename _Traits>
5022 std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
5023 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5024 const std::weibull_distribution<_RealType>& __x);
8e79468d
BK
5025
5026 /**
5027 * @brief Extracts a %weibull_distribution random number distribution
5028 * @p __x from the input stream @p __is.
5029 *
5030 * @param __is An input stream.
5031 * @param __x A %weibull_distribution random number
5032 * generator engine.
5033 *
5034 * @returns The input stream with @p __x extracted or in an error state.
5035 */
5036 template<typename _RealType, typename _CharT, typename _Traits>
5037 std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
5038 operator>>(std::basic_istream<_CharT, _Traits>& __is,
5039 std::weibull_distribution<_RealType>& __x);
8e79468d
BK
5040
5041
5042 /**
5043 * @brief A extreme_value_distribution random number distribution.
5044 *
5045 * The formula for the normal probability mass function is
6cc5a790
BK
5046 * @f[
5047 * p(x|a,b) = \frac{1}{b}
5048 * \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b}))
5049 * @f]
8e79468d
BK
5050 */
5051 template<typename _RealType = double>
5052 class extreme_value_distribution
5053 {
77e3c516
PC
5054 static_assert(std::is_floating_point<_RealType>::value,
5055 "template argument not a floating point type");
5056
8e79468d
BK
5057 public:
5058 /** The type of the range of the distribution. */
5059 typedef _RealType result_type;
5060 /** Parameter type. */
5061 struct param_type
5062 {
5063 typedef extreme_value_distribution<_RealType> distribution_type;
5064
5065 explicit
5066 param_type(_RealType __a = _RealType(0),
5067 _RealType __b = _RealType(1))
5068 : _M_a(__a), _M_b(__b)
5069 { }
5070
5071 _RealType
5072 a() const
5073 { return _M_a; }
5074
5075 _RealType
5076 b() const
5077 { return _M_b; }
5078
fc05e1ba
PC
5079 friend bool
5080 operator==(const param_type& __p1, const param_type& __p2)
5081 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
5082
8e79468d
BK
5083 private:
5084 _RealType _M_a;
5085 _RealType _M_b;
5086 };
5087
5088 explicit
5089 extreme_value_distribution(_RealType __a = _RealType(0),
5090 _RealType __b = _RealType(1))
5091 : _M_param(__a, __b)
5092 { }
5093
5094 explicit
5095 extreme_value_distribution(const param_type& __p)
5096 : _M_param(__p)
5097 { }
5098
5099 /**
5100 * @brief Resets the distribution state.
5101 */
5102 void
5103 reset()
5104 { }
5105
5106 /**
6cc5a790 5107 * @brief Return the @f$a@f$ parameter of the distribution.
8e79468d
BK
5108 */
5109 _RealType
5110 a() const
5111 { return _M_param.a(); }
5112
5113 /**
6cc5a790 5114 * @brief Return the @f$b@f$ parameter of the distribution.
8e79468d
BK
5115 */
5116 _RealType
5117 b() const
5118 { return _M_param.b(); }
5119
5120 /**
5121 * @brief Returns the parameter set of the distribution.
5122 */
5123 param_type
5124 param() const
5125 { return _M_param; }
5126
5127 /**
5128 * @brief Sets the parameter set of the distribution.
5129 * @param __param The new parameter set of the distribution.
5130 */
5131 void
5132 param(const param_type& __param)
5133 { _M_param = __param; }
5134
5135 /**
5136 * @brief Returns the greatest lower bound value of the distribution.
5137 */
5138 result_type
5139 min() const
5140 { return std::numeric_limits<result_type>::min(); }
5141
5142 /**
5143 * @brief Returns the least upper bound value of the distribution.
5144 */
5145 result_type
5146 max() const
5147 { return std::numeric_limits<result_type>::max(); }
5148
247d8075
PC
5149 /**
5150 * @brief Generating functions.
5151 */
8e79468d
BK
5152 template<typename _UniformRandomNumberGenerator>
5153 result_type
5154 operator()(_UniformRandomNumberGenerator& __urng)
5155 { return this->operator()(__urng, this->param()); }
5156
5157 template<typename _UniformRandomNumberGenerator>
5158 result_type
5159 operator()(_UniformRandomNumberGenerator& __urng,
5160 const param_type& __p);
5161
7b93bdde
UD
5162 template<typename _ForwardIterator,
5163 typename _UniformRandomNumberGenerator>
5164 void
5165 __generate(_ForwardIterator __f, _ForwardIterator __t,
5166 _UniformRandomNumberGenerator& __urng)
5167 { this->__generate(__f, __t, __urng, this->param()); }
5168
5169 template<typename _ForwardIterator,
5170 typename _UniformRandomNumberGenerator>
5171 void
5172 __generate(_ForwardIterator __f, _ForwardIterator __t,
5173 _UniformRandomNumberGenerator& __urng,
5174 const param_type& __p)
5175 { this->__generate_impl(__f, __t, __urng, __p); }
5176
5177 template<typename _UniformRandomNumberGenerator>
5178 void
5179 __generate(result_type* __f, result_type* __t,
5180 _UniformRandomNumberGenerator& __urng,
5181 const param_type& __p)
5182 { this->__generate_impl(__f, __t, __urng, __p); }
5183
8e79468d 5184 private:
7b93bdde
UD
5185 template<typename _ForwardIterator,
5186 typename _UniformRandomNumberGenerator>
5187 void
5188 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5189 _UniformRandomNumberGenerator& __urng,
5190 const param_type& __p);
5191
8e79468d
BK
5192 param_type _M_param;
5193 };
5194
fc05e1ba
PC
5195 /**
5196 * @brief Return true if two extreme value distributions have the same
5197 * parameters.
5198 */
5199 template<typename _RealType>
5200 inline bool
5201 operator==(const std::extreme_value_distribution<_RealType>& __d1,
5202 const std::extreme_value_distribution<_RealType>& __d2)
5203 { return __d1.param() == __d2.param(); }
5204
5205 /**
5206 * @brief Return true if two extreme value distributions have different
5207 * parameters.
5208 */
5209 template<typename _RealType>
5210 inline bool
5211 operator!=(const std::extreme_value_distribution<_RealType>& __d1,
5212 const std::extreme_value_distribution<_RealType>& __d2)
5213 { return !(__d1 == __d2); }
5214
8e79468d
BK
5215 /**
5216 * @brief Inserts a %extreme_value_distribution random number distribution
5217 * @p __x into the output stream @p __os.
5218 *
5219 * @param __os An output stream.
5220 * @param __x A %extreme_value_distribution random number distribution.
5221 *
5222 * @returns The output stream with the state of @p __x inserted or in
5223 * an error state.
5224 */
5225 template<typename _RealType, typename _CharT, typename _Traits>
5226 std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
5227 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5228 const std::extreme_value_distribution<_RealType>& __x);
8e79468d
BK
5229
5230 /**
5231 * @brief Extracts a %extreme_value_distribution random number
5232 * distribution @p __x from the input stream @p __is.
5233 *
5234 * @param __is An input stream.
5235 * @param __x A %extreme_value_distribution random number
5236 * generator engine.
5237 *
5238 * @returns The input stream with @p __x extracted or in an error state.
5239 */
5240 template<typename _RealType, typename _CharT, typename _Traits>
5241 std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
5242 operator>>(std::basic_istream<_CharT, _Traits>& __is,
5243 std::extreme_value_distribution<_RealType>& __x);
8e79468d
BK
5244
5245
5246 /**
5247 * @brief A discrete_distribution random number distribution.
5248 *
5249 * The formula for the discrete probability mass function is
5250 *
5251 */
5252 template<typename _IntType = int>
5253 class discrete_distribution
5254 {
77e3c516
PC
5255 static_assert(std::is_integral<_IntType>::value,
5256 "template argument not an integral type");
8e79468d
BK
5257
5258 public:
5259 /** The type of the range of the distribution. */
5260 typedef _IntType result_type;
5261 /** Parameter type. */
5262 struct param_type
5263 {
5264 typedef discrete_distribution<_IntType> distribution_type;
5265 friend class discrete_distribution<_IntType>;
5266
5267 param_type()
879b9073 5268 : _M_prob(), _M_cp()
ce9555cb 5269 { }
8e79468d
BK
5270
5271 template<typename _InputIterator>
5272 param_type(_InputIterator __wbegin,
5273 _InputIterator __wend)
5274 : _M_prob(__wbegin, __wend), _M_cp()
5275 { _M_initialize(); }
5276
5277 param_type(initializer_list<double> __wil)
5278 : _M_prob(__wil.begin(), __wil.end()), _M_cp()
5279 { _M_initialize(); }
5280
5281 template<typename _Func>
5282 param_type(size_t __nw, double __xmin, double __xmax,
5283 _Func __fw);
5284
ce9555cb
PC
5285 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5286 param_type(const param_type&) = default;
5287 param_type& operator=(const param_type&) = default;
5288
8e79468d
BK
5289 std::vector<double>
5290 probabilities() const
879b9073 5291 { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
8e79468d 5292
fc05e1ba
PC
5293 friend bool
5294 operator==(const param_type& __p1, const param_type& __p2)
5295 { return __p1._M_prob == __p2._M_prob; }
5296
8e79468d
BK
5297 private:
5298 void
5299 _M_initialize();
5300
5301 std::vector<double> _M_prob;
5302 std::vector<double> _M_cp;
5303 };
5304
5305 discrete_distribution()
5306 : _M_param()
5307 { }
5308
5309 template<typename _InputIterator>
5310 discrete_distribution(_InputIterator __wbegin,
5311 _InputIterator __wend)
5312 : _M_param(__wbegin, __wend)
5313 { }
5314
f8dd9e0d
PC
5315 discrete_distribution(initializer_list<double> __wl)
5316 : _M_param(__wl)
8e79468d
BK
5317 { }
5318
5319 template<typename _Func>
5320 discrete_distribution(size_t __nw, double __xmin, double __xmax,
5321 _Func __fw)
5322 : _M_param(__nw, __xmin, __xmax, __fw)
5323 { }
5324
5325 explicit
5326 discrete_distribution(const param_type& __p)
5327 : _M_param(__p)
5328 { }
5329
5330 /**
5331 * @brief Resets the distribution state.
5332 */
5333 void
5334 reset()
5335 { }
5336
5337 /**
5338 * @brief Returns the probabilities of the distribution.
5339 */
5340 std::vector<double>
5341 probabilities() const
879b9073
PC
5342 {
5343 return _M_param._M_prob.empty()
5344 ? std::vector<double>(1, 1.0) : _M_param._M_prob;
5345 }
8e79468d
BK
5346
5347 /**
5348 * @brief Returns the parameter set of the distribution.
5349 */
5350 param_type
5351 param() const
5352 { return _M_param; }
5353
5354 /**
5355 * @brief Sets the parameter set of the distribution.
5356 * @param __param The new parameter set of the distribution.
5357 */
5358 void
5359 param(const param_type& __param)
5360 { _M_param = __param; }
5361
5362 /**
5363 * @brief Returns the greatest lower bound value of the distribution.
5364 */
5365 result_type
5366 min() const
5367 { return result_type(0); }
5368
5369 /**
5370 * @brief Returns the least upper bound value of the distribution.
5371 */
5372 result_type
5373 max() const
879b9073
PC
5374 {
5375 return _M_param._M_prob.empty()
5376 ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
5377 }
8e79468d 5378
247d8075
PC
5379 /**
5380 * @brief Generating functions.
5381 */
8e79468d
BK
5382 template<typename _UniformRandomNumberGenerator>
5383 result_type
5384 operator()(_UniformRandomNumberGenerator& __urng)
5385 { return this->operator()(__urng, this->param()); }
5386
5387 template<typename _UniformRandomNumberGenerator>
5388 result_type
5389 operator()(_UniformRandomNumberGenerator& __urng,
5390 const param_type& __p);
5391
7b93bdde
UD
5392 template<typename _ForwardIterator,
5393 typename _UniformRandomNumberGenerator>
5394 void
5395 __generate(_ForwardIterator __f, _ForwardIterator __t,
5396 _UniformRandomNumberGenerator& __urng)
5397 { this->__generate(__f, __t, __urng, this->param()); }
5398
5399 template<typename _ForwardIterator,
5400 typename _UniformRandomNumberGenerator>
5401 void
5402 __generate(_ForwardIterator __f, _ForwardIterator __t,
5403 _UniformRandomNumberGenerator& __urng,
5404 const param_type& __p)
5405 { this->__generate_impl(__f, __t, __urng, __p); }
5406
5407 template<typename _UniformRandomNumberGenerator>
5408 void
5409 __generate(result_type* __f, result_type* __t,
5410 _UniformRandomNumberGenerator& __urng,
5411 const param_type& __p)
5412 { this->__generate_impl(__f, __t, __urng, __p); }
5413
8e79468d
BK
5414 /**
5415 * @brief Inserts a %discrete_distribution random number distribution
5416 * @p __x into the output stream @p __os.
5417 *
5418 * @param __os An output stream.
5419 * @param __x A %discrete_distribution random number distribution.
5420 *
5421 * @returns The output stream with the state of @p __x inserted or in
5422 * an error state.
5423 */
5424 template<typename _IntType1, typename _CharT, typename _Traits>
5425 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
5426 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5427 const std::discrete_distribution<_IntType1>& __x);
8e79468d
BK
5428
5429 /**
5430 * @brief Extracts a %discrete_distribution random number distribution
5431 * @p __x from the input stream @p __is.
5432 *
5433 * @param __is An input stream.
5434 * @param __x A %discrete_distribution random number
5435 * generator engine.
5436 *
5437 * @returns The input stream with @p __x extracted or in an error
5438 * state.
5439 */
5440 template<typename _IntType1, typename _CharT, typename _Traits>
5441 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
5442 operator>>(std::basic_istream<_CharT, _Traits>& __is,
5443 std::discrete_distribution<_IntType1>& __x);
8e79468d
BK
5444
5445 private:
7b93bdde
UD
5446 template<typename _ForwardIterator,
5447 typename _UniformRandomNumberGenerator>
5448 void
5449 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5450 _UniformRandomNumberGenerator& __urng,
5451 const param_type& __p);
5452
8e79468d
BK
5453 param_type _M_param;
5454 };
5455
fc05e1ba
PC
5456 /**
5457 * @brief Return true if two discrete distributions have the same
5458 * parameters.
5459 */
5460 template<typename _IntType>
5461 inline bool
5462 operator==(const std::discrete_distribution<_IntType>& __d1,
5463 const std::discrete_distribution<_IntType>& __d2)
5464 { return __d1.param() == __d2.param(); }
5465
5466 /**
5467 * @brief Return true if two discrete distributions have different
5468 * parameters.
5469 */
5470 template<typename _IntType>
5471 inline bool
5472 operator!=(const std::discrete_distribution<_IntType>& __d1,
5473 const std::discrete_distribution<_IntType>& __d2)
5474 { return !(__d1 == __d2); }
5475
8e79468d
BK
5476
5477 /**
5478 * @brief A piecewise_constant_distribution random number distribution.
5479 *
5480 * The formula for the piecewise constant probability mass function is
5481 *
5482 */
5483 template<typename _RealType = double>
5484 class piecewise_constant_distribution
5485 {
77e3c516
PC
5486 static_assert(std::is_floating_point<_RealType>::value,
5487 "template argument not a floating point type");
5488
8e79468d
BK
5489 public:
5490 /** The type of the range of the distribution. */
5491 typedef _RealType result_type;
5492 /** Parameter type. */
5493 struct param_type
5494 {
5495 typedef piecewise_constant_distribution<_RealType> distribution_type;
5496 friend class piecewise_constant_distribution<_RealType>;
5497
b01630bb 5498 param_type()
879b9073
PC
5499 : _M_int(), _M_den(), _M_cp()
5500 { }
8e79468d
BK
5501
5502 template<typename _InputIteratorB, typename _InputIteratorW>
5503 param_type(_InputIteratorB __bfirst,
5504 _InputIteratorB __bend,
5505 _InputIteratorW __wbegin);
5506
5507 template<typename _Func>
f8dd9e0d 5508 param_type(initializer_list<_RealType> __bi, _Func __fw);
8e79468d
BK
5509
5510 template<typename _Func>
5511 param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5512 _Func __fw);
5513
ce9555cb
PC
5514 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5515 param_type(const param_type&) = default;
5516 param_type& operator=(const param_type&) = default;
5517
8e79468d
BK
5518 std::vector<_RealType>
5519 intervals() const
879b9073
PC
5520 {
5521 if (_M_int.empty())
5522 {
5523 std::vector<_RealType> __tmp(2);
5524 __tmp[1] = _RealType(1);
5525 return __tmp;
5526 }
5527 else
5528 return _M_int;
5529 }
8e79468d
BK
5530
5531 std::vector<double>
5532 densities() const
879b9073 5533 { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
8e79468d 5534
fc05e1ba
PC
5535 friend bool
5536 operator==(const param_type& __p1, const param_type& __p2)
5537 { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
5538
8e79468d
BK
5539 private:
5540 void
5541 _M_initialize();
5542
5543 std::vector<_RealType> _M_int;
5544 std::vector<double> _M_den;
5545 std::vector<double> _M_cp;
5546 };
5547
5548 explicit
5549 piecewise_constant_distribution()
5550 : _M_param()
5551 { }
5552
5553 template<typename _InputIteratorB, typename _InputIteratorW>
5554 piecewise_constant_distribution(_InputIteratorB __bfirst,
5555 _InputIteratorB __bend,
5556 _InputIteratorW __wbegin)
5557 : _M_param(__bfirst, __bend, __wbegin)
5558 { }
5559
5560 template<typename _Func>
f8dd9e0d 5561 piecewise_constant_distribution(initializer_list<_RealType> __bl,
8e79468d 5562 _Func __fw)
f8dd9e0d 5563 : _M_param(__bl, __fw)
8e79468d
BK
5564 { }
5565
5566 template<typename _Func>
5567 piecewise_constant_distribution(size_t __nw,
5568 _RealType __xmin, _RealType __xmax,
5569 _Func __fw)
5570 : _M_param(__nw, __xmin, __xmax, __fw)
5571 { }
5572
5573 explicit
5574 piecewise_constant_distribution(const param_type& __p)
5575 : _M_param(__p)
5576 { }
5577
5578 /**
5579 * @brief Resets the distribution state.
5580 */
5581 void
5582 reset()
5583 { }
5584
5585 /**
5586 * @brief Returns a vector of the intervals.
5587 */
5588 std::vector<_RealType>
5589 intervals() const
879b9073
PC
5590 {
5591 if (_M_param._M_int.empty())
5592 {
5593 std::vector<_RealType> __tmp(2);
5594 __tmp[1] = _RealType(1);
5595 return __tmp;
5596 }
5597 else
5598 return _M_param._M_int;
5599 }
8e79468d
BK
5600
5601 /**
5602 * @brief Returns a vector of the probability densities.
5603 */
5604 std::vector<double>
5605 densities() const
879b9073
PC
5606 {
5607 return _M_param._M_den.empty()
5608 ? std::vector<double>(1, 1.0) : _M_param._M_den;
5609 }
8e79468d
BK
5610
5611 /**
5612 * @brief Returns the parameter set of the distribution.
5613 */
5614 param_type
5615 param() const
5616 { return _M_param; }
5617
5618 /**
5619 * @brief Sets the parameter set of the distribution.
5620 * @param __param The new parameter set of the distribution.
5621 */
5622 void
5623 param(const param_type& __param)
5624 { _M_param = __param; }
5625
5626 /**
5627 * @brief Returns the greatest lower bound value of the distribution.
5628 */
5629 result_type
5630 min() const
879b9073
PC
5631 {
5632 return _M_param._M_int.empty()
5633 ? result_type(0) : _M_param._M_int.front();
5634 }
8e79468d
BK
5635
5636 /**
5637 * @brief Returns the least upper bound value of the distribution.
5638 */
5639 result_type
5640 max() const
879b9073
PC
5641 {
5642 return _M_param._M_int.empty()
5643 ? result_type(1) : _M_param._M_int.back();
5644 }
8e79468d 5645
247d8075
PC
5646 /**
5647 * @brief Generating functions.
5648 */
8e79468d
BK
5649 template<typename _UniformRandomNumberGenerator>
5650 result_type
5651 operator()(_UniformRandomNumberGenerator& __urng)
5652 { return this->operator()(__urng, this->param()); }
5653
5654 template<typename _UniformRandomNumberGenerator>
5655 result_type
5656 operator()(_UniformRandomNumberGenerator& __urng,
5657 const param_type& __p);
5658
7b93bdde
UD
5659 template<typename _ForwardIterator,
5660 typename _UniformRandomNumberGenerator>
5661 void
5662 __generate(_ForwardIterator __f, _ForwardIterator __t,
5663 _UniformRandomNumberGenerator& __urng)
5664 { this->__generate(__f, __t, __urng, this->param()); }
5665
5666 template<typename _ForwardIterator,
5667 typename _UniformRandomNumberGenerator>
5668 void
5669 __generate(_ForwardIterator __f, _ForwardIterator __t,
5670 _UniformRandomNumberGenerator& __urng,
5671 const param_type& __p)
5672 { this->__generate_impl(__f, __t, __urng, __p); }
5673
5674 template<typename _UniformRandomNumberGenerator>
5675 void
5676 __generate(result_type* __f, result_type* __t,
5677 _UniformRandomNumberGenerator& __urng,
5678 const param_type& __p)
5679 { this->__generate_impl(__f, __t, __urng, __p); }
5680
8e79468d
BK
5681 /**
5682 * @brief Inserts a %piecewise_constan_distribution random
5683 * number distribution @p __x into the output stream @p __os.
5684 *
5685 * @param __os An output stream.
5686 * @param __x A %piecewise_constan_distribution random number
5687 * distribution.
5688 *
5689 * @returns The output stream with the state of @p __x inserted or in
5690 * an error state.
5691 */
5692 template<typename _RealType1, typename _CharT, typename _Traits>
5693 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
5694 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5695 const std::piecewise_constant_distribution<_RealType1>& __x);
8e79468d
BK
5696
5697 /**
5698 * @brief Extracts a %piecewise_constan_distribution random
5699 * number distribution @p __x from the input stream @p __is.
5700 *
5701 * @param __is An input stream.
5702 * @param __x A %piecewise_constan_distribution random number
5703 * generator engine.
5704 *
5705 * @returns The input stream with @p __x extracted or in an error
5706 * state.
5707 */
5708 template<typename _RealType1, typename _CharT, typename _Traits>
5709 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
5710 operator>>(std::basic_istream<_CharT, _Traits>& __is,
5711 std::piecewise_constant_distribution<_RealType1>& __x);
8e79468d
BK
5712
5713 private:
7b93bdde
UD
5714 template<typename _ForwardIterator,
5715 typename _UniformRandomNumberGenerator>
5716 void
5717 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5718 _UniformRandomNumberGenerator& __urng,
5719 const param_type& __p);
5720
8e79468d
BK
5721 param_type _M_param;
5722 };
5723
fc05e1ba
PC
5724 /**
5725 * @brief Return true if two piecewise constant distributions have the
5726 * same parameters.
5727 */
5728 template<typename _RealType>
5729 inline bool
5730 operator==(const std::piecewise_constant_distribution<_RealType>& __d1,
5731 const std::piecewise_constant_distribution<_RealType>& __d2)
5732 { return __d1.param() == __d2.param(); }
5733
5734 /**
5735 * @brief Return true if two piecewise constant distributions have
5736 * different parameters.
5737 */
5738 template<typename _RealType>
5739 inline bool
5740 operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
5741 const std::piecewise_constant_distribution<_RealType>& __d2)
5742 { return !(__d1 == __d2); }
5743
8e79468d
BK
5744
5745 /**
5746 * @brief A piecewise_linear_distribution random number distribution.
5747 *
5748 * The formula for the piecewise linear probability mass function is
5749 *
5750 */
5751 template<typename _RealType = double>
5752 class piecewise_linear_distribution
5753 {
77e3c516
PC
5754 static_assert(std::is_floating_point<_RealType>::value,
5755 "template argument not a floating point type");
5756
8e79468d
BK
5757 public:
5758 /** The type of the range of the distribution. */
5759 typedef _RealType result_type;
5760 /** Parameter type. */
5761 struct param_type
5762 {
5763 typedef piecewise_linear_distribution<_RealType> distribution_type;
5764 friend class piecewise_linear_distribution<_RealType>;
5765
f8dd9e0d 5766 param_type()
879b9073
PC
5767 : _M_int(), _M_den(), _M_cp(), _M_m()
5768 { }
8e79468d
BK
5769
5770 template<typename _InputIteratorB, typename _InputIteratorW>
5771 param_type(_InputIteratorB __bfirst,
5772 _InputIteratorB __bend,
5773 _InputIteratorW __wbegin);
5774
5775 template<typename _Func>
f8dd9e0d 5776 param_type(initializer_list<_RealType> __bl, _Func __fw);
8e79468d
BK
5777
5778 template<typename _Func>
5779 param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5780 _Func __fw);
5781
ce9555cb
PC
5782 // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5783 param_type(const param_type&) = default;
5784 param_type& operator=(const param_type&) = default;
5785
8e79468d
BK
5786 std::vector<_RealType>
5787 intervals() const
879b9073
PC
5788 {
5789 if (_M_int.empty())
5790 {
5791 std::vector<_RealType> __tmp(2);
5792 __tmp[1] = _RealType(1);
5793 return __tmp;
5794 }
5795 else
5796 return _M_int;
5797 }
8e79468d
BK
5798
5799 std::vector<double>
5800 densities() const
879b9073 5801 { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
8e79468d 5802
fc05e1ba
PC
5803 friend bool
5804 operator==(const param_type& __p1, const param_type& __p2)
5805 { return (__p1._M_int == __p2._M_int
5806 && __p1._M_den == __p2._M_den); }
5807
8e79468d
BK
5808 private:
5809 void
5810 _M_initialize();
5811
5812 std::vector<_RealType> _M_int;
5813 std::vector<double> _M_den;
5814 std::vector<double> _M_cp;
5815 std::vector<double> _M_m;
5816 };
5817
5818 explicit
5819 piecewise_linear_distribution()
5820 : _M_param()
5821 { }
5822
5823 template<typename _InputIteratorB, typename _InputIteratorW>
5824 piecewise_linear_distribution(_InputIteratorB __bfirst,
5825 _InputIteratorB __bend,
5826 _InputIteratorW __wbegin)
5827 : _M_param(__bfirst, __bend, __wbegin)
5828 { }
5829
5830 template<typename _Func>
f8dd9e0d 5831 piecewise_linear_distribution(initializer_list<_RealType> __bl,
8e79468d 5832 _Func __fw)
f8dd9e0d 5833 : _M_param(__bl, __fw)
8e79468d
BK
5834 { }
5835
5836 template<typename _Func>
5837 piecewise_linear_distribution(size_t __nw,
5838 _RealType __xmin, _RealType __xmax,
5839 _Func __fw)
5840 : _M_param(__nw, __xmin, __xmax, __fw)
5841 { }
5842
5843 explicit
5844 piecewise_linear_distribution(const param_type& __p)
5845 : _M_param(__p)
5846 { }
5847
5848 /**
5849 * Resets the distribution state.
5850 */
5851 void
5852 reset()
5853 { }
5854
5855 /**
5856 * @brief Return the intervals of the distribution.
5857 */
5858 std::vector<_RealType>
5859 intervals() const
879b9073
PC
5860 {
5861 if (_M_param._M_int.empty())
5862 {
5863 std::vector<_RealType> __tmp(2);
5864 __tmp[1] = _RealType(1);
5865 return __tmp;
5866 }
5867 else
5868 return _M_param._M_int;
5869 }
8e79468d
BK
5870
5871 /**
5872 * @brief Return a vector of the probability densities of the
5873 * distribution.
5874 */
5875 std::vector<double>
5876 densities() const
879b9073
PC
5877 {
5878 return _M_param._M_den.empty()
5879 ? std::vector<double>(2, 1.0) : _M_param._M_den;
5880 }
8e79468d
BK
5881
5882 /**
5883 * @brief Returns the parameter set of the distribution.
5884 */
5885 param_type
5886 param() const
5887 { return _M_param; }
5888
5889 /**
5890 * @brief Sets the parameter set of the distribution.
5891 * @param __param The new parameter set of the distribution.
5892 */
5893 void
5894 param(const param_type& __param)
5895 { _M_param = __param; }
5896
5897 /**
5898 * @brief Returns the greatest lower bound value of the distribution.
5899 */
5900 result_type
5901 min() const
879b9073
PC
5902 {
5903 return _M_param._M_int.empty()
5904 ? result_type(0) : _M_param._M_int.front();
5905 }
8e79468d
BK
5906
5907 /**
5908 * @brief Returns the least upper bound value of the distribution.
5909 */
5910 result_type
5911 max() const
879b9073
PC
5912 {
5913 return _M_param._M_int.empty()
5914 ? result_type(1) : _M_param._M_int.back();
5915 }
8e79468d 5916
247d8075
PC
5917 /**
5918 * @brief Generating functions.
5919 */
8e79468d
BK
5920 template<typename _UniformRandomNumberGenerator>
5921 result_type
5922 operator()(_UniformRandomNumberGenerator& __urng)
5923 { return this->operator()(__urng, this->param()); }
5924
5925 template<typename _UniformRandomNumberGenerator>
5926 result_type
5927 operator()(_UniformRandomNumberGenerator& __urng,
5928 const param_type& __p);
5929
7b93bdde
UD
5930 template<typename _ForwardIterator,
5931 typename _UniformRandomNumberGenerator>
5932 void
5933 __generate(_ForwardIterator __f, _ForwardIterator __t,
5934 _UniformRandomNumberGenerator& __urng)
5935 { this->__generate(__f, __t, __urng, this->param()); }
5936
5937 template<typename _ForwardIterator,
5938 typename _UniformRandomNumberGenerator>
5939 void
5940 __generate(_ForwardIterator __f, _ForwardIterator __t,
5941 _UniformRandomNumberGenerator& __urng,
5942 const param_type& __p)
5943 { this->__generate_impl(__f, __t, __urng, __p); }
5944
5945 template<typename _UniformRandomNumberGenerator>
5946 void
5947 __generate(result_type* __f, result_type* __t,
5948 _UniformRandomNumberGenerator& __urng,
5949 const param_type& __p)
5950 { this->__generate_impl(__f, __t, __urng, __p); }
5951
8e79468d
BK
5952 /**
5953 * @brief Inserts a %piecewise_linear_distribution random number
5954 * distribution @p __x into the output stream @p __os.
5955 *
5956 * @param __os An output stream.
5957 * @param __x A %piecewise_linear_distribution random number
5958 * distribution.
5959 *
5960 * @returns The output stream with the state of @p __x inserted or in
5961 * an error state.
5962 */
5963 template<typename _RealType1, typename _CharT, typename _Traits>
5964 friend std::basic_ostream<_CharT, _Traits>&
93c66bc6
BK
5965 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5966 const std::piecewise_linear_distribution<_RealType1>& __x);
8e79468d
BK
5967
5968 /**
5969 * @brief Extracts a %piecewise_linear_distribution random number
5970 * distribution @p __x from the input stream @p __is.
5971 *
5972 * @param __is An input stream.
5973 * @param __x A %piecewise_linear_distribution random number
5974 * generator engine.
5975 *
5976 * @returns The input stream with @p __x extracted or in an error
5977 * state.
5978 */
5979 template<typename _RealType1, typename _CharT, typename _Traits>
5980 friend std::basic_istream<_CharT, _Traits>&
93c66bc6
BK
5981 operator>>(std::basic_istream<_CharT, _Traits>& __is,
5982 std::piecewise_linear_distribution<_RealType1>& __x);
8e79468d
BK
5983
5984 private:
7b93bdde
UD
5985 template<typename _ForwardIterator,
5986 typename _UniformRandomNumberGenerator>
5987 void
5988 __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5989 _UniformRandomNumberGenerator& __urng,
5990 const param_type& __p);
5991
8e79468d
BK
5992 param_type _M_param;
5993 };
5994
fc05e1ba
PC
5995 /**
5996 * @brief Return true if two piecewise linear distributions have the
5997 * same parameters.
5998 */
5999 template<typename _RealType>
6000 inline bool
6001 operator==(const std::piecewise_linear_distribution<_RealType>& __d1,
6002 const std::piecewise_linear_distribution<_RealType>& __d2)
6003 { return __d1.param() == __d2.param(); }
6004
6005 /**
6006 * @brief Return true if two piecewise linear distributions have
6007 * different parameters.
6008 */
6009 template<typename _RealType>
6010 inline bool
6011 operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
6012 const std::piecewise_linear_distribution<_RealType>& __d2)
6013 { return !(__d1 == __d2); }
6014
8e79468d 6015
037181bc 6016 /* @} */ // group random_distributions_poisson
8e79468d 6017
037181bc 6018 /* @} */ // group random_distributions
8e79468d
BK
6019
6020 /**
037181bc
BK
6021 * @addtogroup random_utilities Random Number Utilities
6022 * @ingroup random
8e79468d
BK
6023 * @{
6024 */
6025
6026 /**
6027 * @brief The seed_seq class generates sequences of seeds for random
6028 * number generators.
6029 */
6030 class seed_seq
6031 {
6032
6033 public:
6034 /** The type of the seed vales. */
6035 typedef uint_least32_t result_type;
6036
6037 /** Default constructor. */
6038 seed_seq()
6039 : _M_v()
6040 { }
6041
6042 template<typename _IntType>
6043 seed_seq(std::initializer_list<_IntType> il);
6044
6045 template<typename _InputIterator>
6046 seed_seq(_InputIterator __begin, _InputIterator __end);
6047
6048 // generating functions
6049 template<typename _RandomAccessIterator>
6050 void
6051 generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
6052
6053 // property functions
6054 size_t size() const
6055 { return _M_v.size(); }
6056
6057 template<typename OutputIterator>
6058 void
6059 param(OutputIterator __dest) const
6060 { std::copy(_M_v.begin(), _M_v.end(), __dest); }
6061
6062 private:
6063 ///
94986f6d 6064 std::vector<result_type> _M_v;
8e79468d
BK
6065 };
6066
037181bc 6067 /* @} */ // group random_utilities
8e79468d 6068
037181bc 6069 /* @} */ // group random
12ffa228
BK
6070
6071_GLIBCXX_END_NAMESPACE_VERSION
6072} // namespace std
8e79468d 6073
06f29237 6074#endif