Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/random.h
$ cat -n /usr/include/c++/13/bits/random.h 1 // random number generation -*- C++ -*- 2 3 // Copyright (C) 2009-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 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
35 #include
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
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
60 _RealType 61 generate_canonical(_UniformRandomNumberGenerator& __g); 62 63 /// @cond undocumented 64 // Implementation-space details. 65 namespace __detail 66 { 67 template
69 (std::numeric_limits<_UIntType>::digits)> 70 struct _Shift 71 { static constexpr _UIntType __value = 0; }; 72 73 template
74 struct _Shift<_UIntType, __w, true> 75 { static constexpr _UIntType __value = _UIntType(1) << __w; }; 76 77 template
83 struct _Select_uint_least_t 84 { 85 static_assert(__which < 0, /* needs to be dependent */ 86 "sorry, would be too much trouble for a slow result"); 87 }; 88 89 template
90 struct _Select_uint_least_t<__s, 4> 91 { using type = unsigned int; }; 92 93 template
94 struct _Select_uint_least_t<__s, 3> 95 { using type = unsigned long; }; 96 97 template
98 struct _Select_uint_least_t<__s, 2> 99 { using type = unsigned long long; }; 100 101 #if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__ 102 template
103 struct _Select_uint_least_t<__s, 1> 104 { __extension__ using type = unsigned __int128; }; 105 #endif 106 107 // Assume a != 0, a < m, c < m, x < m. 108 template
= __m - 1), 111 bool __schrage_ok = __m % __a < __m / __a> 112 struct _Mod 113 { 114 static _Tp 115 __calc(_Tp __x) 116 { 117 using _Tp2 118 = typename _Select_uint_least_t
::type; 120 return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); 121 } 122 }; 123 124 // Schrage. 125 template
126 struct _Mod<_Tp, __m, __a, __c, false, true> 127 { 128 static _Tp 129 __calc(_Tp __x); 130 }; 131 132 // Special cases: 133 // - for m == 2^n or m == 0, unsigned integer overflow is safe. 134 // - a * (m - 1) + c fits in _Tp, there is no overflow. 135 template
136 struct _Mod<_Tp, __m, __a, __c, true, __s> 137 { 138 static _Tp 139 __calc(_Tp __x) 140 { 141 _Tp __res = __a * __x + __c; 142 if (__m) 143 __res %= __m; 144 return __res; 145 } 146 }; 147 148 template
149 inline _Tp 150 __mod(_Tp __x) 151 { 152 if _GLIBCXX17_CONSTEXPR (__a == 0) 153 return __c; 154 else 155 { 156 // _Mod must not be instantiated with a == 0 157 constexpr _Tp __a1 = __a ? __a : 1; 158 return _Mod<_Tp, __m, __a1, __c>::__calc(__x); 159 } 160 } 161 162 /* 163 * An adaptor class for converting the output of any Generator into 164 * the input for a specific Distribution. 165 */ 166 template
167 struct _Adaptor 168 { 169 static_assert(std::is_floating_point<_DInputType>::value, 170 "template argument must be a floating point type"); 171 172 public: 173 _Adaptor(_Engine& __g) 174 : _M_g(__g) { } 175 176 _DInputType 177 min() const 178 { return _DInputType(0); } 179 180 _DInputType 181 max() const 182 { return _DInputType(1); } 183 184 /* 185 * Converts a value generated by the adapted random number generator 186 * into a value in the input domain for the dependent random number 187 * distribution. 188 */ 189 _DInputType 190 operator()() 191 { 192 return std::generate_canonical<_DInputType, 193 std::numeric_limits<_DInputType>::digits, 194 _Engine>(_M_g); 195 } 196 197 private: 198 _Engine& _M_g; 199 }; 200 201 // Detect whether a template argument _Sseq is a valid seed sequence for 202 // a random number engine _Engine with result type _Res. 203 // Used to constrain _Engine::_Engine(_Sseq&) and _Engine::seed(_Sseq&) 204 // as required by [rand.eng.general]. 205 206 template
207 using __seed_seq_generate_t = decltype( 208 std::declval<_Sseq&>().generate(std::declval
(), 209 std::declval
())); 210 211 template
> 213 using _If_seed_seq_for = _Require< 214 __not_
, _Engine>>, 215 is_unsigned
, 216 __not_
> 217 >; 218 219 } // namespace __detail 220 /// @endcond 221 222 /** 223 * @addtogroup random_generators Random Number Generators 224 * @ingroup random 225 * 226 * These classes define objects which provide random or pseudorandom 227 * numbers, either from a discrete or a continuous interval. The 228 * random number generator supplied as a part of this library are 229 * all uniform random number generators which provide a sequence of 230 * random number uniformly distributed over their range. 231 * 232 * A number generator is a function object with an operator() that 233 * takes zero arguments and returns a number. 234 * 235 * A compliant random number generator must satisfy the following 236 * requirements.
237 *
Random Number Generator Requirements
238 *
To be documented.
239 * 240 * @{ 241 */ 242 243 /** 244 * @brief A model of a linear congruential random number generator. 245 * 246 * A random number generator that produces pseudorandom numbers via 247 * linear function: 248 * @f[ 249 * x_{i+1}\leftarrow(ax_{i} + c) \bmod m 250 * @f] 251 * 252 * The template parameter @p _UIntType must be an unsigned integral type 253 * large enough to store values up to (__m-1). If the template parameter 254 * @p __m is 0, the modulus @p __m used is 255 * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template 256 * parameters @p __a and @p __c must be less than @p __m. 257 * 258 * The size of the state is @f$1@f$. 259 * 260 * @headerfile random 261 * @since C++11 262 */ 263 template
264 class linear_congruential_engine 265 { 266 static_assert(std::is_unsigned<_UIntType>::value, 267 "result_type must be an unsigned integral type"); 268 static_assert(__m == 0u || (__a < __m && __c < __m), 269 "template argument substituting __m out of bounds"); 270 271 template
272 using _If_seed_seq 273 = __detail::_If_seed_seq_for<_Sseq, linear_congruential_engine, 274 _UIntType>; 275 276 public: 277 /** The type of the generated random value. */ 278 typedef _UIntType result_type; 279 280 /** The multiplier. */ 281 static constexpr result_type multiplier = __a; 282 /** An increment. */ 283 static constexpr result_type increment = __c; 284 /** The modulus. */ 285 static constexpr result_type modulus = __m; 286 static constexpr result_type default_seed = 1u; 287 288 /** 289 * @brief Constructs a %linear_congruential_engine random number 290 * generator engine with seed 1. 291 */ 292 linear_congruential_engine() : linear_congruential_engine(default_seed) 293 { } 294 295 /** 296 * @brief Constructs a %linear_congruential_engine random number 297 * generator engine with seed @p __s. The default seed value 298 * is 1. 299 * 300 * @param __s The initial seed value. 301 */ 302 explicit 303 linear_congruential_engine(result_type __s) 304 { seed(__s); } 305 306 /** 307 * @brief Constructs a %linear_congruential_engine random number 308 * generator engine seeded from the seed sequence @p __q. 309 * 310 * @param __q the seed sequence. 311 */ 312 template
> 313 explicit 314 linear_congruential_engine(_Sseq& __q) 315 { seed(__q); } 316 317 /** 318 * @brief Reseeds the %linear_congruential_engine random number generator 319 * engine sequence to the seed @p __s. 320 * 321 * @param __s The new seed. 322 */ 323 void 324 seed(result_type __s = default_seed); 325 326 /** 327 * @brief Reseeds the %linear_congruential_engine random number generator 328 * engine 329 * sequence using values from the seed sequence @p __q. 330 * 331 * @param __q the seed sequence. 332 */ 333 template
334 _If_seed_seq<_Sseq> 335 seed(_Sseq& __q); 336 337 /** 338 * @brief Gets the smallest possible value in the output range. 339 * 340 * The minimum depends on the @p __c parameter: if it is zero, the 341 * minimum generated must be > 0, otherwise 0 is allowed. 342 */ 343 static constexpr result_type 344 min() 345 { return __c == 0u ? 1u : 0u; } 346 347 /** 348 * @brief Gets the largest possible value in the output range. 349 */ 350 static constexpr result_type 351 max() 352 { return __m - 1u; } 353 354 /** 355 * @brief Discard a sequence of random numbers. 356 */ 357 void 358 discard(unsigned long long __z) 359 { 360 for (; __z != 0ULL; --__z) 361 (*this)(); 362 } 363 364 /** 365 * @brief Gets the next random number in the sequence. 366 */ 367 result_type 368 operator()() 369 { 370 _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x); 371 return _M_x; 372 } 373 374 /** 375 * @brief Compares two linear congruential random number generator 376 * objects of the same type for equality. 377 * 378 * @param __lhs A linear congruential random number generator object. 379 * @param __rhs Another linear congruential random number generator 380 * object. 381 * 382 * @returns true if the infinite sequences of generated values 383 * would be equal, false otherwise. 384 */ 385 friend bool 386 operator==(const linear_congruential_engine& __lhs, 387 const linear_congruential_engine& __rhs) 388 { return __lhs._M_x == __rhs._M_x; } 389 390 /** 391 * @brief Writes the textual representation of the state x(i) of x to 392 * @p __os. 393 * 394 * @param __os The output stream. 395 * @param __lcr A % linear_congruential_engine random number generator. 396 * @returns __os. 397 */ 398 template
400 friend std::basic_ostream<_CharT, _Traits>& 401 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 402 const std::linear_congruential_engine<_UIntType1, 403 __a1, __c1, __m1>& __lcr); 404 405 /** 406 * @brief Sets the state of the engine by reading its textual 407 * representation from @p __is. 408 * 409 * The textual representation must have been previously written using 410 * an output stream whose imbued locale and whose type's template 411 * specialization arguments _CharT and _Traits were the same as those 412 * of @p __is. 413 * 414 * @param __is The input stream. 415 * @param __lcr A % linear_congruential_engine random number generator. 416 * @returns __is. 417 */ 418 template
420 friend std::basic_istream<_CharT, _Traits>& 421 operator>>(std::basic_istream<_CharT, _Traits>& __is, 422 std::linear_congruential_engine<_UIntType1, __a1, 423 __c1, __m1>& __lcr); 424 425 private: 426 _UIntType _M_x; 427 }; 428 429 #if __cpp_impl_three_way_comparison < 201907L 430 /** 431 * @brief Compares two linear congruential random number generator 432 * objects of the same type for inequality. 433 * 434 * @param __lhs A linear congruential random number generator object. 435 * @param __rhs Another linear congruential random number generator 436 * object. 437 * 438 * @returns true if the infinite sequences of generated values 439 * would be different, false otherwise. 440 */ 441 template
442 inline bool 443 operator!=(const std::linear_congruential_engine<_UIntType, __a, 444 __c, __m>& __lhs, 445 const std::linear_congruential_engine<_UIntType, __a, 446 __c, __m>& __rhs) 447 { return !(__lhs == __rhs); } 448 #endif 449 450 /** 451 * A generalized feedback shift register discrete random number generator. 452 * 453 * This algorithm avoids multiplication and division and is designed to be 454 * friendly to a pipelined architecture. If the parameters are chosen 455 * correctly, this generator will produce numbers with a very long period and 456 * fairly good apparent entropy, although still not cryptographically strong. 457 * 458 * The best way to use this generator is with the predefined mt19937 class. 459 * 460 * This algorithm was originally invented by Makoto Matsumoto and 461 * Takuji Nishimura. 462 * 463 * @tparam __w Word size, the number of bits in each element of 464 * the state vector. 465 * @tparam __n The degree of recursion. 466 * @tparam __m The period parameter. 467 * @tparam __r The separation point bit index. 468 * @tparam __a The last row of the twist matrix. 469 * @tparam __u The first right-shift tempering matrix parameter. 470 * @tparam __d The first right-shift tempering matrix mask. 471 * @tparam __s The first left-shift tempering matrix parameter. 472 * @tparam __b The first left-shift tempering matrix mask. 473 * @tparam __t The second left-shift tempering matrix parameter. 474 * @tparam __c The second left-shift tempering matrix mask. 475 * @tparam __l The second right-shift tempering matrix parameter. 476 * @tparam __f Initialization multiplier. 477 * 478 * @headerfile random 479 * @since C++11 480 */ 481 template
486 class mersenne_twister_engine 487 { 488 static_assert(std::is_unsigned<_UIntType>::value, 489 "result_type must be an unsigned integral type"); 490 static_assert(1u <= __m && __m <= __n, 491 "template argument substituting __m out of bounds"); 492 static_assert(__r <= __w, "template argument substituting " 493 "__r out of bound"); 494 static_assert(__u <= __w, "template argument substituting " 495 "__u out of bound"); 496 static_assert(__s <= __w, "template argument substituting " 497 "__s out of bound"); 498 static_assert(__t <= __w, "template argument substituting " 499 "__t out of bound"); 500 static_assert(__l <= __w, "template argument substituting " 501 "__l out of bound"); 502 static_assert(__w <= std::numeric_limits<_UIntType>::digits, 503 "template argument substituting __w out of bound"); 504 static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1), 505 "template argument substituting __a out of bound"); 506 static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1), 507 "template argument substituting __b out of bound"); 508 static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1), 509 "template argument substituting __c out of bound"); 510 static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1), 511 "template argument substituting __d out of bound"); 512 static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1), 513 "template argument substituting __f out of bound"); 514 515 template
516 using _If_seed_seq 517 = __detail::_If_seed_seq_for<_Sseq, mersenne_twister_engine, 518 _UIntType>; 519 520 public: 521 /** The type of the generated random value. */ 522 typedef _UIntType result_type; 523 524 // parameter values 525 static constexpr size_t word_size = __w; 526 static constexpr size_t state_size = __n; 527 static constexpr size_t shift_size = __m; 528 static constexpr size_t mask_bits = __r; 529 static constexpr result_type xor_mask = __a; 530 static constexpr size_t tempering_u = __u; 531 static constexpr result_type tempering_d = __d; 532 static constexpr size_t tempering_s = __s; 533 static constexpr result_type tempering_b = __b; 534 static constexpr size_t tempering_t = __t; 535 static constexpr result_type tempering_c = __c; 536 static constexpr size_t tempering_l = __l; 537 static constexpr result_type initialization_multiplier = __f; 538 static constexpr result_type default_seed = 5489u; 539 540 // constructors and member functions 541 542 mersenne_twister_engine() : mersenne_twister_engine(default_seed) { } 543 544 explicit 545 mersenne_twister_engine(result_type __sd) 546 { seed(__sd); } 547 548 /** 549 * @brief Constructs a %mersenne_twister_engine random number generator 550 * engine seeded from the seed sequence @p __q. 551 * 552 * @param __q the seed sequence. 553 */ 554 template
> 555 explicit 556 mersenne_twister_engine(_Sseq& __q) 557 { seed(__q); } 558 559 void 560 seed(result_type __sd = default_seed); 561 562 template
563 _If_seed_seq<_Sseq> 564 seed(_Sseq& __q); 565 566 /** 567 * @brief Gets the smallest possible value in the output range. 568 */ 569 static constexpr result_type 570 min() 571 { return 0; } 572 573 /** 574 * @brief Gets the largest possible value in the output range. 575 */ 576 static constexpr result_type 577 max() 578 { return __detail::_Shift<_UIntType, __w>::__value - 1; } 579 580 /** 581 * @brief Discard a sequence of random numbers. 582 */ 583 void 584 discard(unsigned long long __z); 585 586 result_type 587 operator()(); 588 589 /** 590 * @brief Compares two % mersenne_twister_engine random number generator 591 * objects of the same type for equality. 592 * 593 * @param __lhs A % mersenne_twister_engine random number generator 594 * object. 595 * @param __rhs Another % mersenne_twister_engine random number 596 * generator object. 597 * 598 * @returns true if the infinite sequences of generated values 599 * would be equal, false otherwise. 600 */ 601 friend bool 602 operator==(const mersenne_twister_engine& __lhs, 603 const mersenne_twister_engine& __rhs) 604 { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x) 605 && __lhs._M_p == __rhs._M_p); } 606 607 /** 608 * @brief Inserts the current state of a % mersenne_twister_engine 609 * random number generator engine @p __x into the output stream 610 * @p __os. 611 * 612 * @param __os An output stream. 613 * @param __x A % mersenne_twister_engine random number generator 614 * engine. 615 * 616 * @returns The output stream with the state of @p __x inserted or in 617 * an error state. 618 */ 619 template
627 friend std::basic_ostream<_CharT, _Traits>& 628 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 629 const std::mersenne_twister_engine<_UIntType1, __w1, __n1, 630 __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1, 631 __l1, __f1>& __x); 632 633 /** 634 * @brief Extracts the current state of a % mersenne_twister_engine 635 * random number generator engine @p __x from the input stream 636 * @p __is. 637 * 638 * @param __is An input stream. 639 * @param __x A % mersenne_twister_engine random number generator 640 * engine. 641 * 642 * @returns The input stream with the state of @p __x extracted or in 643 * an error state. 644 */ 645 template
653 friend std::basic_istream<_CharT, _Traits>& 654 operator>>(std::basic_istream<_CharT, _Traits>& __is, 655 std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1, 656 __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1, 657 __l1, __f1>& __x); 658 659 private: 660 void _M_gen_rand(); 661 662 _UIntType _M_x[state_size]; 663 size_t _M_p; 664 }; 665 666 #if __cpp_impl_three_way_comparison < 201907L 667 /** 668 * @brief Compares two % mersenne_twister_engine random number generator 669 * objects of the same type for inequality. 670 * 671 * @param __lhs A % mersenne_twister_engine random number generator 672 * object. 673 * @param __rhs Another % mersenne_twister_engine random number 674 * generator object. 675 * 676 * @returns true if the infinite sequences of generated values 677 * would be different, false otherwise. 678 */ 679 template
684 inline bool 685 operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m, 686 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs, 687 const std::mersenne_twister_engine<_UIntType, __w, __n, __m, 688 __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs) 689 { return !(__lhs == __rhs); } 690 #endif 691 692 /** 693 * @brief The Marsaglia-Zaman generator. 694 * 695 * This is a model of a Generalized Fibonacci discrete random number 696 * generator, sometimes referred to as the SWC generator. 697 * 698 * A discrete random number generator that produces pseudorandom 699 * numbers using: 700 * @f[ 701 * x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m 702 * @f] 703 * 704 * The size of the state is @f$r@f$ 705 * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$. 706 * 707 * @headerfile random 708 * @since C++11 709 */ 710 template
711 class subtract_with_carry_engine 712 { 713 static_assert(std::is_unsigned<_UIntType>::value, 714 "result_type must be an unsigned integral type"); 715 static_assert(0u < __s && __s < __r, 716 "0 < s < r"); 717 static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits, 718 "template argument substituting __w out of bounds"); 719 720 template
721 using _If_seed_seq 722 = __detail::_If_seed_seq_for<_Sseq, subtract_with_carry_engine, 723 _UIntType>; 724 725 public: 726 /** The type of the generated random value. */ 727 typedef _UIntType result_type; 728 729 // parameter values 730 static constexpr size_t word_size = __w; 731 static constexpr size_t short_lag = __s; 732 static constexpr size_t long_lag = __r; 733 static constexpr uint_least32_t default_seed = 19780503u; 734 735 subtract_with_carry_engine() : subtract_with_carry_engine(0u) 736 { } 737 738 /** 739 * @brief Constructs an explicitly seeded %subtract_with_carry_engine 740 * random number generator. 741 */ 742 explicit 743 subtract_with_carry_engine(result_type __sd) 744 { seed(__sd); } 745 746 /** 747 * @brief Constructs a %subtract_with_carry_engine random number engine 748 * seeded from the seed sequence @p __q. 749 * 750 * @param __q the seed sequence. 751 */ 752 template
> 753 explicit 754 subtract_with_carry_engine(_Sseq& __q) 755 { seed(__q); } 756 757 /** 758 * @brief Seeds the initial state @f$x_0@f$ of the random number 759 * generator. 760 * 761 * N1688[4.19] modifies this as follows. If @p __value == 0, 762 * sets value to 19780503. In any case, with a linear 763 * congruential generator lcg(i) having parameters @f$ m_{lcg} = 764 * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value 765 * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m 766 * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$ 767 * set carry to 1, otherwise sets carry to 0. 768 */ 769 void 770 seed(result_type __sd = 0u); 771 772 /** 773 * @brief Seeds the initial state @f$x_0@f$ of the 774 * % subtract_with_carry_engine random number generator. 775 */ 776 template
777 _If_seed_seq<_Sseq> 778 seed(_Sseq& __q); 779 780 /** 781 * @brief Gets the inclusive minimum value of the range of random 782 * integers returned by this generator. 783 */ 784 static constexpr result_type 785 min() 786 { return 0; } 787 788 /** 789 * @brief Gets the inclusive maximum value of the range of random 790 * integers returned by this generator. 791 */ 792 static constexpr result_type 793 max() 794 { return __detail::_Shift<_UIntType, __w>::__value - 1; } 795 796 /** 797 * @brief Discard a sequence of random numbers. 798 */ 799 void 800 discard(unsigned long long __z) 801 { 802 for (; __z != 0ULL; --__z) 803 (*this)(); 804 } 805 806 /** 807 * @brief Gets the next random number in the sequence. 808 */ 809 result_type 810 operator()(); 811 812 /** 813 * @brief Compares two % subtract_with_carry_engine random number 814 * generator objects of the same type for equality. 815 * 816 * @param __lhs A % subtract_with_carry_engine random number generator 817 * object. 818 * @param __rhs Another % subtract_with_carry_engine random number 819 * generator object. 820 * 821 * @returns true if the infinite sequences of generated values 822 * would be equal, false otherwise. 823 */ 824 friend bool 825 operator==(const subtract_with_carry_engine& __lhs, 826 const subtract_with_carry_engine& __rhs) 827 { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x) 828 && __lhs._M_carry == __rhs._M_carry 829 && __lhs._M_p == __rhs._M_p); } 830 831 /** 832 * @brief Inserts the current state of a % subtract_with_carry_engine 833 * random number generator engine @p __x into the output stream 834 * @p __os. 835 * 836 * @param __os An output stream. 837 * @param __x A % subtract_with_carry_engine random number generator 838 * engine. 839 * 840 * @returns The output stream with the state of @p __x inserted or in 841 * an error state. 842 */ 843 template
845 friend std::basic_ostream<_CharT, _Traits>& 846 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 847 const std::subtract_with_carry_engine<_UIntType1, __w1, 848 __s1, __r1>& __x); 849 850 /** 851 * @brief Extracts the current state of a % subtract_with_carry_engine 852 * random number generator engine @p __x from the input stream 853 * @p __is. 854 * 855 * @param __is An input stream. 856 * @param __x A % subtract_with_carry_engine random number generator 857 * engine. 858 * 859 * @returns The input stream with the state of @p __x extracted or in 860 * an error state. 861 */ 862 template
864 friend std::basic_istream<_CharT, _Traits>& 865 operator>>(std::basic_istream<_CharT, _Traits>& __is, 866 std::subtract_with_carry_engine<_UIntType1, __w1, 867 __s1, __r1>& __x); 868 869 private: 870 /// The state of the generator. This is a ring buffer. 871 _UIntType _M_x[long_lag]; 872 _UIntType _M_carry; ///< The carry 873 size_t _M_p; ///< Current index of x(i - r). 874 }; 875 876 #if __cpp_impl_three_way_comparison < 201907L 877 /** 878 * @brief Compares two % subtract_with_carry_engine random number 879 * generator objects of the same type for inequality. 880 * 881 * @param __lhs A % subtract_with_carry_engine random number generator 882 * object. 883 * @param __rhs Another % subtract_with_carry_engine random number 884 * generator object. 885 * 886 * @returns true if the infinite sequences of generated values 887 * would be different, false otherwise. 888 */ 889 template
890 inline bool 891 operator!=(const std::subtract_with_carry_engine<_UIntType, __w, 892 __s, __r>& __lhs, 893 const std::subtract_with_carry_engine<_UIntType, __w, 894 __s, __r>& __rhs) 895 { return !(__lhs == __rhs); } 896 #endif 897 898 /** 899 * Produces random numbers from some base engine by discarding blocks of 900 * data. 901 * 902 * @pre @f$ 0 \leq r \leq p @f$ 903 * 904 * @headerfile random 905 * @since C++11 906 */ 907 template
908 class discard_block_engine 909 { 910 static_assert(1 <= __r && __r <= __p, 911 "template argument substituting __r out of bounds"); 912 913 public: 914 /** The type of the generated random value. */ 915 typedef typename _RandomNumberEngine::result_type result_type; 916 917 template
918 using _If_seed_seq 919 = __detail::_If_seed_seq_for<_Sseq, discard_block_engine, 920 result_type>; 921 922 // parameter values 923 static constexpr size_t block_size = __p; 924 static constexpr size_t used_block = __r; 925 926 /** 927 * @brief Constructs a default %discard_block_engine engine. 928 * 929 * The underlying engine is default constructed as well. 930 */ 931 discard_block_engine() 932 : _M_b(), _M_n(0) { } 933 934 /** 935 * @brief Copy constructs a %discard_block_engine engine. 936 * 937 * Copies an existing base class random number generator. 938 * @param __rng An existing (base class) engine object. 939 */ 940 explicit 941 discard_block_engine(const _RandomNumberEngine& __rng) 942 : _M_b(__rng), _M_n(0) { } 943 944 /** 945 * @brief Move constructs a %discard_block_engine engine. 946 * 947 * Copies an existing base class random number generator. 948 * @param __rng An existing (base class) engine object. 949 */ 950 explicit 951 discard_block_engine(_RandomNumberEngine&& __rng) 952 : _M_b(std::move(__rng)), _M_n(0) { } 953 954 /** 955 * @brief Seed constructs a %discard_block_engine engine. 956 * 957 * Constructs the underlying generator engine seeded with @p __s. 958 * @param __s A seed value for the base class engine. 959 */ 960 explicit 961 discard_block_engine(result_type __s) 962 : _M_b(__s), _M_n(0) { } 963 964 /** 965 * @brief Generator construct a %discard_block_engine engine. 966 * 967 * @param __q A seed sequence. 968 */ 969 template
> 970 explicit 971 discard_block_engine(_Sseq& __q) 972 : _M_b(__q), _M_n(0) 973 { } 974 975 /** 976 * @brief Reseeds the %discard_block_engine object with the default 977 * seed for the underlying base class generator engine. 978 */ 979 void 980 seed() 981 { 982 _M_b.seed(); 983 _M_n = 0; 984 } 985 986 /** 987 * @brief Reseeds the %discard_block_engine object with the default 988 * seed for the underlying base class generator engine. 989 */ 990 void 991 seed(result_type __s) 992 { 993 _M_b.seed(__s); 994 _M_n = 0; 995 } 996 997 /** 998 * @brief Reseeds the %discard_block_engine object with the given seed 999 * sequence. 1000 * @param __q A seed generator function. 1001 */ 1002 template
1003 _If_seed_seq<_Sseq> 1004 seed(_Sseq& __q) 1005 { 1006 _M_b.seed(__q); 1007 _M_n = 0; 1008 } 1009 1010 /** 1011 * @brief Gets a const reference to the underlying generator engine 1012 * object. 1013 */ 1014 const _RandomNumberEngine& 1015 base() const noexcept 1016 { return _M_b; } 1017 1018 /** 1019 * @brief Gets the minimum value in the generated random number range. 1020 */ 1021 static constexpr result_type 1022 min() 1023 { return _RandomNumberEngine::min(); } 1024 1025 /** 1026 * @brief Gets the maximum value in the generated random number range. 1027 */ 1028 static constexpr result_type 1029 max() 1030 { return _RandomNumberEngine::max(); } 1031 1032 /** 1033 * @brief Discard a sequence of random numbers. 1034 */ 1035 void 1036 discard(unsigned long long __z) 1037 { 1038 for (; __z != 0ULL; --__z) 1039 (*this)(); 1040 } 1041 1042 /** 1043 * @brief Gets the next value in the generated random number sequence. 1044 */ 1045 result_type 1046 operator()(); 1047 1048 /** 1049 * @brief Compares two %discard_block_engine random number generator 1050 * objects of the same type for equality. 1051 * 1052 * @param __lhs A %discard_block_engine random number generator object. 1053 * @param __rhs Another %discard_block_engine random number generator 1054 * object. 1055 * 1056 * @returns true if the infinite sequences of generated values 1057 * would be equal, false otherwise. 1058 */ 1059 friend bool 1060 operator==(const discard_block_engine& __lhs, 1061 const discard_block_engine& __rhs) 1062 { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; } 1063 1064 /** 1065 * @brief Inserts the current state of a %discard_block_engine random 1066 * number generator engine @p __x into the output stream 1067 * @p __os. 1068 * 1069 * @param __os An output stream. 1070 * @param __x A %discard_block_engine random number generator engine. 1071 * 1072 * @returns The output stream with the state of @p __x inserted or in 1073 * an error state. 1074 */ 1075 template
1077 friend std::basic_ostream<_CharT, _Traits>& 1078 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1079 const std::discard_block_engine<_RandomNumberEngine1, 1080 __p1, __r1>& __x); 1081 1082 /** 1083 * @brief Extracts the current state of a % subtract_with_carry_engine 1084 * random number generator engine @p __x from the input stream 1085 * @p __is. 1086 * 1087 * @param __is An input stream. 1088 * @param __x A %discard_block_engine random number generator engine. 1089 * 1090 * @returns The input stream with the state of @p __x extracted or in 1091 * an error state. 1092 */ 1093 template
1095 friend std::basic_istream<_CharT, _Traits>& 1096 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1097 std::discard_block_engine<_RandomNumberEngine1, 1098 __p1, __r1>& __x); 1099 1100 private: 1101 _RandomNumberEngine _M_b; 1102 size_t _M_n; 1103 }; 1104 1105 #if __cpp_impl_three_way_comparison < 201907L 1106 /** 1107 * @brief Compares two %discard_block_engine random number generator 1108 * objects of the same type for inequality. 1109 * 1110 * @param __lhs A %discard_block_engine random number generator object. 1111 * @param __rhs Another %discard_block_engine random number generator 1112 * object. 1113 * 1114 * @returns true if the infinite sequences of generated values 1115 * would be different, false otherwise. 1116 */ 1117 template
1118 inline bool 1119 operator!=(const std::discard_block_engine<_RandomNumberEngine, __p, 1120 __r>& __lhs, 1121 const std::discard_block_engine<_RandomNumberEngine, __p, 1122 __r>& __rhs) 1123 { return !(__lhs == __rhs); } 1124 #endif 1125 1126 /** 1127 * Produces random numbers by combining random numbers from some base 1128 * engine to produce random numbers with a specified number of bits @p __w. 1129 * 1130 * @headerfile random 1131 * @since C++11 1132 */ 1133 template
1134 class independent_bits_engine 1135 { 1136 static_assert(std::is_unsigned<_UIntType>::value, 1137 "result_type must be an unsigned integral type"); 1138 static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits, 1139 "template argument substituting __w out of bounds"); 1140 1141 template
1142 using _If_seed_seq 1143 = __detail::_If_seed_seq_for<_Sseq, independent_bits_engine, 1144 _UIntType>; 1145 1146 public: 1147 /** The type of the generated random value. */ 1148 typedef _UIntType result_type; 1149 1150 /** 1151 * @brief Constructs a default %independent_bits_engine engine. 1152 * 1153 * The underlying engine is default constructed as well. 1154 */ 1155 independent_bits_engine() 1156 : _M_b() { } 1157 1158 /** 1159 * @brief Copy constructs a %independent_bits_engine engine. 1160 * 1161 * Copies an existing base class random number generator. 1162 * @param __rng An existing (base class) engine object. 1163 */ 1164 explicit 1165 independent_bits_engine(const _RandomNumberEngine& __rng) 1166 : _M_b(__rng) { } 1167 1168 /** 1169 * @brief Move constructs a %independent_bits_engine engine. 1170 * 1171 * Copies an existing base class random number generator. 1172 * @param __rng An existing (base class) engine object. 1173 */ 1174 explicit 1175 independent_bits_engine(_RandomNumberEngine&& __rng) 1176 : _M_b(std::move(__rng)) { } 1177 1178 /** 1179 * @brief Seed constructs a %independent_bits_engine engine. 1180 * 1181 * Constructs the underlying generator engine seeded with @p __s. 1182 * @param __s A seed value for the base class engine. 1183 */ 1184 explicit 1185 independent_bits_engine(result_type __s) 1186 : _M_b(__s) { } 1187 1188 /** 1189 * @brief Generator construct a %independent_bits_engine engine. 1190 * 1191 * @param __q A seed sequence. 1192 */ 1193 template
> 1194 explicit 1195 independent_bits_engine(_Sseq& __q) 1196 : _M_b(__q) 1197 { } 1198 1199 /** 1200 * @brief Reseeds the %independent_bits_engine object with the default 1201 * seed for the underlying base class generator engine. 1202 */ 1203 void 1204 seed() 1205 { _M_b.seed(); } 1206 1207 /** 1208 * @brief Reseeds the %independent_bits_engine object with the default 1209 * seed for the underlying base class generator engine. 1210 */ 1211 void 1212 seed(result_type __s) 1213 { _M_b.seed(__s); } 1214 1215 /** 1216 * @brief Reseeds the %independent_bits_engine object with the given 1217 * seed sequence. 1218 * @param __q A seed generator function. 1219 */ 1220 template
1221 _If_seed_seq<_Sseq> 1222 seed(_Sseq& __q) 1223 { _M_b.seed(__q); } 1224 1225 /** 1226 * @brief Gets a const reference to the underlying generator engine 1227 * object. 1228 */ 1229 const _RandomNumberEngine& 1230 base() const noexcept 1231 { return _M_b; } 1232 1233 /** 1234 * @brief Gets the minimum value in the generated random number range. 1235 */ 1236 static constexpr result_type 1237 min() 1238 { return 0U; } 1239 1240 /** 1241 * @brief Gets the maximum value in the generated random number range. 1242 */ 1243 static constexpr result_type 1244 max() 1245 { return __detail::_Shift<_UIntType, __w>::__value - 1; } 1246 1247 /** 1248 * @brief Discard a sequence of random numbers. 1249 */ 1250 void 1251 discard(unsigned long long __z) 1252 { 1253 for (; __z != 0ULL; --__z) 1254 (*this)(); 1255 } 1256 1257 /** 1258 * @brief Gets the next value in the generated random number sequence. 1259 */ 1260 result_type 1261 operator()(); 1262 1263 /** 1264 * @brief Compares two %independent_bits_engine random number generator 1265 * objects of the same type for equality. 1266 * 1267 * @param __lhs A %independent_bits_engine random number generator 1268 * object. 1269 * @param __rhs Another %independent_bits_engine random number generator 1270 * object. 1271 * 1272 * @returns true if the infinite sequences of generated values 1273 * would be equal, false otherwise. 1274 */ 1275 friend bool 1276 operator==(const independent_bits_engine& __lhs, 1277 const independent_bits_engine& __rhs) 1278 { return __lhs._M_b == __rhs._M_b; } 1279 1280 /** 1281 * @brief Extracts the current state of a % subtract_with_carry_engine 1282 * random number generator engine @p __x from the input stream 1283 * @p __is. 1284 * 1285 * @param __is An input stream. 1286 * @param __x A %independent_bits_engine random number generator 1287 * engine. 1288 * 1289 * @returns The input stream with the state of @p __x extracted or in 1290 * an error state. 1291 */ 1292 template
1293 friend std::basic_istream<_CharT, _Traits>& 1294 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1295 std::independent_bits_engine<_RandomNumberEngine, 1296 __w, _UIntType>& __x) 1297 { 1298 __is >> __x._M_b; 1299 return __is; 1300 } 1301 1302 private: 1303 _RandomNumberEngine _M_b; 1304 }; 1305 1306 #if __cpp_impl_three_way_comparison < 201907L 1307 /** 1308 * @brief Compares two %independent_bits_engine random number generator 1309 * objects of the same type for inequality. 1310 * 1311 * @param __lhs A %independent_bits_engine random number generator 1312 * object. 1313 * @param __rhs Another %independent_bits_engine random number generator 1314 * object. 1315 * 1316 * @returns true if the infinite sequences of generated values 1317 * would be different, false otherwise. 1318 */ 1319 template
1320 inline bool 1321 operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w, 1322 _UIntType>& __lhs, 1323 const std::independent_bits_engine<_RandomNumberEngine, __w, 1324 _UIntType>& __rhs) 1325 { return !(__lhs == __rhs); } 1326 #endif 1327 1328 /** 1329 * @brief Inserts the current state of a %independent_bits_engine random 1330 * number generator engine @p __x into the output stream @p __os. 1331 * 1332 * @param __os An output stream. 1333 * @param __x A %independent_bits_engine random number generator engine. 1334 * 1335 * @returns The output stream with the state of @p __x inserted or in 1336 * an error state. 1337 */ 1338 template
1340 std::basic_ostream<_CharT, _Traits>& 1341 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1342 const std::independent_bits_engine<_RandomNumberEngine, 1343 __w, _UIntType>& __x) 1344 { 1345 __os << __x.base(); 1346 return __os; 1347 } 1348 1349 1350 /** 1351 * @brief Produces random numbers by reordering random numbers from some 1352 * base engine. 1353 * 1354 * The values from the base engine are stored in a sequence of size @p __k 1355 * and shuffled by an algorithm that depends on those values. 1356 * 1357 * @headerfile random 1358 * @since C++11 1359 */ 1360 template
1361 class shuffle_order_engine 1362 { 1363 static_assert(1u <= __k, "template argument substituting " 1364 "__k out of bound"); 1365 1366 public: 1367 /** The type of the generated random value. */ 1368 typedef typename _RandomNumberEngine::result_type result_type; 1369 1370 template
1371 using _If_seed_seq 1372 = __detail::_If_seed_seq_for<_Sseq, shuffle_order_engine, 1373 result_type>; 1374 1375 static constexpr size_t table_size = __k; 1376 1377 /** 1378 * @brief Constructs a default %shuffle_order_engine engine. 1379 * 1380 * The underlying engine is default constructed as well. 1381 */ 1382 shuffle_order_engine() 1383 : _M_b() 1384 { _M_initialize(); } 1385 1386 /** 1387 * @brief Copy constructs a %shuffle_order_engine engine. 1388 * 1389 * Copies an existing base class random number generator. 1390 * @param __rng An existing (base class) engine object. 1391 */ 1392 explicit 1393 shuffle_order_engine(const _RandomNumberEngine& __rng) 1394 : _M_b(__rng) 1395 { _M_initialize(); } 1396 1397 /** 1398 * @brief Move constructs a %shuffle_order_engine engine. 1399 * 1400 * Copies an existing base class random number generator. 1401 * @param __rng An existing (base class) engine object. 1402 */ 1403 explicit 1404 shuffle_order_engine(_RandomNumberEngine&& __rng) 1405 : _M_b(std::move(__rng)) 1406 { _M_initialize(); } 1407 1408 /** 1409 * @brief Seed constructs a %shuffle_order_engine engine. 1410 * 1411 * Constructs the underlying generator engine seeded with @p __s. 1412 * @param __s A seed value for the base class engine. 1413 */ 1414 explicit 1415 shuffle_order_engine(result_type __s) 1416 : _M_b(__s) 1417 { _M_initialize(); } 1418 1419 /** 1420 * @brief Generator construct a %shuffle_order_engine engine. 1421 * 1422 * @param __q A seed sequence. 1423 */ 1424 template
> 1425 explicit 1426 shuffle_order_engine(_Sseq& __q) 1427 : _M_b(__q) 1428 { _M_initialize(); } 1429 1430 /** 1431 * @brief Reseeds the %shuffle_order_engine object with the default seed 1432 for the underlying base class generator engine. 1433 */ 1434 void 1435 seed() 1436 { 1437 _M_b.seed(); 1438 _M_initialize(); 1439 } 1440 1441 /** 1442 * @brief Reseeds the %shuffle_order_engine object with the default seed 1443 * for the underlying base class generator engine. 1444 */ 1445 void 1446 seed(result_type __s) 1447 { 1448 _M_b.seed(__s); 1449 _M_initialize(); 1450 } 1451 1452 /** 1453 * @brief Reseeds the %shuffle_order_engine object with the given seed 1454 * sequence. 1455 * @param __q A seed generator function. 1456 */ 1457 template
1458 _If_seed_seq<_Sseq> 1459 seed(_Sseq& __q) 1460 { 1461 _M_b.seed(__q); 1462 _M_initialize(); 1463 } 1464 1465 /** 1466 * Gets a const reference to the underlying generator engine object. 1467 */ 1468 const _RandomNumberEngine& 1469 base() const noexcept 1470 { return _M_b; } 1471 1472 /** 1473 * Gets the minimum value in the generated random number range. 1474 */ 1475 static constexpr result_type 1476 min() 1477 { return _RandomNumberEngine::min(); } 1478 1479 /** 1480 * Gets the maximum value in the generated random number range. 1481 */ 1482 static constexpr result_type 1483 max() 1484 { return _RandomNumberEngine::max(); } 1485 1486 /** 1487 * Discard a sequence of random numbers. 1488 */ 1489 void 1490 discard(unsigned long long __z) 1491 { 1492 for (; __z != 0ULL; --__z) 1493 (*this)(); 1494 } 1495 1496 /** 1497 * Gets the next value in the generated random number sequence. 1498 */ 1499 result_type 1500 operator()(); 1501 1502 /** 1503 * Compares two %shuffle_order_engine random number generator objects 1504 * of the same type for equality. 1505 * 1506 * @param __lhs A %shuffle_order_engine random number generator object. 1507 * @param __rhs Another %shuffle_order_engine random number generator 1508 * object. 1509 * 1510 * @returns true if the infinite sequences of generated values 1511 * would be equal, false otherwise. 1512 */ 1513 friend bool 1514 operator==(const shuffle_order_engine& __lhs, 1515 const shuffle_order_engine& __rhs) 1516 { return (__lhs._M_b == __rhs._M_b 1517 && std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v) 1518 && __lhs._M_y == __rhs._M_y); } 1519 1520 /** 1521 * @brief Inserts the current state of a %shuffle_order_engine random 1522 * number generator engine @p __x into the output stream 1523 @p __os. 1524 * 1525 * @param __os An output stream. 1526 * @param __x A %shuffle_order_engine random number generator engine. 1527 * 1528 * @returns The output stream with the state of @p __x inserted or in 1529 * an error state. 1530 */ 1531 template
1533 friend std::basic_ostream<_CharT, _Traits>& 1534 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 1535 const std::shuffle_order_engine<_RandomNumberEngine1, 1536 __k1>& __x); 1537 1538 /** 1539 * @brief Extracts the current state of a % subtract_with_carry_engine 1540 * random number generator engine @p __x from the input stream 1541 * @p __is. 1542 * 1543 * @param __is An input stream. 1544 * @param __x A %shuffle_order_engine random number generator engine. 1545 * 1546 * @returns The input stream with the state of @p __x extracted or in 1547 * an error state. 1548 */ 1549 template
1551 friend std::basic_istream<_CharT, _Traits>& 1552 operator>>(std::basic_istream<_CharT, _Traits>& __is, 1553 std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x); 1554 1555 private: 1556 void _M_initialize() 1557 { 1558 for (size_t __i = 0; __i < __k; ++__i) 1559 _M_v[__i] = _M_b(); 1560 _M_y = _M_b(); 1561 } 1562 1563 _RandomNumberEngine _M_b; 1564 result_type _M_v[__k]; 1565 result_type _M_y; 1566 }; 1567 1568 #if __cpp_impl_three_way_comparison < 201907L 1569 /** 1570 * Compares two %shuffle_order_engine random number generator objects 1571 * of the same type for inequality. 1572 * 1573 * @param __lhs A %shuffle_order_engine random number generator object. 1574 * @param __rhs Another %shuffle_order_engine random number generator 1575 * object. 1576 * 1577 * @returns true if the infinite sequences of generated values 1578 * would be different, false otherwise. 1579 */ 1580 template
1581 inline bool 1582 operator!=(const std::shuffle_order_engine<_RandomNumberEngine, 1583 __k>& __lhs, 1584 const std::shuffle_order_engine<_RandomNumberEngine, 1585 __k>& __rhs) 1586 { return !(__lhs == __rhs); } 1587 #endif 1588 1589 /** 1590 * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller. 1591 */ 1592 typedef linear_congruential_engine
1593 minstd_rand0; 1594 1595 /** 1596 * An alternative LCR (Lehmer Generator function). 1597 */ 1598 typedef linear_congruential_engine
1599 minstd_rand; 1600 1601 /** 1602 * The classic Mersenne Twister. 1603 * 1604 * Reference: 1605 * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally 1606 * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions 1607 * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. 1608 */ 1609 typedef mersenne_twister_engine< 1610 uint_fast32_t, 1611 32, 624, 397, 31, 1612 0x9908b0dfUL, 11, 1613 0xffffffffUL, 7, 1614 0x9d2c5680UL, 15, 1615 0xefc60000UL, 18, 1812433253UL> mt19937; 1616 1617 /** 1618 * An alternative Mersenne Twister. 1619 */ 1620 typedef mersenne_twister_engine< 1621 uint_fast64_t, 1622 64, 312, 156, 31, 1623 0xb5026f5aa96619e9ULL, 29, 1624 0x5555555555555555ULL, 17, 1625 0x71d67fffeda60000ULL, 37, 1626 0xfff7eee000000000ULL, 43, 1627 6364136223846793005ULL> mt19937_64; 1628 1629 typedef subtract_with_carry_engine
1630 ranlux24_base; 1631 1632 typedef subtract_with_carry_engine
1633 ranlux48_base; 1634 1635 typedef discard_block_engine
ranlux24; 1636 1637 typedef discard_block_engine
ranlux48; 1638 1639 typedef shuffle_order_engine
knuth_b; 1640 1641 typedef minstd_rand0 default_random_engine; 1642 1643 /** 1644 * A standard interface to a platform-specific non-deterministic 1645 * random number generator (if any are available). 1646 * 1647 * @headerfile random 1648 * @since C++11 1649 */ 1650 class random_device 1651 { 1652 public: 1653 /** The type of the generated random value. */ 1654 typedef unsigned int result_type; 1655 1656 // constructors, destructors and member functions 1657 1658 random_device() { _M_init("default"); } 1659 1660 explicit 1661 random_device(const std::string& __token) { _M_init(__token); } 1662 1663 ~random_device() 1664 { _M_fini(); } 1665 1666 static constexpr result_type 1667 min() 1668 { return std::numeric_limits
::min(); } 1669 1670 static constexpr result_type 1671 max() 1672 { return std::numeric_limits
::max(); } 1673 1674 double 1675 entropy() const noexcept 1676 { return this->_M_getentropy(); } 1677 1678 result_type 1679 operator()() 1680 { return this->_M_getval(); } 1681 1682 // No copy functions. 1683 random_device(const random_device&) = delete; 1684 void operator=(const random_device&) = delete; 1685 1686 private: 1687 1688 void _M_init(const std::string& __token); 1689 void _M_init_pretr1(const std::string& __token); 1690 void _M_fini(); 1691 1692 result_type _M_getval(); 1693 result_type _M_getval_pretr1(); 1694 double _M_getentropy() const noexcept; 1695 1696 void _M_init(const char*, size_t); // not exported from the shared library 1697 1698 __extension__ union 1699 { 1700 struct 1701 { 1702 void* _M_file; 1703 result_type (*_M_func)(void*); 1704 int _M_fd; 1705 }; 1706 mt19937 _M_mt; 1707 }; 1708 }; 1709 1710 /// @} group random_generators 1711 1712 /** 1713 * @addtogroup random_distributions Random Number Distributions 1714 * @ingroup random 1715 * @{ 1716 */ 1717 1718 /** 1719 * @addtogroup random_distributions_uniform Uniform Distributions 1720 * @ingroup random_distributions 1721 * @{ 1722 */ 1723 1724 // std::uniform_int_distribution is defined in
1725 1726 #if __cpp_impl_three_way_comparison < 201907L 1727 /** 1728 * @brief Return true if two uniform integer distributions have 1729 * different parameters. 1730 */ 1731 template
1732 inline bool 1733 operator!=(const std::uniform_int_distribution<_IntType>& __d1, 1734 const std::uniform_int_distribution<_IntType>& __d2) 1735 { return !(__d1 == __d2); } 1736 #endif 1737 1738 /** 1739 * @brief Inserts a %uniform_int_distribution random number 1740 * distribution @p __x into the output stream @p os. 1741 * 1742 * @param __os An output stream. 1743 * @param __x A %uniform_int_distribution random number distribution. 1744 * 1745 * @returns The output stream with the state of @p __x inserted or in 1746 * an error state. 1747 */ 1748 template
1749 std::basic_ostream<_CharT, _Traits>& 1750 operator<<(std::basic_ostream<_CharT, _Traits>&, 1751 const std::uniform_int_distribution<_IntType>&); 1752 1753 /** 1754 * @brief Extracts a %uniform_int_distribution random number distribution 1755 * @p __x from the input stream @p __is. 1756 * 1757 * @param __is An input stream. 1758 * @param __x A %uniform_int_distribution random number generator engine. 1759 * 1760 * @returns The input stream with @p __x extracted or in an error state. 1761 */ 1762 template
1763 std::basic_istream<_CharT, _Traits>& 1764 operator>>(std::basic_istream<_CharT, _Traits>&, 1765 std::uniform_int_distribution<_IntType>&); 1766 1767 1768 /** 1769 * @brief Uniform continuous distribution for random numbers. 1770 * 1771 * A continuous random distribution on the range [min, max) with equal 1772 * probability throughout the range. The URNG should be real-valued and 1773 * deliver number in the range [0, 1). 1774 * 1775 * @headerfile random 1776 * @since C++11 1777 */ 1778 template
1779 class uniform_real_distribution 1780 { 1781 static_assert(std::is_floating_point<_RealType>::value, 1782 "result_type must be a floating point type"); 1783 1784 public: 1785 /** The type of the range of the distribution. */ 1786 typedef _RealType result_type; 1787 1788 /** Parameter type. */ 1789 struct param_type 1790 { 1791 typedef uniform_real_distribution<_RealType> distribution_type; 1792 1793 param_type() : param_type(0) { } 1794 1795 explicit 1796 param_type(_RealType __a, _RealType __b = _RealType(1)) 1797 : _M_a(__a), _M_b(__b) 1798 { 1799 __glibcxx_assert(_M_a <= _M_b); 1800 } 1801 1802 result_type 1803 a() const 1804 { return _M_a; } 1805 1806 result_type 1807 b() const 1808 { return _M_b; } 1809 1810 friend bool 1811 operator==(const param_type& __p1, const param_type& __p2) 1812 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } 1813 1814 #if __cpp_impl_three_way_comparison < 201907L 1815 friend bool 1816 operator!=(const param_type& __p1, const param_type& __p2) 1817 { return !(__p1 == __p2); } 1818 #endif 1819 1820 private: 1821 _RealType _M_a; 1822 _RealType _M_b; 1823 }; 1824 1825 public: 1826 /** 1827 * @brief Constructs a uniform_real_distribution object. 1828 * 1829 * The lower bound is set to 0.0 and the upper bound to 1.0 1830 */ 1831 uniform_real_distribution() : uniform_real_distribution(0.0) { } 1832 1833 /** 1834 * @brief Constructs a uniform_real_distribution object. 1835 * 1836 * @param __a [IN] The lower bound of the distribution. 1837 * @param __b [IN] The upper bound of the distribution. 1838 */ 1839 explicit 1840 uniform_real_distribution(_RealType __a, _RealType __b = _RealType(1)) 1841 : _M_param(__a, __b) 1842 { } 1843 1844 explicit 1845 uniform_real_distribution(const param_type& __p) 1846 : _M_param(__p) 1847 { } 1848 1849 /** 1850 * @brief Resets the distribution state. 1851 * 1852 * Does nothing for the uniform real distribution. 1853 */ 1854 void 1855 reset() { } 1856 1857 result_type 1858 a() const 1859 { return _M_param.a(); } 1860 1861 result_type 1862 b() const 1863 { return _M_param.b(); } 1864 1865 /** 1866 * @brief Returns the parameter set of the distribution. 1867 */ 1868 param_type 1869 param() const 1870 { return _M_param; } 1871 1872 /** 1873 * @brief Sets the parameter set of the distribution. 1874 * @param __param The new parameter set of the distribution. 1875 */ 1876 void 1877 param(const param_type& __param) 1878 { _M_param = __param; } 1879 1880 /** 1881 * @brief Returns the inclusive lower bound of the distribution range. 1882 */ 1883 result_type 1884 min() const 1885 { return this->a(); } 1886 1887 /** 1888 * @brief Returns the inclusive upper bound of the distribution range. 1889 */ 1890 result_type 1891 max() const 1892 { return this->b(); } 1893 1894 /** 1895 * @brief Generating functions. 1896 */ 1897 template
1898 result_type 1899 operator()(_UniformRandomNumberGenerator& __urng) 1900 { return this->operator()(__urng, _M_param); } 1901 1902 template
1903 result_type 1904 operator()(_UniformRandomNumberGenerator& __urng, 1905 const param_type& __p) 1906 { 1907 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 1908 __aurng(__urng); 1909 return (__aurng() * (__p.b() - __p.a())) + __p.a(); 1910 } 1911 1912 template
1914 void 1915 __generate(_ForwardIterator __f, _ForwardIterator __t, 1916 _UniformRandomNumberGenerator& __urng) 1917 { this->__generate(__f, __t, __urng, _M_param); } 1918 1919 template
1921 void 1922 __generate(_ForwardIterator __f, _ForwardIterator __t, 1923 _UniformRandomNumberGenerator& __urng, 1924 const param_type& __p) 1925 { this->__generate_impl(__f, __t, __urng, __p); } 1926 1927 template
1928 void 1929 __generate(result_type* __f, result_type* __t, 1930 _UniformRandomNumberGenerator& __urng, 1931 const param_type& __p) 1932 { this->__generate_impl(__f, __t, __urng, __p); } 1933 1934 /** 1935 * @brief Return true if two uniform real distributions have 1936 * the same parameters. 1937 */ 1938 friend bool 1939 operator==(const uniform_real_distribution& __d1, 1940 const uniform_real_distribution& __d2) 1941 { return __d1._M_param == __d2._M_param; } 1942 1943 private: 1944 template
1946 void 1947 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1948 _UniformRandomNumberGenerator& __urng, 1949 const param_type& __p); 1950 1951 param_type _M_param; 1952 }; 1953 1954 #if __cpp_impl_three_way_comparison < 201907L 1955 /** 1956 * @brief Return true if two uniform real distributions have 1957 * different parameters. 1958 */ 1959 template
1960 inline bool 1961 operator!=(const std::uniform_real_distribution<_IntType>& __d1, 1962 const std::uniform_real_distribution<_IntType>& __d2) 1963 { return !(__d1 == __d2); } 1964 #endif 1965 1966 /** 1967 * @brief Inserts a %uniform_real_distribution random number 1968 * distribution @p __x into the output stream @p __os. 1969 * 1970 * @param __os An output stream. 1971 * @param __x A %uniform_real_distribution random number distribution. 1972 * 1973 * @returns The output stream with the state of @p __x inserted or in 1974 * an error state. 1975 */ 1976 template
1977 std::basic_ostream<_CharT, _Traits>& 1978 operator<<(std::basic_ostream<_CharT, _Traits>&, 1979 const std::uniform_real_distribution<_RealType>&); 1980 1981 /** 1982 * @brief Extracts a %uniform_real_distribution random number distribution 1983 * @p __x from the input stream @p __is. 1984 * 1985 * @param __is An input stream. 1986 * @param __x A %uniform_real_distribution random number generator engine. 1987 * 1988 * @returns The input stream with @p __x extracted or in an error state. 1989 */ 1990 template
1991 std::basic_istream<_CharT, _Traits>& 1992 operator>>(std::basic_istream<_CharT, _Traits>&, 1993 std::uniform_real_distribution<_RealType>&); 1994 1995 /// @} group random_distributions_uniform 1996 1997 /** 1998 * @addtogroup random_distributions_normal Normal Distributions 1999 * @ingroup random_distributions 2000 * @{ 2001 */ 2002 2003 /** 2004 * @brief A normal continuous distribution for random numbers. 2005 * 2006 * The formula for the normal probability density function is 2007 * @f[ 2008 * p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}} 2009 * e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } 2010 * @f] 2011 * 2012 * @headerfile random 2013 * @since C++11 2014 */ 2015 template
2016 class normal_distribution 2017 { 2018 static_assert(std::is_floating_point<_RealType>::value, 2019 "result_type must be a floating point type"); 2020 2021 public: 2022 /** The type of the range of the distribution. */ 2023 typedef _RealType result_type; 2024 2025 /** Parameter type. */ 2026 struct param_type 2027 { 2028 typedef normal_distribution<_RealType> distribution_type; 2029 2030 param_type() : param_type(0.0) { } 2031 2032 explicit 2033 param_type(_RealType __mean, _RealType __stddev = _RealType(1)) 2034 : _M_mean(__mean), _M_stddev(__stddev) 2035 { 2036 __glibcxx_assert(_M_stddev > _RealType(0)); 2037 } 2038 2039 _RealType 2040 mean() const 2041 { return _M_mean; } 2042 2043 _RealType 2044 stddev() const 2045 { return _M_stddev; } 2046 2047 friend bool 2048 operator==(const param_type& __p1, const param_type& __p2) 2049 { return (__p1._M_mean == __p2._M_mean 2050 && __p1._M_stddev == __p2._M_stddev); } 2051 2052 #if __cpp_impl_three_way_comparison < 201907L 2053 friend bool 2054 operator!=(const param_type& __p1, const param_type& __p2) 2055 { return !(__p1 == __p2); } 2056 #endif 2057 2058 private: 2059 _RealType _M_mean; 2060 _RealType _M_stddev; 2061 }; 2062 2063 public: 2064 normal_distribution() : normal_distribution(0.0) { } 2065 2066 /** 2067 * Constructs a normal distribution with parameters @f$mean@f$ and 2068 * standard deviation. 2069 */ 2070 explicit 2071 normal_distribution(result_type __mean, 2072 result_type __stddev = result_type(1)) 2073 : _M_param(__mean, __stddev) 2074 { } 2075 2076 explicit 2077 normal_distribution(const param_type& __p) 2078 : _M_param(__p) 2079 { } 2080 2081 /** 2082 * @brief Resets the distribution state. 2083 */ 2084 void 2085 reset() 2086 { _M_saved_available = false; } 2087 2088 /** 2089 * @brief Returns the mean of the distribution. 2090 */ 2091 _RealType 2092 mean() const 2093 { return _M_param.mean(); } 2094 2095 /** 2096 * @brief Returns the standard deviation of the distribution. 2097 */ 2098 _RealType 2099 stddev() const 2100 { return _M_param.stddev(); } 2101 2102 /** 2103 * @brief Returns the parameter set of the distribution. 2104 */ 2105 param_type 2106 param() const 2107 { return _M_param; } 2108 2109 /** 2110 * @brief Sets the parameter set of the distribution. 2111 * @param __param The new parameter set of the distribution. 2112 */ 2113 void 2114 param(const param_type& __param) 2115 { _M_param = __param; } 2116 2117 /** 2118 * @brief Returns the greatest lower bound value of the distribution. 2119 */ 2120 result_type 2121 min() const 2122 { return std::numeric_limits
::lowest(); } 2123 2124 /** 2125 * @brief Returns the least upper bound value of the distribution. 2126 */ 2127 result_type 2128 max() const 2129 { return std::numeric_limits
::max(); } 2130 2131 /** 2132 * @brief Generating functions. 2133 */ 2134 template
2135 result_type 2136 operator()(_UniformRandomNumberGenerator& __urng) 2137 { return this->operator()(__urng, _M_param); } 2138 2139 template
2140 result_type 2141 operator()(_UniformRandomNumberGenerator& __urng, 2142 const param_type& __p); 2143 2144 template
2146 void 2147 __generate(_ForwardIterator __f, _ForwardIterator __t, 2148 _UniformRandomNumberGenerator& __urng) 2149 { this->__generate(__f, __t, __urng, _M_param); } 2150 2151 template
2153 void 2154 __generate(_ForwardIterator __f, _ForwardIterator __t, 2155 _UniformRandomNumberGenerator& __urng, 2156 const param_type& __p) 2157 { this->__generate_impl(__f, __t, __urng, __p); } 2158 2159 template
2160 void 2161 __generate(result_type* __f, result_type* __t, 2162 _UniformRandomNumberGenerator& __urng, 2163 const param_type& __p) 2164 { this->__generate_impl(__f, __t, __urng, __p); } 2165 2166 /** 2167 * @brief Return true if two normal distributions have 2168 * the same parameters and the sequences that would 2169 * be generated are equal. 2170 */ 2171 template
2172 friend bool 2173 operator==(const std::normal_distribution<_RealType1>& __d1, 2174 const std::normal_distribution<_RealType1>& __d2); 2175 2176 /** 2177 * @brief Inserts a %normal_distribution random number distribution 2178 * @p __x into the output stream @p __os. 2179 * 2180 * @param __os An output stream. 2181 * @param __x A %normal_distribution random number distribution. 2182 * 2183 * @returns The output stream with the state of @p __x inserted or in 2184 * an error state. 2185 */ 2186 template
2187 friend std::basic_ostream<_CharT, _Traits>& 2188 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2189 const std::normal_distribution<_RealType1>& __x); 2190 2191 /** 2192 * @brief Extracts a %normal_distribution random number distribution 2193 * @p __x from the input stream @p __is. 2194 * 2195 * @param __is An input stream. 2196 * @param __x A %normal_distribution random number generator engine. 2197 * 2198 * @returns The input stream with @p __x extracted or in an error 2199 * state. 2200 */ 2201 template
2202 friend std::basic_istream<_CharT, _Traits>& 2203 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2204 std::normal_distribution<_RealType1>& __x); 2205 2206 private: 2207 template
2209 void 2210 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2211 _UniformRandomNumberGenerator& __urng, 2212 const param_type& __p); 2213 2214 param_type _M_param; 2215 result_type _M_saved = 0; 2216 bool _M_saved_available = false; 2217 }; 2218 2219 #if __cpp_impl_three_way_comparison < 201907L 2220 /** 2221 * @brief Return true if two normal distributions are different. 2222 */ 2223 template
2224 inline bool 2225 operator!=(const std::normal_distribution<_RealType>& __d1, 2226 const std::normal_distribution<_RealType>& __d2) 2227 { return !(__d1 == __d2); } 2228 #endif 2229 2230 /** 2231 * @brief A lognormal_distribution random number distribution. 2232 * 2233 * The formula for the normal probability mass function is 2234 * @f[ 2235 * p(x|m,s) = \frac{1}{sx\sqrt{2\pi}} 2236 * \exp{-\frac{(\ln{x} - m)^2}{2s^2}} 2237 * @f] 2238 * 2239 * @headerfile random 2240 * @since C++11 2241 */ 2242 template
2243 class lognormal_distribution 2244 { 2245 static_assert(std::is_floating_point<_RealType>::value, 2246 "result_type must be a floating point type"); 2247 2248 public: 2249 /** The type of the range of the distribution. */ 2250 typedef _RealType result_type; 2251 2252 /** Parameter type. */ 2253 struct param_type 2254 { 2255 typedef lognormal_distribution<_RealType> distribution_type; 2256 2257 param_type() : param_type(0.0) { } 2258 2259 explicit 2260 param_type(_RealType __m, _RealType __s = _RealType(1)) 2261 : _M_m(__m), _M_s(__s) 2262 { } 2263 2264 _RealType 2265 m() const 2266 { return _M_m; } 2267 2268 _RealType 2269 s() const 2270 { return _M_s; } 2271 2272 friend bool 2273 operator==(const param_type& __p1, const param_type& __p2) 2274 { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; } 2275 2276 #if __cpp_impl_three_way_comparison < 201907L 2277 friend bool 2278 operator!=(const param_type& __p1, const param_type& __p2) 2279 { return !(__p1 == __p2); } 2280 #endif 2281 2282 private: 2283 _RealType _M_m; 2284 _RealType _M_s; 2285 }; 2286 2287 lognormal_distribution() : lognormal_distribution(0.0) { } 2288 2289 explicit 2290 lognormal_distribution(_RealType __m, _RealType __s = _RealType(1)) 2291 : _M_param(__m, __s), _M_nd() 2292 { } 2293 2294 explicit 2295 lognormal_distribution(const param_type& __p) 2296 : _M_param(__p), _M_nd() 2297 { } 2298 2299 /** 2300 * Resets the distribution state. 2301 */ 2302 void 2303 reset() 2304 { _M_nd.reset(); } 2305 2306 /** 2307 * 2308 */ 2309 _RealType 2310 m() const 2311 { return _M_param.m(); } 2312 2313 _RealType 2314 s() const 2315 { return _M_param.s(); } 2316 2317 /** 2318 * @brief Returns the parameter set of the distribution. 2319 */ 2320 param_type 2321 param() const 2322 { return _M_param; } 2323 2324 /** 2325 * @brief Sets the parameter set of the distribution. 2326 * @param __param The new parameter set of the distribution. 2327 */ 2328 void 2329 param(const param_type& __param) 2330 { _M_param = __param; } 2331 2332 /** 2333 * @brief Returns the greatest lower bound value of the distribution. 2334 */ 2335 result_type 2336 min() const 2337 { return result_type(0); } 2338 2339 /** 2340 * @brief Returns the least upper bound value of the distribution. 2341 */ 2342 result_type 2343 max() const 2344 { return std::numeric_limits
::max(); } 2345 2346 /** 2347 * @brief Generating functions. 2348 */ 2349 template
2350 result_type 2351 operator()(_UniformRandomNumberGenerator& __urng) 2352 { return this->operator()(__urng, _M_param); } 2353 2354 template
2355 result_type 2356 operator()(_UniformRandomNumberGenerator& __urng, 2357 const param_type& __p) 2358 { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); } 2359 2360 template
2362 void 2363 __generate(_ForwardIterator __f, _ForwardIterator __t, 2364 _UniformRandomNumberGenerator& __urng) 2365 { this->__generate(__f, __t, __urng, _M_param); } 2366 2367 template
2369 void 2370 __generate(_ForwardIterator __f, _ForwardIterator __t, 2371 _UniformRandomNumberGenerator& __urng, 2372 const param_type& __p) 2373 { this->__generate_impl(__f, __t, __urng, __p); } 2374 2375 template
2376 void 2377 __generate(result_type* __f, result_type* __t, 2378 _UniformRandomNumberGenerator& __urng, 2379 const param_type& __p) 2380 { this->__generate_impl(__f, __t, __urng, __p); } 2381 2382 /** 2383 * @brief Return true if two lognormal distributions have 2384 * the same parameters and the sequences that would 2385 * be generated are equal. 2386 */ 2387 friend bool 2388 operator==(const lognormal_distribution& __d1, 2389 const lognormal_distribution& __d2) 2390 { return (__d1._M_param == __d2._M_param 2391 && __d1._M_nd == __d2._M_nd); } 2392 2393 /** 2394 * @brief Inserts a %lognormal_distribution random number distribution 2395 * @p __x into the output stream @p __os. 2396 * 2397 * @param __os An output stream. 2398 * @param __x A %lognormal_distribution random number distribution. 2399 * 2400 * @returns The output stream with the state of @p __x inserted or in 2401 * an error state. 2402 */ 2403 template
2404 friend std::basic_ostream<_CharT, _Traits>& 2405 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2406 const std::lognormal_distribution<_RealType1>& __x); 2407 2408 /** 2409 * @brief Extracts a %lognormal_distribution random number distribution 2410 * @p __x from the input stream @p __is. 2411 * 2412 * @param __is An input stream. 2413 * @param __x A %lognormal_distribution random number 2414 * generator engine. 2415 * 2416 * @returns The input stream with @p __x extracted or in an error state. 2417 */ 2418 template
2419 friend std::basic_istream<_CharT, _Traits>& 2420 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2421 std::lognormal_distribution<_RealType1>& __x); 2422 2423 private: 2424 template
2426 void 2427 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2428 _UniformRandomNumberGenerator& __urng, 2429 const param_type& __p); 2430 2431 param_type _M_param; 2432 2433 std::normal_distribution
_M_nd; 2434 }; 2435 2436 #if __cpp_impl_three_way_comparison < 201907L 2437 /** 2438 * @brief Return true if two lognormal distributions are different. 2439 */ 2440 template
2441 inline bool 2442 operator!=(const std::lognormal_distribution<_RealType>& __d1, 2443 const std::lognormal_distribution<_RealType>& __d2) 2444 { return !(__d1 == __d2); } 2445 #endif 2446 2447 /// @} group random_distributions_normal 2448 2449 /** 2450 * @addtogroup random_distributions_poisson Poisson Distributions 2451 * @ingroup random_distributions 2452 * @{ 2453 */ 2454 2455 /** 2456 * @brief A gamma continuous distribution for random numbers. 2457 * 2458 * The formula for the gamma probability density function is: 2459 * @f[ 2460 * p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)} 2461 * (x/\beta)^{\alpha - 1} e^{-x/\beta} 2462 * @f] 2463 * 2464 * @headerfile random 2465 * @since C++11 2466 */ 2467 template
2468 class gamma_distribution 2469 { 2470 static_assert(std::is_floating_point<_RealType>::value, 2471 "result_type must be a floating point type"); 2472 2473 public: 2474 /** The type of the range of the distribution. */ 2475 typedef _RealType result_type; 2476 2477 /** Parameter type. */ 2478 struct param_type 2479 { 2480 typedef gamma_distribution<_RealType> distribution_type; 2481 friend class gamma_distribution<_RealType>; 2482 2483 param_type() : param_type(1.0) { } 2484 2485 explicit 2486 param_type(_RealType __alpha_val, _RealType __beta_val = _RealType(1)) 2487 : _M_alpha(__alpha_val), _M_beta(__beta_val) 2488 { 2489 __glibcxx_assert(_M_alpha > _RealType(0)); 2490 _M_initialize(); 2491 } 2492 2493 _RealType 2494 alpha() const 2495 { return _M_alpha; } 2496 2497 _RealType 2498 beta() const 2499 { return _M_beta; } 2500 2501 friend bool 2502 operator==(const param_type& __p1, const param_type& __p2) 2503 { return (__p1._M_alpha == __p2._M_alpha 2504 && __p1._M_beta == __p2._M_beta); } 2505 2506 #if __cpp_impl_three_way_comparison < 201907L 2507 friend bool 2508 operator!=(const param_type& __p1, const param_type& __p2) 2509 { return !(__p1 == __p2); } 2510 #endif 2511 2512 private: 2513 void 2514 _M_initialize(); 2515 2516 _RealType _M_alpha; 2517 _RealType _M_beta; 2518 2519 _RealType _M_malpha, _M_a2; 2520 }; 2521 2522 public: 2523 /** 2524 * @brief Constructs a gamma distribution with parameters 1 and 1. 2525 */ 2526 gamma_distribution() : gamma_distribution(1.0) { } 2527 2528 /** 2529 * @brief Constructs a gamma distribution with parameters 2530 * @f$\alpha@f$ and @f$\beta@f$. 2531 */ 2532 explicit 2533 gamma_distribution(_RealType __alpha_val, 2534 _RealType __beta_val = _RealType(1)) 2535 : _M_param(__alpha_val, __beta_val), _M_nd() 2536 { } 2537 2538 explicit 2539 gamma_distribution(const param_type& __p) 2540 : _M_param(__p), _M_nd() 2541 { } 2542 2543 /** 2544 * @brief Resets the distribution state. 2545 */ 2546 void 2547 reset() 2548 { _M_nd.reset(); } 2549 2550 /** 2551 * @brief Returns the @f$\alpha@f$ of the distribution. 2552 */ 2553 _RealType 2554 alpha() const 2555 { return _M_param.alpha(); } 2556 2557 /** 2558 * @brief Returns the @f$\beta@f$ of the distribution. 2559 */ 2560 _RealType 2561 beta() const 2562 { return _M_param.beta(); } 2563 2564 /** 2565 * @brief Returns the parameter set of the distribution. 2566 */ 2567 param_type 2568 param() const 2569 { return _M_param; } 2570 2571 /** 2572 * @brief Sets the parameter set of the distribution. 2573 * @param __param The new parameter set of the distribution. 2574 */ 2575 void 2576 param(const param_type& __param) 2577 { _M_param = __param; } 2578 2579 /** 2580 * @brief Returns the greatest lower bound value of the distribution. 2581 */ 2582 result_type 2583 min() const 2584 { return result_type(0); } 2585 2586 /** 2587 * @brief Returns the least upper bound value of the distribution. 2588 */ 2589 result_type 2590 max() const 2591 { return std::numeric_limits
::max(); } 2592 2593 /** 2594 * @brief Generating functions. 2595 */ 2596 template
2597 result_type 2598 operator()(_UniformRandomNumberGenerator& __urng) 2599 { return this->operator()(__urng, _M_param); } 2600 2601 template
2602 result_type 2603 operator()(_UniformRandomNumberGenerator& __urng, 2604 const param_type& __p); 2605 2606 template
2608 void 2609 __generate(_ForwardIterator __f, _ForwardIterator __t, 2610 _UniformRandomNumberGenerator& __urng) 2611 { this->__generate(__f, __t, __urng, _M_param); } 2612 2613 template
2615 void 2616 __generate(_ForwardIterator __f, _ForwardIterator __t, 2617 _UniformRandomNumberGenerator& __urng, 2618 const param_type& __p) 2619 { this->__generate_impl(__f, __t, __urng, __p); } 2620 2621 template
2622 void 2623 __generate(result_type* __f, result_type* __t, 2624 _UniformRandomNumberGenerator& __urng, 2625 const param_type& __p) 2626 { this->__generate_impl(__f, __t, __urng, __p); } 2627 2628 /** 2629 * @brief Return true if two gamma distributions have the same 2630 * parameters and the sequences that would be generated 2631 * are equal. 2632 */ 2633 friend bool 2634 operator==(const gamma_distribution& __d1, 2635 const gamma_distribution& __d2) 2636 { return (__d1._M_param == __d2._M_param 2637 && __d1._M_nd == __d2._M_nd); } 2638 2639 /** 2640 * @brief Inserts a %gamma_distribution random number distribution 2641 * @p __x into the output stream @p __os. 2642 * 2643 * @param __os An output stream. 2644 * @param __x A %gamma_distribution random number distribution. 2645 * 2646 * @returns The output stream with the state of @p __x inserted or in 2647 * an error state. 2648 */ 2649 template
2650 friend std::basic_ostream<_CharT, _Traits>& 2651 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2652 const std::gamma_distribution<_RealType1>& __x); 2653 2654 /** 2655 * @brief Extracts a %gamma_distribution random number distribution 2656 * @p __x from the input stream @p __is. 2657 * 2658 * @param __is An input stream. 2659 * @param __x A %gamma_distribution random number generator engine. 2660 * 2661 * @returns The input stream with @p __x extracted or in an error state. 2662 */ 2663 template
2664 friend std::basic_istream<_CharT, _Traits>& 2665 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2666 std::gamma_distribution<_RealType1>& __x); 2667 2668 private: 2669 template
2671 void 2672 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2673 _UniformRandomNumberGenerator& __urng, 2674 const param_type& __p); 2675 2676 param_type _M_param; 2677 2678 std::normal_distribution
_M_nd; 2679 }; 2680 2681 #if __cpp_impl_three_way_comparison < 201907L 2682 /** 2683 * @brief Return true if two gamma distributions are different. 2684 */ 2685 template
2686 inline bool 2687 operator!=(const std::gamma_distribution<_RealType>& __d1, 2688 const std::gamma_distribution<_RealType>& __d2) 2689 { return !(__d1 == __d2); } 2690 #endif 2691 2692 /// @} group random_distributions_poisson 2693 2694 /** 2695 * @addtogroup random_distributions_normal Normal Distributions 2696 * @ingroup random_distributions 2697 * @{ 2698 */ 2699 2700 /** 2701 * @brief A chi_squared_distribution random number distribution. 2702 * 2703 * The formula for the normal probability mass function is 2704 * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$ 2705 * 2706 * @headerfile random 2707 * @since C++11 2708 */ 2709 template
2710 class chi_squared_distribution 2711 { 2712 static_assert(std::is_floating_point<_RealType>::value, 2713 "result_type must be a floating point type"); 2714 2715 public: 2716 /** The type of the range of the distribution. */ 2717 typedef _RealType result_type; 2718 2719 /** Parameter type. */ 2720 struct param_type 2721 { 2722 typedef chi_squared_distribution<_RealType> distribution_type; 2723 2724 param_type() : param_type(1) { } 2725 2726 explicit 2727 param_type(_RealType __n) 2728 : _M_n(__n) 2729 { } 2730 2731 _RealType 2732 n() const 2733 { return _M_n; } 2734 2735 friend bool 2736 operator==(const param_type& __p1, const param_type& __p2) 2737 { return __p1._M_n == __p2._M_n; } 2738 2739 #if __cpp_impl_three_way_comparison < 201907L 2740 friend bool 2741 operator!=(const param_type& __p1, const param_type& __p2) 2742 { return !(__p1 == __p2); } 2743 #endif 2744 2745 private: 2746 _RealType _M_n; 2747 }; 2748 2749 chi_squared_distribution() : chi_squared_distribution(1) { } 2750 2751 explicit 2752 chi_squared_distribution(_RealType __n) 2753 : _M_param(__n), _M_gd(__n / 2) 2754 { } 2755 2756 explicit 2757 chi_squared_distribution(const param_type& __p) 2758 : _M_param(__p), _M_gd(__p.n() / 2) 2759 { } 2760 2761 /** 2762 * @brief Resets the distribution state. 2763 */ 2764 void 2765 reset() 2766 { _M_gd.reset(); } 2767 2768 /** 2769 * 2770 */ 2771 _RealType 2772 n() const 2773 { return _M_param.n(); } 2774 2775 /** 2776 * @brief Returns the parameter set of the distribution. 2777 */ 2778 param_type 2779 param() const 2780 { return _M_param; } 2781 2782 /** 2783 * @brief Sets the parameter set of the distribution. 2784 * @param __param The new parameter set of the distribution. 2785 */ 2786 void 2787 param(const param_type& __param) 2788 { 2789 _M_param = __param; 2790 typedef typename std::gamma_distribution
::param_type 2791 param_type; 2792 _M_gd.param(param_type{__param.n() / 2}); 2793 } 2794 2795 /** 2796 * @brief Returns the greatest lower bound value of the distribution. 2797 */ 2798 result_type 2799 min() const 2800 { return result_type(0); } 2801 2802 /** 2803 * @brief Returns the least upper bound value of the distribution. 2804 */ 2805 result_type 2806 max() const 2807 { return std::numeric_limits
::max(); } 2808 2809 /** 2810 * @brief Generating functions. 2811 */ 2812 template
2813 result_type 2814 operator()(_UniformRandomNumberGenerator& __urng) 2815 { return 2 * _M_gd(__urng); } 2816 2817 template
2818 result_type 2819 operator()(_UniformRandomNumberGenerator& __urng, 2820 const param_type& __p) 2821 { 2822 typedef typename std::gamma_distribution
::param_type 2823 param_type; 2824 return 2 * _M_gd(__urng, param_type(__p.n() / 2)); 2825 } 2826 2827 template
2829 void 2830 __generate(_ForwardIterator __f, _ForwardIterator __t, 2831 _UniformRandomNumberGenerator& __urng) 2832 { this->__generate_impl(__f, __t, __urng); } 2833 2834 template
2836 void 2837 __generate(_ForwardIterator __f, _ForwardIterator __t, 2838 _UniformRandomNumberGenerator& __urng, 2839 const param_type& __p) 2840 { typename std::gamma_distribution
::param_type 2841 __p2(__p.n() / 2); 2842 this->__generate_impl(__f, __t, __urng, __p2); } 2843 2844 template
2845 void 2846 __generate(result_type* __f, result_type* __t, 2847 _UniformRandomNumberGenerator& __urng) 2848 { this->__generate_impl(__f, __t, __urng); } 2849 2850 template
2851 void 2852 __generate(result_type* __f, result_type* __t, 2853 _UniformRandomNumberGenerator& __urng, 2854 const param_type& __p) 2855 { typename std::gamma_distribution
::param_type 2856 __p2(__p.n() / 2); 2857 this->__generate_impl(__f, __t, __urng, __p2); } 2858 2859 /** 2860 * @brief Return true if two Chi-squared distributions have 2861 * the same parameters and the sequences that would be 2862 * generated are equal. 2863 */ 2864 friend bool 2865 operator==(const chi_squared_distribution& __d1, 2866 const chi_squared_distribution& __d2) 2867 { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; } 2868 2869 /** 2870 * @brief Inserts a %chi_squared_distribution random number distribution 2871 * @p __x into the output stream @p __os. 2872 * 2873 * @param __os An output stream. 2874 * @param __x A %chi_squared_distribution random number distribution. 2875 * 2876 * @returns The output stream with the state of @p __x inserted or in 2877 * an error state. 2878 */ 2879 template
2880 friend std::basic_ostream<_CharT, _Traits>& 2881 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2882 const std::chi_squared_distribution<_RealType1>& __x); 2883 2884 /** 2885 * @brief Extracts a %chi_squared_distribution random number distribution 2886 * @p __x from the input stream @p __is. 2887 * 2888 * @param __is An input stream. 2889 * @param __x A %chi_squared_distribution random number 2890 * generator engine. 2891 * 2892 * @returns The input stream with @p __x extracted or in an error state. 2893 */ 2894 template
2895 friend std::basic_istream<_CharT, _Traits>& 2896 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2897 std::chi_squared_distribution<_RealType1>& __x); 2898 2899 private: 2900 template
2902 void 2903 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2904 _UniformRandomNumberGenerator& __urng); 2905 2906 template
2908 void 2909 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2910 _UniformRandomNumberGenerator& __urng, 2911 const typename 2912 std::gamma_distribution
::param_type& __p); 2913 2914 param_type _M_param; 2915 2916 std::gamma_distribution
_M_gd; 2917 }; 2918 2919 #if __cpp_impl_three_way_comparison < 201907L 2920 /** 2921 * @brief Return true if two Chi-squared distributions are different. 2922 */ 2923 template
2924 inline bool 2925 operator!=(const std::chi_squared_distribution<_RealType>& __d1, 2926 const std::chi_squared_distribution<_RealType>& __d2) 2927 { return !(__d1 == __d2); } 2928 #endif 2929 2930 /** 2931 * @brief A cauchy_distribution random number distribution. 2932 * 2933 * The formula for the normal probability mass function is 2934 * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$ 2935 * 2936 * @headerfile random 2937 * @since C++11 2938 */ 2939 template
2940 class cauchy_distribution 2941 { 2942 static_assert(std::is_floating_point<_RealType>::value, 2943 "result_type must be a floating point type"); 2944 2945 public: 2946 /** The type of the range of the distribution. */ 2947 typedef _RealType result_type; 2948 2949 /** Parameter type. */ 2950 struct param_type 2951 { 2952 typedef cauchy_distribution<_RealType> distribution_type; 2953 2954 param_type() : param_type(0) { } 2955 2956 explicit 2957 param_type(_RealType __a, _RealType __b = _RealType(1)) 2958 : _M_a(__a), _M_b(__b) 2959 { } 2960 2961 _RealType 2962 a() const 2963 { return _M_a; } 2964 2965 _RealType 2966 b() const 2967 { return _M_b; } 2968 2969 friend bool 2970 operator==(const param_type& __p1, const param_type& __p2) 2971 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } 2972 2973 #if __cpp_impl_three_way_comparison < 201907L 2974 friend bool 2975 operator!=(const param_type& __p1, const param_type& __p2) 2976 { return !(__p1 == __p2); } 2977 #endif 2978 2979 private: 2980 _RealType _M_a; 2981 _RealType _M_b; 2982 }; 2983 2984 cauchy_distribution() : cauchy_distribution(0.0) { } 2985 2986 explicit 2987 cauchy_distribution(_RealType __a, _RealType __b = 1.0) 2988 : _M_param(__a, __b) 2989 { } 2990 2991 explicit 2992 cauchy_distribution(const param_type& __p) 2993 : _M_param(__p) 2994 { } 2995 2996 /** 2997 * @brief Resets the distribution state. 2998 */ 2999 void 3000 reset() 3001 { } 3002 3003 /** 3004 * 3005 */ 3006 _RealType 3007 a() const 3008 { return _M_param.a(); } 3009 3010 _RealType 3011 b() const 3012 { return _M_param.b(); } 3013 3014 /** 3015 * @brief Returns the parameter set of the distribution. 3016 */ 3017 param_type 3018 param() const 3019 { return _M_param; } 3020 3021 /** 3022 * @brief Sets the parameter set of the distribution. 3023 * @param __param The new parameter set of the distribution. 3024 */ 3025 void 3026 param(const param_type& __param) 3027 { _M_param = __param; } 3028 3029 /** 3030 * @brief Returns the greatest lower bound value of the distribution. 3031 */ 3032 result_type 3033 min() const 3034 { return std::numeric_limits
::lowest(); } 3035 3036 /** 3037 * @brief Returns the least upper bound value of the distribution. 3038 */ 3039 result_type 3040 max() const 3041 { return std::numeric_limits
::max(); } 3042 3043 /** 3044 * @brief Generating functions. 3045 */ 3046 template
3047 result_type 3048 operator()(_UniformRandomNumberGenerator& __urng) 3049 { return this->operator()(__urng, _M_param); } 3050 3051 template
3052 result_type 3053 operator()(_UniformRandomNumberGenerator& __urng, 3054 const param_type& __p); 3055 3056 template
3058 void 3059 __generate(_ForwardIterator __f, _ForwardIterator __t, 3060 _UniformRandomNumberGenerator& __urng) 3061 { this->__generate(__f, __t, __urng, _M_param); } 3062 3063 template
3065 void 3066 __generate(_ForwardIterator __f, _ForwardIterator __t, 3067 _UniformRandomNumberGenerator& __urng, 3068 const param_type& __p) 3069 { this->__generate_impl(__f, __t, __urng, __p); } 3070 3071 template
3072 void 3073 __generate(result_type* __f, result_type* __t, 3074 _UniformRandomNumberGenerator& __urng, 3075 const param_type& __p) 3076 { this->__generate_impl(__f, __t, __urng, __p); } 3077 3078 /** 3079 * @brief Return true if two Cauchy distributions have 3080 * the same parameters. 3081 */ 3082 friend bool 3083 operator==(const cauchy_distribution& __d1, 3084 const cauchy_distribution& __d2) 3085 { return __d1._M_param == __d2._M_param; } 3086 3087 private: 3088 template
3090 void 3091 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3092 _UniformRandomNumberGenerator& __urng, 3093 const param_type& __p); 3094 3095 param_type _M_param; 3096 }; 3097 3098 #if __cpp_impl_three_way_comparison < 201907L 3099 /** 3100 * @brief Return true if two Cauchy distributions have 3101 * different parameters. 3102 */ 3103 template
3104 inline bool 3105 operator!=(const std::cauchy_distribution<_RealType>& __d1, 3106 const std::cauchy_distribution<_RealType>& __d2) 3107 { return !(__d1 == __d2); } 3108 #endif 3109 3110 /** 3111 * @brief Inserts a %cauchy_distribution random number distribution 3112 * @p __x into the output stream @p __os. 3113 * 3114 * @param __os An output stream. 3115 * @param __x A %cauchy_distribution random number distribution. 3116 * 3117 * @returns The output stream with the state of @p __x inserted or in 3118 * an error state. 3119 */ 3120 template
3121 std::basic_ostream<_CharT, _Traits>& 3122 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3123 const std::cauchy_distribution<_RealType>& __x); 3124 3125 /** 3126 * @brief Extracts a %cauchy_distribution random number distribution 3127 * @p __x from the input stream @p __is. 3128 * 3129 * @param __is An input stream. 3130 * @param __x A %cauchy_distribution random number 3131 * generator engine. 3132 * 3133 * @returns The input stream with @p __x extracted or in an error state. 3134 */ 3135 template
3136 std::basic_istream<_CharT, _Traits>& 3137 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3138 std::cauchy_distribution<_RealType>& __x); 3139 3140 3141 /** 3142 * @brief A fisher_f_distribution random number distribution. 3143 * 3144 * The formula for the normal probability mass function is 3145 * @f[ 3146 * p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)} 3147 * (\frac{m}{n})^{m/2} x^{(m/2)-1} 3148 * (1 + \frac{mx}{n})^{-(m+n)/2} 3149 * @f] 3150 * 3151 * @headerfile random 3152 * @since C++11 3153 */ 3154 template
3155 class fisher_f_distribution 3156 { 3157 static_assert(std::is_floating_point<_RealType>::value, 3158 "result_type must be a floating point type"); 3159 3160 public: 3161 /** The type of the range of the distribution. */ 3162 typedef _RealType result_type; 3163 3164 /** Parameter type. */ 3165 struct param_type 3166 { 3167 typedef fisher_f_distribution<_RealType> distribution_type; 3168 3169 param_type() : param_type(1) { } 3170 3171 explicit 3172 param_type(_RealType __m, _RealType __n = _RealType(1)) 3173 : _M_m(__m), _M_n(__n) 3174 { } 3175 3176 _RealType 3177 m() const 3178 { return _M_m; } 3179 3180 _RealType 3181 n() const 3182 { return _M_n; } 3183 3184 friend bool 3185 operator==(const param_type& __p1, const param_type& __p2) 3186 { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; } 3187 3188 #if __cpp_impl_three_way_comparison < 201907L 3189 friend bool 3190 operator!=(const param_type& __p1, const param_type& __p2) 3191 { return !(__p1 == __p2); } 3192 #endif 3193 3194 private: 3195 _RealType _M_m; 3196 _RealType _M_n; 3197 }; 3198 3199 fisher_f_distribution() : fisher_f_distribution(1.0) { } 3200 3201 explicit 3202 fisher_f_distribution(_RealType __m, 3203 _RealType __n = _RealType(1)) 3204 : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2) 3205 { } 3206 3207 explicit 3208 fisher_f_distribution(const param_type& __p) 3209 : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2) 3210 { } 3211 3212 /** 3213 * @brief Resets the distribution state. 3214 */ 3215 void 3216 reset() 3217 { 3218 _M_gd_x.reset(); 3219 _M_gd_y.reset(); 3220 } 3221 3222 /** 3223 * 3224 */ 3225 _RealType 3226 m() const 3227 { return _M_param.m(); } 3228 3229 _RealType 3230 n() const 3231 { return _M_param.n(); } 3232 3233 /** 3234 * @brief Returns the parameter set of the distribution. 3235 */ 3236 param_type 3237 param() const 3238 { return _M_param; } 3239 3240 /** 3241 * @brief Sets the parameter set of the distribution. 3242 * @param __param The new parameter set of the distribution. 3243 */ 3244 void 3245 param(const param_type& __param) 3246 { _M_param = __param; } 3247 3248 /** 3249 * @brief Returns the greatest lower bound value of the distribution. 3250 */ 3251 result_type 3252 min() const 3253 { return result_type(0); } 3254 3255 /** 3256 * @brief Returns the least upper bound value of the distribution. 3257 */ 3258 result_type 3259 max() const 3260 { return std::numeric_limits
::max(); } 3261 3262 /** 3263 * @brief Generating functions. 3264 */ 3265 template
3266 result_type 3267 operator()(_UniformRandomNumberGenerator& __urng) 3268 { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); } 3269 3270 template
3271 result_type 3272 operator()(_UniformRandomNumberGenerator& __urng, 3273 const param_type& __p) 3274 { 3275 typedef typename std::gamma_distribution
::param_type 3276 param_type; 3277 return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n()) 3278 / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m())); 3279 } 3280 3281 template
3283 void 3284 __generate(_ForwardIterator __f, _ForwardIterator __t, 3285 _UniformRandomNumberGenerator& __urng) 3286 { this->__generate_impl(__f, __t, __urng); } 3287 3288 template
3290 void 3291 __generate(_ForwardIterator __f, _ForwardIterator __t, 3292 _UniformRandomNumberGenerator& __urng, 3293 const param_type& __p) 3294 { this->__generate_impl(__f, __t, __urng, __p); } 3295 3296 template
3297 void 3298 __generate(result_type* __f, result_type* __t, 3299 _UniformRandomNumberGenerator& __urng) 3300 { this->__generate_impl(__f, __t, __urng); } 3301 3302 template
3303 void 3304 __generate(result_type* __f, result_type* __t, 3305 _UniformRandomNumberGenerator& __urng, 3306 const param_type& __p) 3307 { this->__generate_impl(__f, __t, __urng, __p); } 3308 3309 /** 3310 * @brief Return true if two Fisher f distributions have 3311 * the same parameters and the sequences that would 3312 * be generated are equal. 3313 */ 3314 friend bool 3315 operator==(const fisher_f_distribution& __d1, 3316 const fisher_f_distribution& __d2) 3317 { return (__d1._M_param == __d2._M_param 3318 && __d1._M_gd_x == __d2._M_gd_x 3319 && __d1._M_gd_y == __d2._M_gd_y); } 3320 3321 /** 3322 * @brief Inserts a %fisher_f_distribution random number distribution 3323 * @p __x into the output stream @p __os. 3324 * 3325 * @param __os An output stream. 3326 * @param __x A %fisher_f_distribution random number distribution. 3327 * 3328 * @returns The output stream with the state of @p __x inserted or in 3329 * an error state. 3330 */ 3331 template
3332 friend std::basic_ostream<_CharT, _Traits>& 3333 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3334 const std::fisher_f_distribution<_RealType1>& __x); 3335 3336 /** 3337 * @brief Extracts a %fisher_f_distribution random number distribution 3338 * @p __x from the input stream @p __is. 3339 * 3340 * @param __is An input stream. 3341 * @param __x A %fisher_f_distribution random number 3342 * generator engine. 3343 * 3344 * @returns The input stream with @p __x extracted or in an error state. 3345 */ 3346 template
3347 friend std::basic_istream<_CharT, _Traits>& 3348 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3349 std::fisher_f_distribution<_RealType1>& __x); 3350 3351 private: 3352 template
3354 void 3355 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3356 _UniformRandomNumberGenerator& __urng); 3357 3358 template
3360 void 3361 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3362 _UniformRandomNumberGenerator& __urng, 3363 const param_type& __p); 3364 3365 param_type _M_param; 3366 3367 std::gamma_distribution
_M_gd_x, _M_gd_y; 3368 }; 3369 3370 #if __cpp_impl_three_way_comparison < 201907L 3371 /** 3372 * @brief Return true if two Fisher f distributions are different. 3373 */ 3374 template
3375 inline bool 3376 operator!=(const std::fisher_f_distribution<_RealType>& __d1, 3377 const std::fisher_f_distribution<_RealType>& __d2) 3378 { return !(__d1 == __d2); } 3379 #endif 3380 3381 /** 3382 * @brief A student_t_distribution random number distribution. 3383 * 3384 * The formula for the normal probability mass function is: 3385 * @f[ 3386 * p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)} 3387 * (1 + \frac{x^2}{n}) ^{-(n+1)/2} 3388 * @f] 3389 * 3390 * @headerfile random 3391 * @since C++11 3392 */ 3393 template
3394 class student_t_distribution 3395 { 3396 static_assert(std::is_floating_point<_RealType>::value, 3397 "result_type must be a floating point type"); 3398 3399 public: 3400 /** The type of the range of the distribution. */ 3401 typedef _RealType result_type; 3402 3403 /** Parameter type. */ 3404 struct param_type 3405 { 3406 typedef student_t_distribution<_RealType> distribution_type; 3407 3408 param_type() : param_type(1) { } 3409 3410 explicit 3411 param_type(_RealType __n) 3412 : _M_n(__n) 3413 { } 3414 3415 _RealType 3416 n() const 3417 { return _M_n; } 3418 3419 friend bool 3420 operator==(const param_type& __p1, const param_type& __p2) 3421 { return __p1._M_n == __p2._M_n; } 3422 3423 #if __cpp_impl_three_way_comparison < 201907L 3424 friend bool 3425 operator!=(const param_type& __p1, const param_type& __p2) 3426 { return !(__p1 == __p2); } 3427 #endif 3428 3429 private: 3430 _RealType _M_n; 3431 }; 3432 3433 student_t_distribution() : student_t_distribution(1.0) { } 3434 3435 explicit 3436 student_t_distribution(_RealType __n) 3437 : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2) 3438 { } 3439 3440 explicit 3441 student_t_distribution(const param_type& __p) 3442 : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2) 3443 { } 3444 3445 /** 3446 * @brief Resets the distribution state. 3447 */ 3448 void 3449 reset() 3450 { 3451 _M_nd.reset(); 3452 _M_gd.reset(); 3453 } 3454 3455 /** 3456 * 3457 */ 3458 _RealType 3459 n() const 3460 { return _M_param.n(); } 3461 3462 /** 3463 * @brief Returns the parameter set of the distribution. 3464 */ 3465 param_type 3466 param() const 3467 { return _M_param; } 3468 3469 /** 3470 * @brief Sets the parameter set of the distribution. 3471 * @param __param The new parameter set of the distribution. 3472 */ 3473 void 3474 param(const param_type& __param) 3475 { _M_param = __param; } 3476 3477 /** 3478 * @brief Returns the greatest lower bound value of the distribution. 3479 */ 3480 result_type 3481 min() const 3482 { return std::numeric_limits
::lowest(); } 3483 3484 /** 3485 * @brief Returns the least upper bound value of the distribution. 3486 */ 3487 result_type 3488 max() const 3489 { return std::numeric_limits
::max(); } 3490 3491 /** 3492 * @brief Generating functions. 3493 */ 3494 template
3495 result_type 3496 operator()(_UniformRandomNumberGenerator& __urng) 3497 { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); } 3498 3499 template
3500 result_type 3501 operator()(_UniformRandomNumberGenerator& __urng, 3502 const param_type& __p) 3503 { 3504 typedef typename std::gamma_distribution
::param_type 3505 param_type; 3506 3507 const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2)); 3508 return _M_nd(__urng) * std::sqrt(__p.n() / __g); 3509 } 3510 3511 template
3513 void 3514 __generate(_ForwardIterator __f, _ForwardIterator __t, 3515 _UniformRandomNumberGenerator& __urng) 3516 { this->__generate_impl(__f, __t, __urng); } 3517 3518 template
3520 void 3521 __generate(_ForwardIterator __f, _ForwardIterator __t, 3522 _UniformRandomNumberGenerator& __urng, 3523 const param_type& __p) 3524 { this->__generate_impl(__f, __t, __urng, __p); } 3525 3526 template
3527 void 3528 __generate(result_type* __f, result_type* __t, 3529 _UniformRandomNumberGenerator& __urng) 3530 { this->__generate_impl(__f, __t, __urng); } 3531 3532 template
3533 void 3534 __generate(result_type* __f, result_type* __t, 3535 _UniformRandomNumberGenerator& __urng, 3536 const param_type& __p) 3537 { this->__generate_impl(__f, __t, __urng, __p); } 3538 3539 /** 3540 * @brief Return true if two Student t distributions have 3541 * the same parameters and the sequences that would 3542 * be generated are equal. 3543 */ 3544 friend bool 3545 operator==(const student_t_distribution& __d1, 3546 const student_t_distribution& __d2) 3547 { return (__d1._M_param == __d2._M_param 3548 && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); } 3549 3550 /** 3551 * @brief Inserts a %student_t_distribution random number distribution 3552 * @p __x into the output stream @p __os. 3553 * 3554 * @param __os An output stream. 3555 * @param __x A %student_t_distribution random number distribution. 3556 * 3557 * @returns The output stream with the state of @p __x inserted or in 3558 * an error state. 3559 */ 3560 template
3561 friend std::basic_ostream<_CharT, _Traits>& 3562 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3563 const std::student_t_distribution<_RealType1>& __x); 3564 3565 /** 3566 * @brief Extracts a %student_t_distribution random number distribution 3567 * @p __x from the input stream @p __is. 3568 * 3569 * @param __is An input stream. 3570 * @param __x A %student_t_distribution random number 3571 * generator engine. 3572 * 3573 * @returns The input stream with @p __x extracted or in an error state. 3574 */ 3575 template
3576 friend std::basic_istream<_CharT, _Traits>& 3577 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3578 std::student_t_distribution<_RealType1>& __x); 3579 3580 private: 3581 template
3583 void 3584 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3585 _UniformRandomNumberGenerator& __urng); 3586 template
3588 void 3589 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3590 _UniformRandomNumberGenerator& __urng, 3591 const param_type& __p); 3592 3593 param_type _M_param; 3594 3595 std::normal_distribution
_M_nd; 3596 std::gamma_distribution
_M_gd; 3597 }; 3598 3599 #if __cpp_impl_three_way_comparison < 201907L 3600 /** 3601 * @brief Return true if two Student t distributions are different. 3602 */ 3603 template
3604 inline bool 3605 operator!=(const std::student_t_distribution<_RealType>& __d1, 3606 const std::student_t_distribution<_RealType>& __d2) 3607 { return !(__d1 == __d2); } 3608 #endif 3609 3610 /// @} group random_distributions_normal 3611 3612 /** 3613 * @addtogroup random_distributions_bernoulli Bernoulli Distributions 3614 * @ingroup random_distributions 3615 * @{ 3616 */ 3617 3618 /** 3619 * @brief A Bernoulli random number distribution. 3620 * 3621 * Generates a sequence of true and false values with likelihood @f$p@f$ 3622 * that true will come up and @f$(1 - p)@f$ that false will appear. 3623 * 3624 * @headerfile random 3625 * @since C++11 3626 */ 3627 class bernoulli_distribution 3628 { 3629 public: 3630 /** The type of the range of the distribution. */ 3631 typedef bool result_type; 3632 3633 /** Parameter type. */ 3634 struct param_type 3635 { 3636 typedef bernoulli_distribution distribution_type; 3637 3638 param_type() : param_type(0.5) { } 3639 3640 explicit 3641 param_type(double __p) 3642 : _M_p(__p) 3643 { 3644 __glibcxx_assert((_M_p >= 0.0) && (_M_p <= 1.0)); 3645 } 3646 3647 double 3648 p() const 3649 { return _M_p; } 3650 3651 friend bool 3652 operator==(const param_type& __p1, const param_type& __p2) 3653 { return __p1._M_p == __p2._M_p; } 3654 3655 #if __cpp_impl_three_way_comparison < 201907L 3656 friend bool 3657 operator!=(const param_type& __p1, const param_type& __p2) 3658 { return !(__p1 == __p2); } 3659 #endif 3660 3661 private: 3662 double _M_p; 3663 }; 3664 3665 public: 3666 /** 3667 * @brief Constructs a Bernoulli distribution with likelihood 0.5. 3668 */ 3669 bernoulli_distribution() : bernoulli_distribution(0.5) { } 3670 3671 /** 3672 * @brief Constructs a Bernoulli distribution with likelihood @p p. 3673 * 3674 * @param __p [IN] The likelihood of a true result being returned. 3675 * Must be in the interval @f$[0, 1]@f$. 3676 */ 3677 explicit 3678 bernoulli_distribution(double __p) 3679 : _M_param(__p) 3680 { } 3681 3682 explicit 3683 bernoulli_distribution(const param_type& __p) 3684 : _M_param(__p) 3685 { } 3686 3687 /** 3688 * @brief Resets the distribution state. 3689 * 3690 * Does nothing for a Bernoulli distribution. 3691 */ 3692 void 3693 reset() { } 3694 3695 /** 3696 * @brief Returns the @p p parameter of the distribution. 3697 */ 3698 double 3699 p() const 3700 { return _M_param.p(); } 3701 3702 /** 3703 * @brief Returns the parameter set of the distribution. 3704 */ 3705 param_type 3706 param() const 3707 { return _M_param; } 3708 3709 /** 3710 * @brief Sets the parameter set of the distribution. 3711 * @param __param The new parameter set of the distribution. 3712 */ 3713 void 3714 param(const param_type& __param) 3715 { _M_param = __param; } 3716 3717 /** 3718 * @brief Returns the greatest lower bound value of the distribution. 3719 */ 3720 result_type 3721 min() const 3722 { return std::numeric_limits
::min(); } 3723 3724 /** 3725 * @brief Returns the least upper bound value of the distribution. 3726 */ 3727 result_type 3728 max() const 3729 { return std::numeric_limits
::max(); } 3730 3731 /** 3732 * @brief Generating functions. 3733 */ 3734 template
3735 result_type 3736 operator()(_UniformRandomNumberGenerator& __urng) 3737 { return this->operator()(__urng, _M_param); } 3738 3739 template
3740 result_type 3741 operator()(_UniformRandomNumberGenerator& __urng, 3742 const param_type& __p) 3743 { 3744 __detail::_Adaptor<_UniformRandomNumberGenerator, double> 3745 __aurng(__urng); 3746 if ((__aurng() - __aurng.min()) 3747 < __p.p() * (__aurng.max() - __aurng.min())) 3748 return true; 3749 return false; 3750 } 3751 3752 template
3754 void 3755 __generate(_ForwardIterator __f, _ForwardIterator __t, 3756 _UniformRandomNumberGenerator& __urng) 3757 { this->__generate(__f, __t, __urng, _M_param); } 3758 3759 template
3761 void 3762 __generate(_ForwardIterator __f, _ForwardIterator __t, 3763 _UniformRandomNumberGenerator& __urng, const param_type& __p) 3764 { this->__generate_impl(__f, __t, __urng, __p); } 3765 3766 template
3767 void 3768 __generate(result_type* __f, result_type* __t, 3769 _UniformRandomNumberGenerator& __urng, 3770 const param_type& __p) 3771 { this->__generate_impl(__f, __t, __urng, __p); } 3772 3773 /** 3774 * @brief Return true if two Bernoulli distributions have 3775 * the same parameters. 3776 */ 3777 friend bool 3778 operator==(const bernoulli_distribution& __d1, 3779 const bernoulli_distribution& __d2) 3780 { return __d1._M_param == __d2._M_param; } 3781 3782 private: 3783 template
3785 void 3786 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3787 _UniformRandomNumberGenerator& __urng, 3788 const param_type& __p); 3789 3790 param_type _M_param; 3791 }; 3792 3793 #if __cpp_impl_three_way_comparison < 201907L 3794 /** 3795 * @brief Return true if two Bernoulli distributions have 3796 * different parameters. 3797 */ 3798 inline bool 3799 operator!=(const std::bernoulli_distribution& __d1, 3800 const std::bernoulli_distribution& __d2) 3801 { return !(__d1 == __d2); } 3802 #endif 3803 3804 /** 3805 * @brief Inserts a %bernoulli_distribution random number distribution 3806 * @p __x into the output stream @p __os. 3807 * 3808 * @param __os An output stream. 3809 * @param __x A %bernoulli_distribution random number distribution. 3810 * 3811 * @returns The output stream with the state of @p __x inserted or in 3812 * an error state. 3813 */ 3814 template
3815 std::basic_ostream<_CharT, _Traits>& 3816 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3817 const std::bernoulli_distribution& __x); 3818 3819 /** 3820 * @brief Extracts a %bernoulli_distribution random number distribution 3821 * @p __x from the input stream @p __is. 3822 * 3823 * @param __is An input stream. 3824 * @param __x A %bernoulli_distribution random number generator engine. 3825 * 3826 * @returns The input stream with @p __x extracted or in an error state. 3827 */ 3828 template
3829 inline std::basic_istream<_CharT, _Traits>& 3830 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3831 std::bernoulli_distribution& __x) 3832 { 3833 double __p; 3834 if (__is >> __p) 3835 __x.param(bernoulli_distribution::param_type(__p)); 3836 return __is; 3837 } 3838 3839 3840 /** 3841 * @brief A discrete binomial random number distribution. 3842 * 3843 * The formula for the binomial probability density function is 3844 * @f$p(i|t,p) = \binom{t}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ 3845 * and @f$p@f$ are the parameters of the distribution. 3846 * 3847 * @headerfile random 3848 * @since C++11 3849 */ 3850 template
3851 class binomial_distribution 3852 { 3853 static_assert(std::is_integral<_IntType>::value, 3854 "result_type must be an integral type"); 3855 3856 public: 3857 /** The type of the range of the distribution. */ 3858 typedef _IntType result_type; 3859 3860 /** Parameter type. */ 3861 struct param_type 3862 { 3863 typedef binomial_distribution<_IntType> distribution_type; 3864 friend class binomial_distribution<_IntType>; 3865 3866 param_type() : param_type(1) { } 3867 3868 explicit 3869 param_type(_IntType __t, double __p = 0.5) 3870 : _M_t(__t), _M_p(__p) 3871 { 3872 __glibcxx_assert((_M_t >= _IntType(0)) 3873 && (_M_p >= 0.0) 3874 && (_M_p <= 1.0)); 3875 _M_initialize(); 3876 } 3877 3878 _IntType 3879 t() const 3880 { return _M_t; } 3881 3882 double 3883 p() const 3884 { return _M_p; } 3885 3886 friend bool 3887 operator==(const param_type& __p1, const param_type& __p2) 3888 { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; } 3889 3890 #if __cpp_impl_three_way_comparison < 201907L 3891 friend bool 3892 operator!=(const param_type& __p1, const param_type& __p2) 3893 { return !(__p1 == __p2); } 3894 #endif 3895 3896 private: 3897 void 3898 _M_initialize(); 3899 3900 _IntType _M_t; 3901 double _M_p; 3902 3903 double _M_q; 3904 #if _GLIBCXX_USE_C99_MATH_TR1 3905 double _M_d1, _M_d2, _M_s1, _M_s2, _M_c, 3906 _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; 3907 #endif 3908 bool _M_easy; 3909 }; 3910 3911 // constructors and member functions 3912 3913 binomial_distribution() : binomial_distribution(1) { } 3914 3915 explicit 3916 binomial_distribution(_IntType __t, double __p = 0.5) 3917 : _M_param(__t, __p), _M_nd() 3918 { } 3919 3920 explicit 3921 binomial_distribution(const param_type& __p) 3922 : _M_param(__p), _M_nd() 3923 { } 3924 3925 /** 3926 * @brief Resets the distribution state. 3927 */ 3928 void 3929 reset() 3930 { _M_nd.reset(); } 3931 3932 /** 3933 * @brief Returns the distribution @p t parameter. 3934 */ 3935 _IntType 3936 t() const 3937 { return _M_param.t(); } 3938 3939 /** 3940 * @brief Returns the distribution @p p parameter. 3941 */ 3942 double 3943 p() const 3944 { return _M_param.p(); } 3945 3946 /** 3947 * @brief Returns the parameter set of the distribution. 3948 */ 3949 param_type 3950 param() const 3951 { return _M_param; } 3952 3953 /** 3954 * @brief Sets the parameter set of the distribution. 3955 * @param __param The new parameter set of the distribution. 3956 */ 3957 void 3958 param(const param_type& __param) 3959 { _M_param = __param; } 3960 3961 /** 3962 * @brief Returns the greatest lower bound value of the distribution. 3963 */ 3964 result_type 3965 min() const 3966 { return 0; } 3967 3968 /** 3969 * @brief Returns the least upper bound value of the distribution. 3970 */ 3971 result_type 3972 max() const 3973 { return _M_param.t(); } 3974 3975 /** 3976 * @brief Generating functions. 3977 */ 3978 template
3979 result_type 3980 operator()(_UniformRandomNumberGenerator& __urng) 3981 { return this->operator()(__urng, _M_param); } 3982 3983 template
3984 result_type 3985 operator()(_UniformRandomNumberGenerator& __urng, 3986 const param_type& __p); 3987 3988 template
3990 void 3991 __generate(_ForwardIterator __f, _ForwardIterator __t, 3992 _UniformRandomNumberGenerator& __urng) 3993 { this->__generate(__f, __t, __urng, _M_param); } 3994 3995 template
3997 void 3998 __generate(_ForwardIterator __f, _ForwardIterator __t, 3999 _UniformRandomNumberGenerator& __urng, 4000 const param_type& __p) 4001 { this->__generate_impl(__f, __t, __urng, __p); } 4002 4003 template
4004 void 4005 __generate(result_type* __f, result_type* __t, 4006 _UniformRandomNumberGenerator& __urng, 4007 const param_type& __p) 4008 { this->__generate_impl(__f, __t, __urng, __p); } 4009 4010 /** 4011 * @brief Return true if two binomial distributions have 4012 * the same parameters and the sequences that would 4013 * be generated are equal. 4014 */ 4015 friend bool 4016 operator==(const binomial_distribution& __d1, 4017 const binomial_distribution& __d2) 4018 #ifdef _GLIBCXX_USE_C99_MATH_TR1 4019 { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } 4020 #else 4021 { return __d1._M_param == __d2._M_param; } 4022 #endif 4023 4024 /** 4025 * @brief Inserts a %binomial_distribution random number distribution 4026 * @p __x into the output stream @p __os. 4027 * 4028 * @param __os An output stream. 4029 * @param __x A %binomial_distribution random number distribution. 4030 * 4031 * @returns The output stream with the state of @p __x inserted or in 4032 * an error state. 4033 */ 4034 template
4036 friend std::basic_ostream<_CharT, _Traits>& 4037 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 4038 const std::binomial_distribution<_IntType1>& __x); 4039 4040 /** 4041 * @brief Extracts a %binomial_distribution random number distribution 4042 * @p __x from the input stream @p __is. 4043 * 4044 * @param __is An input stream. 4045 * @param __x A %binomial_distribution random number generator engine. 4046 * 4047 * @returns The input stream with @p __x extracted or in an error 4048 * state. 4049 */ 4050 template
4052 friend std::basic_istream<_CharT, _Traits>& 4053 operator>>(std::basic_istream<_CharT, _Traits>& __is, 4054 std::binomial_distribution<_IntType1>& __x); 4055 4056 private: 4057 template
4059 void 4060 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 4061 _UniformRandomNumberGenerator& __urng, 4062 const param_type& __p); 4063 4064 template
4065 result_type 4066 _M_waiting(_UniformRandomNumberGenerator& __urng, 4067 _IntType __t, double __q); 4068 4069 param_type _M_param; 4070 4071 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. 4072 std::normal_distribution
_M_nd; 4073 }; 4074 4075 #if __cpp_impl_three_way_comparison < 201907L 4076 /** 4077 * @brief Return true if two binomial distributions are different. 4078 */ 4079 template
4080 inline bool 4081 operator!=(const std::binomial_distribution<_IntType>& __d1, 4082 const std::binomial_distribution<_IntType>& __d2) 4083 { return !(__d1 == __d2); } 4084 #endif 4085 4086 /** 4087 * @brief A discrete geometric random number distribution. 4088 * 4089 * The formula for the geometric probability density function is 4090 * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the 4091 * distribution. 4092 * 4093 * @headerfile random 4094 * @since C++11 4095 */ 4096 template
4097 class geometric_distribution 4098 { 4099 static_assert(std::is_integral<_IntType>::value, 4100 "result_type must be an integral type"); 4101 4102 public: 4103 /** The type of the range of the distribution. */ 4104 typedef _IntType result_type; 4105 4106 /** Parameter type. */ 4107 struct param_type 4108 { 4109 typedef geometric_distribution<_IntType> distribution_type; 4110 friend class geometric_distribution<_IntType>; 4111 4112 param_type() : param_type(0.5) { } 4113 4114 explicit 4115 param_type(double __p) 4116 : _M_p(__p) 4117 { 4118 __glibcxx_assert((_M_p > 0.0) && (_M_p < 1.0)); 4119 _M_initialize(); 4120 } 4121 4122 double 4123 p() const 4124 { return _M_p; } 4125 4126 friend bool 4127 operator==(const param_type& __p1, const param_type& __p2) 4128 { return __p1._M_p == __p2._M_p; } 4129 4130 #if __cpp_impl_three_way_comparison < 201907L 4131 friend bool 4132 operator!=(const param_type& __p1, const param_type& __p2) 4133 { return !(__p1 == __p2); } 4134 #endif 4135 4136 private: 4137 void 4138 _M_initialize() 4139 { _M_log_1_p = std::log(1.0 - _M_p); } 4140 4141 double _M_p; 4142 4143 double _M_log_1_p; 4144 }; 4145 4146 // constructors and member functions 4147 4148 geometric_distribution() : geometric_distribution(0.5) { } 4149 4150 explicit 4151 geometric_distribution(double __p) 4152 : _M_param(__p) 4153 { } 4154 4155 explicit 4156 geometric_distribution(const param_type& __p) 4157 : _M_param(__p) 4158 { } 4159 4160 /** 4161 * @brief Resets the distribution state. 4162 * 4163 * Does nothing for the geometric distribution. 4164 */ 4165 void 4166 reset() { } 4167 4168 /** 4169 * @brief Returns the distribution parameter @p p. 4170 */ 4171 double 4172 p() const 4173 { return _M_param.p(); } 4174 4175 /** 4176 * @brief Returns the parameter set of the distribution. 4177 */ 4178 param_type 4179 param() const 4180 { return _M_param; } 4181 4182 /** 4183 * @brief Sets the parameter set of the distribution. 4184 * @param __param The new parameter set of the distribution. 4185 */ 4186 void 4187 param(const param_type& __param) 4188 { _M_param = __param; } 4189 4190 /** 4191 * @brief Returns the greatest lower bound value of the distribution. 4192 */ 4193 result_type 4194 min() const 4195 { return 0; } 4196 4197 /** 4198 * @brief Returns the least upper bound value of the distribution. 4199 */ 4200 result_type 4201 max() const 4202 { return std::numeric_limits
::max(); } 4203 4204 /** 4205 * @brief Generating functions. 4206 */ 4207 template
4208 result_type 4209 operator()(_UniformRandomNumberGenerator& __urng) 4210 { return this->operator()(__urng, _M_param); } 4211 4212 template
4213 result_type 4214 operator()(_UniformRandomNumberGenerator& __urng, 4215 const param_type& __p); 4216 4217 template
4219 void 4220 __generate(_ForwardIterator __f, _ForwardIterator __t, 4221 _UniformRandomNumberGenerator& __urng) 4222 { this->__generate(__f, __t, __urng, _M_param); } 4223 4224 template
4226 void 4227 __generate(_ForwardIterator __f, _ForwardIterator __t, 4228 _UniformRandomNumberGenerator& __urng, 4229 const param_type& __p) 4230 { this->__generate_impl(__f, __t, __urng, __p); } 4231 4232 template
4233 void 4234 __generate(result_type* __f, result_type* __t, 4235 _UniformRandomNumberGenerator& __urng, 4236 const param_type& __p) 4237 { this->__generate_impl(__f, __t, __urng, __p); } 4238 4239 /** 4240 * @brief Return true if two geometric distributions have 4241 * the same parameters. 4242 */ 4243 friend bool 4244 operator==(const geometric_distribution& __d1, 4245 const geometric_distribution& __d2) 4246 { return __d1._M_param == __d2._M_param; } 4247 4248 private: 4249 template
4251 void 4252 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 4253 _UniformRandomNumberGenerator& __urng, 4254 const param_type& __p); 4255 4256 param_type _M_param; 4257 }; 4258 4259 #if __cpp_impl_three_way_comparison < 201907L 4260 /** 4261 * @brief Return true if two geometric distributions have 4262 * different parameters. 4263 */ 4264 template
4265 inline bool 4266 operator!=(const std::geometric_distribution<_IntType>& __d1, 4267 const std::geometric_distribution<_IntType>& __d2) 4268 { return !(__d1 == __d2); } 4269 #endif 4270 4271 /** 4272 * @brief Inserts a %geometric_distribution random number distribution 4273 * @p __x into the output stream @p __os. 4274 * 4275 * @param __os An output stream. 4276 * @param __x A %geometric_distribution random number distribution. 4277 * 4278 * @returns The output stream with the state of @p __x inserted or in 4279 * an error state. 4280 */ 4281 template
4283 std::basic_ostream<_CharT, _Traits>& 4284 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 4285 const std::geometric_distribution<_IntType>& __x); 4286 4287 /** 4288 * @brief Extracts a %geometric_distribution random number distribution 4289 * @p __x from the input stream @p __is. 4290 * 4291 * @param __is An input stream. 4292 * @param __x A %geometric_distribution random number generator engine. 4293 * 4294 * @returns The input stream with @p __x extracted or in an error state. 4295 */ 4296 template
4298 std::basic_istream<_CharT, _Traits>& 4299 operator>>(std::basic_istream<_CharT, _Traits>& __is, 4300 std::geometric_distribution<_IntType>& __x); 4301 4302 4303 /** 4304 * @brief A negative_binomial_distribution random number distribution. 4305 * 4306 * The formula for the negative binomial probability mass function is 4307 * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ 4308 * and @f$p@f$ are the parameters of the distribution. 4309 * 4310 * @headerfile random 4311 * @since C++11 4312 */ 4313 template
4314 class negative_binomial_distribution 4315 { 4316 static_assert(std::is_integral<_IntType>::value, 4317 "result_type must be an integral type"); 4318 4319 public: 4320 /** The type of the range of the distribution. */ 4321 typedef _IntType result_type; 4322 4323 /** Parameter type. */ 4324 struct param_type 4325 { 4326 typedef negative_binomial_distribution<_IntType> distribution_type; 4327 4328 param_type() : param_type(1) { } 4329 4330 explicit 4331 param_type(_IntType __k, double __p = 0.5) 4332 : _M_k(__k), _M_p(__p) 4333 { 4334 __glibcxx_assert((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0)); 4335 } 4336 4337 _IntType 4338 k() const 4339 { return _M_k; } 4340 4341 double 4342 p() const 4343 { return _M_p; } 4344 4345 friend bool 4346 operator==(const param_type& __p1, const param_type& __p2) 4347 { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; } 4348 4349 #if __cpp_impl_three_way_comparison < 201907L 4350 friend bool 4351 operator!=(const param_type& __p1, const param_type& __p2) 4352 { return !(__p1 == __p2); } 4353 #endif 4354 4355 private: 4356 _IntType _M_k; 4357 double _M_p; 4358 }; 4359 4360 negative_binomial_distribution() : negative_binomial_distribution(1) { } 4361 4362 explicit 4363 negative_binomial_distribution(_IntType __k, double __p = 0.5) 4364 : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p) 4365 { } 4366 4367 explicit 4368 negative_binomial_distribution(const param_type& __p) 4369 : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p()) 4370 { } 4371 4372 /** 4373 * @brief Resets the distribution state. 4374 */ 4375 void 4376 reset() 4377 { _M_gd.reset(); } 4378 4379 /** 4380 * @brief Return the @f$k@f$ parameter of the distribution. 4381 */ 4382 _IntType 4383 k() const 4384 { return _M_param.k(); } 4385 4386 /** 4387 * @brief Return the @f$p@f$ parameter of the distribution. 4388 */ 4389 double 4390 p() const 4391 { return _M_param.p(); } 4392 4393 /** 4394 * @brief Returns the parameter set of the distribution. 4395 */ 4396 param_type 4397 param() const 4398 { return _M_param; } 4399 4400 /** 4401 * @brief Sets the parameter set of the distribution. 4402 * @param __param The new parameter set of the distribution. 4403 */ 4404 void 4405 param(const param_type& __param) 4406 { _M_param = __param; } 4407 4408 /** 4409 * @brief Returns the greatest lower bound value of the distribution. 4410 */ 4411 result_type 4412 min() const 4413 { return result_type(0); } 4414 4415 /** 4416 * @brief Returns the least upper bound value of the distribution. 4417 */ 4418 result_type 4419 max() const 4420 { return std::numeric_limits
::max(); } 4421 4422 /** 4423 * @brief Generating functions. 4424 */ 4425 template
4426 result_type 4427 operator()(_UniformRandomNumberGenerator& __urng); 4428 4429 template
4430 result_type 4431 operator()(_UniformRandomNumberGenerator& __urng, 4432 const param_type& __p); 4433 4434 template
4436 void 4437 __generate(_ForwardIterator __f, _ForwardIterator __t, 4438 _UniformRandomNumberGenerator& __urng) 4439 { this->__generate_impl(__f, __t, __urng); } 4440 4441 template
4443 void 4444 __generate(_ForwardIterator __f, _ForwardIterator __t, 4445 _UniformRandomNumberGenerator& __urng, 4446 const param_type& __p) 4447 { this->__generate_impl(__f, __t, __urng, __p); } 4448 4449 template
4450 void 4451 __generate(result_type* __f, result_type* __t, 4452 _UniformRandomNumberGenerator& __urng) 4453 { this->__generate_impl(__f, __t, __urng); } 4454 4455 template
4456 void 4457 __generate(result_type* __f, result_type* __t, 4458 _UniformRandomNumberGenerator& __urng, 4459 const param_type& __p) 4460 { this->__generate_impl(__f, __t, __urng, __p); } 4461 4462 /** 4463 * @brief Return true if two negative binomial distributions have 4464 * the same parameters and the sequences that would be 4465 * generated are equal. 4466 */ 4467 friend bool 4468 operator==(const negative_binomial_distribution& __d1, 4469 const negative_binomial_distribution& __d2) 4470 { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; } 4471 4472 /** 4473 * @brief Inserts a %negative_binomial_distribution random 4474 * number distribution @p __x into the output stream @p __os. 4475 * 4476 * @param __os An output stream. 4477 * @param __x A %negative_binomial_distribution random number 4478 * distribution. 4479 * 4480 * @returns The output stream with the state of @p __x inserted or in 4481 * an error state. 4482 */ 4483 template
4484 friend std::basic_ostream<_CharT, _Traits>& 4485 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 4486 const std::negative_binomial_distribution<_IntType1>& __x); 4487 4488 /** 4489 * @brief Extracts a %negative_binomial_distribution random number 4490 * distribution @p __x from the input stream @p __is. 4491 * 4492 * @param __is An input stream. 4493 * @param __x A %negative_binomial_distribution random number 4494 * generator engine. 4495 * 4496 * @returns The input stream with @p __x extracted or in an error state. 4497 */ 4498 template
4499 friend std::basic_istream<_CharT, _Traits>& 4500 operator>>(std::basic_istream<_CharT, _Traits>& __is, 4501 std::negative_binomial_distribution<_IntType1>& __x); 4502 4503 private: 4504 template
4506 void 4507 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 4508 _UniformRandomNumberGenerator& __urng); 4509 template
4511 void 4512 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 4513 _UniformRandomNumberGenerator& __urng, 4514 const param_type& __p); 4515 4516 param_type _M_param; 4517 4518 std::gamma_distribution
_M_gd; 4519 }; 4520 4521 #if __cpp_impl_three_way_comparison < 201907L 4522 /** 4523 * @brief Return true if two negative binomial distributions are different. 4524 */ 4525 template
4526 inline bool 4527 operator!=(const std::negative_binomial_distribution<_IntType>& __d1, 4528 const std::negative_binomial_distribution<_IntType>& __d2) 4529 { return !(__d1 == __d2); } 4530 #endif 4531 4532 /// @} group random_distributions_bernoulli 4533 4534 /** 4535 * @addtogroup random_distributions_poisson Poisson Distributions 4536 * @ingroup random_distributions 4537 * @{ 4538 */ 4539 4540 /** 4541 * @brief A discrete Poisson random number distribution. 4542 * 4543 * The formula for the Poisson probability density function is 4544 * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the 4545 * parameter of the distribution. 4546 * 4547 * @headerfile random 4548 * @since C++11 4549 */ 4550 template
4551 class poisson_distribution 4552 { 4553 static_assert(std::is_integral<_IntType>::value, 4554 "result_type must be an integral type"); 4555 4556 public: 4557 /** The type of the range of the distribution. */ 4558 typedef _IntType result_type; 4559 4560 /** Parameter type. */ 4561 struct param_type 4562 { 4563 typedef poisson_distribution<_IntType> distribution_type; 4564 friend class poisson_distribution<_IntType>; 4565 4566 param_type() : param_type(1.0) { } 4567 4568 explicit 4569 param_type(double __mean) 4570 : _M_mean(__mean) 4571 { 4572 __glibcxx_assert(_M_mean > 0.0); 4573 _M_initialize(); 4574 } 4575 4576 double 4577 mean() const 4578 { return _M_mean; } 4579 4580 friend bool 4581 operator==(const param_type& __p1, const param_type& __p2) 4582 { return __p1._M_mean == __p2._M_mean; } 4583 4584 #if __cpp_impl_three_way_comparison < 201907L 4585 friend bool 4586 operator!=(const param_type& __p1, const param_type& __p2) 4587 { return !(__p1 == __p2); } 4588 #endif 4589 4590 private: 4591 // Hosts either log(mean) or the threshold of the simple method. 4592 void 4593 _M_initialize(); 4594 4595 double _M_mean; 4596 4597 double _M_lm_thr; 4598 #if _GLIBCXX_USE_C99_MATH_TR1 4599 double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb; 4600 #endif 4601 }; 4602 4603 // constructors and member functions 4604 4605 poisson_distribution() : poisson_distribution(1.0) { } 4606 4607 explicit 4608 poisson_distribution(double __mean) 4609 : _M_param(__mean), _M_nd() 4610 { } 4611 4612 explicit 4613 poisson_distribution(const param_type& __p) 4614 : _M_param(__p), _M_nd() 4615 { } 4616 4617 /** 4618 * @brief Resets the distribution state. 4619 */ 4620 void 4621 reset() 4622 { _M_nd.reset(); } 4623 4624 /** 4625 * @brief Returns the distribution parameter @p mean. 4626 */ 4627 double 4628 mean() const 4629 { return _M_param.mean(); } 4630 4631 /** 4632 * @brief Returns the parameter set of the distribution. 4633 */ 4634 param_type 4635 param() const 4636 { return _M_param; } 4637 4638 /** 4639 * @brief Sets the parameter set of the distribution. 4640 * @param __param The new parameter set of the distribution. 4641 */ 4642 void 4643 param(const param_type& __param) 4644 { _M_param = __param; } 4645 4646 /** 4647 * @brief Returns the greatest lower bound value of the distribution. 4648 */ 4649 result_type 4650 min() const 4651 { return 0; } 4652 4653 /** 4654 * @brief Returns the least upper bound value of the distribution. 4655 */ 4656 result_type 4657 max() const 4658 { return std::numeric_limits
::max(); } 4659 4660 /** 4661 * @brief Generating functions. 4662 */ 4663 template
4664 result_type 4665 operator()(_UniformRandomNumberGenerator& __urng) 4666 { return this->operator()(__urng, _M_param); } 4667 4668 template
4669 result_type 4670 operator()(_UniformRandomNumberGenerator& __urng, 4671 const param_type& __p); 4672 4673 template
4675 void 4676 __generate(_ForwardIterator __f, _ForwardIterator __t, 4677 _UniformRandomNumberGenerator& __urng) 4678 { this->__generate(__f, __t, __urng, _M_param); } 4679 4680 template
4682 void 4683 __generate(_ForwardIterator __f, _ForwardIterator __t, 4684 _UniformRandomNumberGenerator& __urng, 4685 const param_type& __p) 4686 { this->__generate_impl(__f, __t, __urng, __p); } 4687 4688 template
4689 void 4690 __generate(result_type* __f, result_type* __t, 4691 _UniformRandomNumberGenerator& __urng, 4692 const param_type& __p) 4693 { this->__generate_impl(__f, __t, __urng, __p); } 4694 4695 /** 4696 * @brief Return true if two Poisson distributions have the same 4697 * parameters and the sequences that would be generated 4698 * are equal. 4699 */ 4700 friend bool 4701 operator==(const poisson_distribution& __d1, 4702 const poisson_distribution& __d2) 4703 #ifdef _GLIBCXX_USE_C99_MATH_TR1 4704 { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } 4705 #else 4706 { return __d1._M_param == __d2._M_param; } 4707 #endif 4708 4709 /** 4710 * @brief Inserts a %poisson_distribution random number distribution 4711 * @p __x into the output stream @p __os. 4712 * 4713 * @param __os An output stream. 4714 * @param __x A %poisson_distribution random number distribution. 4715 * 4716 * @returns The output stream with the state of @p __x inserted or in 4717 * an error state. 4718 */ 4719 template
4720 friend std::basic_ostream<_CharT, _Traits>& 4721 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 4722 const std::poisson_distribution<_IntType1>& __x); 4723 4724 /** 4725 * @brief Extracts a %poisson_distribution random number distribution 4726 * @p __x from the input stream @p __is. 4727 * 4728 * @param __is An input stream. 4729 * @param __x A %poisson_distribution random number generator engine. 4730 * 4731 * @returns The input stream with @p __x extracted or in an error 4732 * state. 4733 */ 4734 template
4735 friend std::basic_istream<_CharT, _Traits>& 4736 operator>>(std::basic_istream<_CharT, _Traits>& __is, 4737 std::poisson_distribution<_IntType1>& __x); 4738 4739 private: 4740 template
4742 void 4743 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 4744 _UniformRandomNumberGenerator& __urng, 4745 const param_type& __p); 4746 4747 param_type _M_param; 4748 4749 // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. 4750 std::normal_distribution
_M_nd; 4751 }; 4752 4753 #if __cpp_impl_three_way_comparison < 201907L 4754 /** 4755 * @brief Return true if two Poisson distributions are different. 4756 */ 4757 template
4758 inline bool 4759 operator!=(const std::poisson_distribution<_IntType>& __d1, 4760 const std::poisson_distribution<_IntType>& __d2) 4761 { return !(__d1 == __d2); } 4762 #endif 4763 4764 /** 4765 * @brief An exponential continuous distribution for random numbers. 4766 * 4767 * The formula for the exponential probability density function is 4768 * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$. 4769 * 4770 *
4771 *
Distribution Statistics
4772 *
Mean
@f$\frac{1}{\lambda}@f$
4773 *
Median
@f$\frac{\ln 2}{\lambda}@f$
4774 *
Mode
@f$zero@f$
4775 *
Range
@f$[0, \infty]@f$
4776 *
Standard Deviation
@f$\frac{1}{\lambda}@f$
4777 *
4778 * 4779 * @headerfile random 4780 * @since C++11 4781 */ 4782 template
4783 class exponential_distribution 4784 { 4785 static_assert(std::is_floating_point<_RealType>::value, 4786 "result_type must be a floating point type"); 4787 4788 public: 4789 /** The type of the range of the distribution. */ 4790 typedef _RealType result_type; 4791 4792 /** Parameter type. */ 4793 struct param_type 4794 { 4795 typedef exponential_distribution<_RealType> distribution_type; 4796 4797 param_type() : param_type(1.0) { } 4798 4799 explicit 4800 param_type(_RealType __lambda) 4801 : _M_lambda(__lambda) 4802 { 4803 __glibcxx_assert(_M_lambda > _RealType(0)); 4804 } 4805 4806 _RealType 4807 lambda() const 4808 { return _M_lambda; } 4809 4810 friend bool 4811 operator==(const param_type& __p1, const param_type& __p2) 4812 { return __p1._M_lambda == __p2._M_lambda; } 4813 4814 #if __cpp_impl_three_way_comparison < 201907L 4815 friend bool 4816 operator!=(const param_type& __p1, const param_type& __p2) 4817 { return !(__p1 == __p2); } 4818 #endif 4819 4820 private: 4821 _RealType _M_lambda; 4822 }; 4823 4824 public: 4825 /** 4826 * @brief Constructs an exponential distribution with inverse scale 4827 * parameter 1.0 4828 */ 4829 exponential_distribution() : exponential_distribution(1.0) { } 4830 4831 /** 4832 * @brief Constructs an exponential distribution with inverse scale 4833 * parameter @f$\lambda@f$. 4834 */ 4835 explicit 4836 exponential_distribution(_RealType __lambda) 4837 : _M_param(__lambda) 4838 { } 4839 4840 explicit 4841 exponential_distribution(const param_type& __p) 4842 : _M_param(__p) 4843 { } 4844 4845 /** 4846 * @brief Resets the distribution state. 4847 * 4848 * Has no effect on exponential distributions. 4849 */ 4850 void 4851 reset() { } 4852 4853 /** 4854 * @brief Returns the inverse scale parameter of the distribution. 4855 */ 4856 _RealType 4857 lambda() const 4858 { return _M_param.lambda(); } 4859 4860 /** 4861 * @brief Returns the parameter set of the distribution. 4862 */ 4863 param_type 4864 param() const 4865 { return _M_param; } 4866 4867 /** 4868 * @brief Sets the parameter set of the distribution. 4869 * @param __param The new parameter set of the distribution. 4870 */ 4871 void 4872 param(const param_type& __param) 4873 { _M_param = __param; } 4874 4875 /** 4876 * @brief Returns the greatest lower bound value of the distribution. 4877 */ 4878 result_type 4879 min() const 4880 { return result_type(0); } 4881 4882 /** 4883 * @brief Returns the least upper bound value of the distribution. 4884 */ 4885 result_type 4886 max() const 4887 { return std::numeric_limits
::max(); } 4888 4889 /** 4890 * @brief Generating functions. 4891 */ 4892 template
4893 result_type 4894 operator()(_UniformRandomNumberGenerator& __urng) 4895 { return this->operator()(__urng, _M_param); } 4896 4897 template
4898 result_type 4899 operator()(_UniformRandomNumberGenerator& __urng, 4900 const param_type& __p) 4901 { 4902 __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 4903 __aurng(__urng); 4904 return -std::log(result_type(1) - __aurng()) / __p.lambda(); 4905 } 4906 4907 template
4909 void 4910 __generate(_ForwardIterator __f, _ForwardIterator __t, 4911 _UniformRandomNumberGenerator& __urng) 4912 { this->__generate(__f, __t, __urng, _M_param); } 4913 4914 template
4916 void 4917 __generate(_ForwardIterator __f, _ForwardIterator __t, 4918 _UniformRandomNumberGenerator& __urng, 4919 const param_type& __p) 4920 { this->__generate_impl(__f, __t, __urng, __p); } 4921 4922 template