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