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