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