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