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