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