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