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