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