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