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