Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/ext/random
1 // Random number extensions -*- C++ -*- 2 3 // Copyright (C) 2012-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file ext/random 26 * This file is a GNU extension to the Standard C++ Library. 27 */ 28 29 #ifndef _EXT_RANDOM 30 #define _EXT_RANDOM 1 31 32 #ifdef _GLIBCXX_SYSHDR 33 #pragma GCC system_header 34 #endif 35 36 #include <bits/requires_hosted.h> // GNU extensions are currently omitted 37 38 #if __cplusplus < 201103L 39 # include <bits/c++0x_warning.h> 40 #else 41 42 #include <random> 43 #include <algorithm> 44 #include <array> 45 #include <ext/cmath> 46 #ifdef __SSE2__ 47 # include <emmintrin.h> 48 #endif 49 50 #ifdef UINT32_C 51 52 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 57 58 /* Mersenne twister implementation optimized for vector operations. 59 * 60 * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ 61 */ 62 template<typename _UIntType, size_t __m, 63 size_t __pos1, size_t __sl1, size_t __sl2, 64 size_t __sr1, size_t __sr2, 65 uint32_t __msk1, uint32_t __msk2, 66 uint32_t __msk3, uint32_t __msk4, 67 uint32_t __parity1, uint32_t __parity2, 68 uint32_t __parity3, uint32_t __parity4> 69 class simd_fast_mersenne_twister_engine 70 { 71 static_assert(std::is_unsigned<_UIntType>::value, "template argument " 72 "substituting _UIntType not an unsigned integral type"); 73 static_assert(__sr1 < 32, "first right shift too large"); 74 static_assert(__sr2 < 16, "second right shift too large"); 75 static_assert(__sl1 < 32, "first left shift too large"); 76 static_assert(__sl2 < 16, "second left shift too large"); 77 78 public: 79 typedef _UIntType result_type; 80 81 private: 82 static constexpr size_t m_w = sizeof(result_type) * 8; 83 static constexpr size_t _M_nstate = __m / 128 + 1; 84 static constexpr size_t _M_nstate32 = _M_nstate * 4; 85 86 static_assert(std::is_unsigned<_UIntType>::value, "template argument " 87 "substituting _UIntType not an unsigned integral type"); 88 static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); 89 static_assert(16 % sizeof(_UIntType) == 0, 90 "UIntType size must divide 16"); 91 92 template<typename _Sseq> 93 using _If_seed_seq 94 = std::__detail::_If_seed_seq_for<_Sseq, 95 simd_fast_mersenne_twister_engine, 96 result_type>; 97 98 public: 99 static constexpr size_t state_size = _M_nstate * (16 100 / sizeof(result_type)); 101 static constexpr result_type default_seed = 5489u; 102 103 // constructors and member functions 104 105 simd_fast_mersenne_twister_engine() 106 : simd_fast_mersenne_twister_engine(default_seed) 107 { } 108 109 explicit 110 simd_fast_mersenne_twister_engine(result_type __sd) 111 { seed(__sd); } 112 113 template<typename _Sseq, typename = _If_seed_seq<_Sseq>> 114 explicit 115 simd_fast_mersenne_twister_engine(_Sseq& __q) 116 { seed(__q); } 117 118 void 119 seed(result_type __sd = default_seed); 120 121 template<typename _Sseq> 122 _If_seed_seq<_Sseq> 123 seed(_Sseq& __q); 124 125 static constexpr result_type 126 min() 127 { return 0; } 128 129 static constexpr result_type 130 max() 131 { return std::numeric_limits<result_type>::max(); } 132 133 void 134 discard(unsigned long long __z); 135 136 result_type 137 operator()() 138 { 139 if (__builtin_expect(_M_pos >= state_size, 0)) 140 _M_gen_rand(); 141 142 return _M_stateT[_M_pos++]; 143 } 144 145 template<typename _UIntType_2, size_t __m_2, 146 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, 147 size_t __sr1_2, size_t __sr2_2, 148 uint32_t __msk1_2, uint32_t __msk2_2, 149 uint32_t __msk3_2, uint32_t __msk4_2, 150 uint32_t __parity1_2, uint32_t __parity2_2, 151 uint32_t __parity3_2, uint32_t __parity4_2> 152 friend bool 153 operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, 154 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, 155 __msk1_2, __msk2_2, __msk3_2, __msk4_2, 156 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, 157 const simd_fast_mersenne_twister_engine<_UIntType_2, 158 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, 159 __msk1_2, __msk2_2, __msk3_2, __msk4_2, 160 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); 161 162 template<typename _UIntType_2, size_t __m_2, 163 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, 164 size_t __sr1_2, size_t __sr2_2, 165 uint32_t __msk1_2, uint32_t __msk2_2, 166 uint32_t __msk3_2, uint32_t __msk4_2, 167 uint32_t __parity1_2, uint32_t __parity2_2, 168 uint32_t __parity3_2, uint32_t __parity4_2, 169 typename _CharT, typename _Traits> 170 friend std::basic_ostream<_CharT, _Traits>& 171 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 172 const __gnu_cxx::simd_fast_mersenne_twister_engine 173 <_UIntType_2, 174 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, 175 __msk1_2, __msk2_2, __msk3_2, __msk4_2, 176 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); 177 178 template<typename _UIntType_2, size_t __m_2, 179 size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, 180 size_t __sr1_2, size_t __sr2_2, 181 uint32_t __msk1_2, uint32_t __msk2_2, 182 uint32_t __msk3_2, uint32_t __msk4_2, 183 uint32_t __parity1_2, uint32_t __parity2_2, 184 uint32_t __parity3_2, uint32_t __parity4_2, 185 typename _CharT, typename _Traits> 186 friend std::basic_istream<_CharT, _Traits>& 187 operator>>(std::basic_istream<_CharT, _Traits>& __is, 188 __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, 189 __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, 190 __msk1_2, __msk2_2, __msk3_2, __msk4_2, 191 __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); 192 193 private: 194 union 195 { 196 #ifdef __SSE2__ 197 __m128i _M_state[_M_nstate]; 198 #endif 199 #ifdef __ARM_NEON 200 #ifdef __aarch64__ 201 __Uint32x4_t _M_state[_M_nstate]; 202 #endif 203 #endif 204 uint32_t _M_state32[_M_nstate32]; 205 result_type _M_stateT[state_size]; 206 } __attribute__ ((__aligned__ (16))); 207 size_t _M_pos; 208 209 void _M_gen_rand(void); 210 void _M_period_certification(); 211 }; 212 213 #if __cpp_impl_three_way_comparison < 201907L 214 template<typename _UIntType, size_t __m, 215 size_t __pos1, size_t __sl1, size_t __sl2, 216 size_t __sr1, size_t __sr2, 217 uint32_t __msk1, uint32_t __msk2, 218 uint32_t __msk3, uint32_t __msk4, 219 uint32_t __parity1, uint32_t __parity2, 220 uint32_t __parity3, uint32_t __parity4> 221 inline bool 222 operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, 223 __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, 224 __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, 225 const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, 226 __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, 227 __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) 228 { return !(__lhs == __rhs); } 229 #endif 230 231 /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined 232 * in the C implementation by Daito and Matsumoto, as both a 32-bit 233 * and 64-bit version. 234 */ 235 typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2, 236 15, 3, 13, 3, 237 0xfdff37ffU, 0xef7f3f7dU, 238 0xff777b7dU, 0x7ff7fb2fU, 239 0x00000001U, 0x00000000U, 240 0x00000000U, 0x5986f054U> 241 sfmt607; 242 243 typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2, 244 15, 3, 13, 3, 245 0xfdff37ffU, 0xef7f3f7dU, 246 0xff777b7dU, 0x7ff7fb2fU, 247 0x00000001U, 0x00000000U, 248 0x00000000U, 0x5986f054U> 249 sfmt607_64; 250 251 252 typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7, 253 14, 3, 5, 1, 254 0xf7fefffdU, 0x7fefcfffU, 255 0xaff3ef3fU, 0xb5ffff7fU, 256 0x00000001U, 0x00000000U, 257 0x00000000U, 0x20000000U> 258 sfmt1279; 259 260 typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7, 261 14, 3, 5, 1, 262 0xf7fefffdU, 0x7fefcfffU, 263 0xaff3ef3fU, 0xb5ffff7fU, 264 0x00000001U, 0x00000000U, 265 0x00000000U, 0x20000000U> 266 sfmt1279_64; 267 268 269 typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12, 270 19, 1, 5, 1, 271 0xbff7ffbfU, 0xfdfffffeU, 272 0xf7ffef7fU, 0xf2f7cbbfU, 273 0x00000001U, 0x00000000U, 274 0x00000000U, 0x41dfa600U> 275 sfmt2281; 276 277 typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12, 278 19, 1, 5, 1, 279 0xbff7ffbfU, 0xfdfffffeU, 280 0xf7ffef7fU, 0xf2f7cbbfU, 281 0x00000001U, 0x00000000U, 282 0x00000000U, 0x41dfa600U> 283 sfmt2281_64; 284 285 286 typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17, 287 20, 1, 7, 1, 288 0x9f7bffffU, 0x9fffff5fU, 289 0x3efffffbU, 0xfffff7bbU, 290 0xa8000001U, 0xaf5390a3U, 291 0xb740b3f8U, 0x6c11486dU> 292 sfmt4253; 293 294 typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17, 295 20, 1, 7, 1, 296 0x9f7bffffU, 0x9fffff5fU, 297 0x3efffffbU, 0xfffff7bbU, 298 0xa8000001U, 0xaf5390a3U, 299 0xb740b3f8U, 0x6c11486dU> 300 sfmt4253_64; 301 302 303 typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68, 304 14, 3, 7, 3, 305 0xeffff7fbU, 0xffffffefU, 306 0xdfdfbfffU, 0x7fffdbfdU, 307 0x00000001U, 0x00000000U, 308 0xe8148000U, 0xd0c7afa3U> 309 sfmt11213; 310 311 typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68, 312 14, 3, 7, 3, 313 0xeffff7fbU, 0xffffffefU, 314 0xdfdfbfffU, 0x7fffdbfdU, 315 0x00000001U, 0x00000000U, 316 0xe8148000U, 0xd0c7afa3U> 317 sfmt11213_64; 318 319 320 typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122, 321 18, 1, 11, 1, 322 0xdfffffefU, 0xddfecb7fU, 323 0xbffaffffU, 0xbffffff6U, 324 0x00000001U, 0x00000000U, 325 0x00000000U, 0x13c9e684U> 326 sfmt19937; 327 328 typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122, 329 18, 1, 11, 1, 330 0xdfffffefU, 0xddfecb7fU, 331 0xbffaffffU, 0xbffffff6U, 332 0x00000001U, 0x00000000U, 333 0x00000000U, 0x13c9e684U> 334 sfmt19937_64; 335 336 337 typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330, 338 5, 3, 9, 3, 339 0xeffffffbU, 0xdfbebfffU, 340 0xbfbf7befU, 0x9ffd7bffU, 341 0x00000001U, 0x00000000U, 342 0xa3ac4000U, 0xecc1327aU> 343 sfmt44497; 344 345 typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330, 346 5, 3, 9, 3, 347 0xeffffffbU, 0xdfbebfffU, 348 0xbfbf7befU, 0x9ffd7bffU, 349 0x00000001U, 0x00000000U, 350 0xa3ac4000U, 0xecc1327aU> 351 sfmt44497_64; 352 353 #if __SIZE_WIDTH__ >= 32 354 355 typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366, 356 6, 7, 19, 1, 357 0xfdbffbffU, 0xbff7ff3fU, 358 0xfd77efffU, 0xbf9ff3ffU, 359 0x00000001U, 0x00000000U, 360 0x00000000U, 0xe9528d85U> 361 sfmt86243; 362 363 typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366, 364 6, 7, 19, 1, 365 0xfdbffbffU, 0xbff7ff3fU, 366 0xfd77efffU, 0xbf9ff3ffU, 367 0x00000001U, 0x00000000U, 368 0x00000000U, 0xe9528d85U> 369 sfmt86243_64; 370 371 372 typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110, 373 19, 1, 21, 1, 374 0xffffbb5fU, 0xfb6ebf95U, 375 0xfffefffaU, 0xcff77fffU, 376 0x00000001U, 0x00000000U, 377 0xcb520000U, 0xc7e91c7dU> 378 sfmt132049; 379 380 typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110, 381 19, 1, 21, 1, 382 0xffffbb5fU, 0xfb6ebf95U, 383 0xfffefffaU, 0xcff77fffU, 384 0x00000001U, 0x00000000U, 385 0xcb520000U, 0xc7e91c7dU> 386 sfmt132049_64; 387 388 389 typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627, 390 11, 3, 10, 1, 391 0xbff7bff7U, 0xbfffffffU, 392 0xbffffa7fU, 0xffddfbfbU, 393 0xf8000001U, 0x89e80709U, 394 0x3bd2b64bU, 0x0c64b1e4U> 395 sfmt216091; 396 397 typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627, 398 11, 3, 10, 1, 399 0xbff7bff7U, 0xbfffffffU, 400 0xbffffa7fU, 0xffddfbfbU, 401 0xf8000001U, 0x89e80709U, 402 0x3bd2b64bU, 0x0c64b1e4U> 403 sfmt216091_64; 404 #endif // __SIZE_WIDTH__ >= 32 405 406 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 407 408 /** 409 * @brief A beta continuous distribution for random numbers. 410 * 411 * The formula for the beta probability density function is: 412 * @f[ 413 * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} 414 * x^{\alpha - 1} (1 - x)^{\beta - 1} 415 * @f] 416 */ 417 template<typename _RealType = double> 418 class beta_distribution 419 { 420 static_assert(std::is_floating_point<_RealType>::value, 421 "template argument not a floating point type"); 422 423 public: 424 /** The type of the range of the distribution. */ 425 typedef _RealType result_type; 426 427 /** Parameter type. */ 428 struct param_type 429 { 430 typedef beta_distribution<_RealType> distribution_type; 431 friend class beta_distribution<_RealType>; 432 433 param_type() : param_type(1) { } 434 435 explicit 436 param_type(_RealType __alpha_val, _RealType __beta_val = _RealType(1)) 437 : _M_alpha(__alpha_val), _M_beta(__beta_val) 438 { 439 __glibcxx_assert(_M_alpha > _RealType(0)); 440 __glibcxx_assert(_M_beta > _RealType(0)); 441 } 442 443 _RealType 444 alpha() const 445 { return _M_alpha; } 446 447 _RealType 448 beta() const 449 { return _M_beta; } 450 451 friend bool 452 operator==(const param_type& __p1, const param_type& __p2) 453 { return (__p1._M_alpha == __p2._M_alpha 454 && __p1._M_beta == __p2._M_beta); } 455 456 #if __cpp_impl_three_way_comparison < 201907L 457 friend bool 458 operator!=(const param_type& __p1, const param_type& __p2) 459 { return !(__p1 == __p2); } 460 #endif 461 462 private: 463 void 464 _M_initialize(); 465 466 _RealType _M_alpha; 467 _RealType _M_beta; 468 }; 469 470 public: 471 beta_distribution() : beta_distribution(1.0) { } 472 473 /** 474 * @brief Constructs a beta distribution with parameters 475 * @f$\alpha@f$ and @f$\beta@f$. 476 */ 477 explicit 478 beta_distribution(_RealType __alpha_val, 479 _RealType __beta_val = _RealType(1)) 480 : _M_param(__alpha_val, __beta_val) 481 { } 482 483 explicit 484 beta_distribution(const param_type& __p) 485 : _M_param(__p) 486 { } 487 488 /** 489 * @brief Resets the distribution state. 490 */ 491 void 492 reset() 493 { } 494 495 /** 496 * @brief Returns the @f$\alpha@f$ of the distribution. 497 */ 498 _RealType 499 alpha() const 500 { return _M_param.alpha(); } 501 502 /** 503 * @brief Returns the @f$\beta@f$ of the distribution. 504 */ 505 _RealType 506 beta() const 507 { return _M_param.beta(); } 508 509 /** 510 * @brief Returns the parameter set of the distribution. 511 */ 512 param_type 513 param() const 514 { return _M_param; } 515 516 /** 517 * @brief Sets the parameter set of the distribution. 518 * @param __param The new parameter set of the distribution. 519 */ 520 void 521 param(const param_type& __param) 522 { _M_param = __param; } 523 524 /** 525 * @brief Returns the greatest lower bound value of the distribution. 526 */ 527 result_type 528 min() const 529 { return result_type(0); } 530 531 /** 532 * @brief Returns the least upper bound value of the distribution. 533 */ 534 result_type 535 max() const 536 { return result_type(1); } 537 538 /** 539 * @brief Generating functions. 540 */ 541 template<typename _UniformRandomNumberGenerator> 542 result_type 543 operator()(_UniformRandomNumberGenerator& __urng) 544 { return this->operator()(__urng, _M_param); } 545 546 template<typename _UniformRandomNumberGenerator> 547 result_type 548 operator()(_UniformRandomNumberGenerator& __urng, 549 const param_type& __p); 550 551 template<typename _ForwardIterator, 552 typename _UniformRandomNumberGenerator> 553 void 554 __generate(_ForwardIterator __f, _ForwardIterator __t, 555 _UniformRandomNumberGenerator& __urng) 556 { this->__generate(__f, __t, __urng, _M_param); } 557 558 template<typename _ForwardIterator, 559 typename _UniformRandomNumberGenerator> 560 void 561 __generate(_ForwardIterator __f, _ForwardIterator __t, 562 _UniformRandomNumberGenerator& __urng, 563 const param_type& __p) 564 { this->__generate_impl(__f, __t, __urng, __p); } 565 566 template<typename _UniformRandomNumberGenerator> 567 void 568 __generate(result_type* __f, result_type* __t, 569 _UniformRandomNumberGenerator& __urng, 570 const param_type& __p) 571 { this->__generate_impl(__f, __t, __urng, __p); } 572 573 /** 574 * @brief Return true if two beta distributions have the same 575 * parameters and the sequences that would be generated 576 * are equal. 577 */ 578 friend bool 579 operator==(const beta_distribution& __d1, 580 const beta_distribution& __d2) 581 { return __d1._M_param == __d2._M_param; } 582 583 /** 584 * @brief Inserts a %beta_distribution random number distribution 585 * @p __x into the output stream @p __os. 586 * 587 * @param __os An output stream. 588 * @param __x A %beta_distribution random number distribution. 589 * 590 * @returns The output stream with the state of @p __x inserted or in 591 * an error state. 592 */ 593 template<typename _RealType1, typename _CharT, typename _Traits> 594 friend std::basic_ostream<_CharT, _Traits>& 595 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 596 const __gnu_cxx::beta_distribution<_RealType1>& __x); 597 598 /** 599 * @brief Extracts a %beta_distribution random number distribution 600 * @p __x from the input stream @p __is. 601 * 602 * @param __is An input stream. 603 * @param __x A %beta_distribution random number generator engine. 604 * 605 * @returns The input stream with @p __x extracted or in an error state. 606 */ 607 template<typename _RealType1, typename _CharT, typename _Traits> 608 friend std::basic_istream<_CharT, _Traits>& 609 operator>>(std::basic_istream<_CharT, _Traits>& __is, 610 __gnu_cxx::beta_distribution<_RealType1>& __x); 611 612 private: 613 template<typename _ForwardIterator, 614 typename _UniformRandomNumberGenerator> 615 void 616 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 617 _UniformRandomNumberGenerator& __urng, 618 const param_type& __p); 619 620 param_type _M_param; 621 }; 622 623 #if __cpp_impl_three_way_comparison < 201907L 624 /** 625 * @brief Return true if two beta distributions are different. 626 */ 627 template<typename _RealType> 628 inline bool 629 operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, 630 const __gnu_cxx::beta_distribution<_RealType>& __d2) 631 { return !(__d1 == __d2); } 632 #endif 633 634 /** 635 * @brief A multi-variate normal continuous distribution for random numbers. 636 * 637 * The formula for the normal probability density function is 638 * @f[ 639 * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = 640 * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} 641 * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} 642 * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} 643 * @f] 644 * 645 * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are 646 * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance 647 * matrix (which must be positive-definite). 648 */ 649 template<std::size_t _Dimen, typename _RealType = double> 650 class normal_mv_distribution 651 { 652 static_assert(std::is_floating_point<_RealType>::value, 653 "template argument not a floating point type"); 654 static_assert(_Dimen != 0, "dimension is zero"); 655 656 public: 657 /** The type of the range of the distribution. */ 658 typedef std::array<_RealType, _Dimen> result_type; 659 /** Parameter type. */ 660 class param_type 661 { 662 static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; 663 664 public: 665 typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; 666 friend class normal_mv_distribution<_Dimen, _RealType>; 667 668 param_type() 669 { 670 std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); 671 auto __it = _M_t.begin(); 672 for (size_t __i = 0; __i < _Dimen; ++__i) 673 { 674 std::fill_n(__it, __i, _RealType(0)); 675 __it += __i; 676 *__it++ = _RealType(1); 677 } 678 } 679 680 template<typename _ForwardIterator1, typename _ForwardIterator2> 681 param_type(_ForwardIterator1 __meanbegin, 682 _ForwardIterator1 __meanend, 683 _ForwardIterator2 __varcovbegin, 684 _ForwardIterator2 __varcovend) 685 { 686 __glibcxx_function_requires(_ForwardIteratorConcept< 687 _ForwardIterator1>) 688 __glibcxx_function_requires(_ForwardIteratorConcept< 689 _ForwardIterator2>) 690 _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) 691 <= _Dimen); 692 const auto __dist = std::distance(__varcovbegin, __varcovend); 693 _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen 694 || __dist == _Dimen * (_Dimen + 1) / 2 695 || __dist == _Dimen); 696 697 if (__dist == _Dimen * _Dimen) 698 _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); 699 else if (__dist == _Dimen * (_Dimen + 1) / 2) 700 _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); 701 else 702 { 703 __glibcxx_assert(__dist == _Dimen); 704 _M_init_diagonal(__meanbegin, __meanend, 705 __varcovbegin, __varcovend); 706 } 707 } 708 709 param_type(std::initializer_list<_RealType> __mean, 710 std::initializer_list<_RealType> __varcov) 711 { 712 _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); 713 _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen 714 || __varcov.size() == _Dimen * (_Dimen + 1) / 2 715 || __varcov.size() == _Dimen); 716 717 if (__varcov.size() == _Dimen * _Dimen) 718 _M_init_full(__mean.begin(), __mean.end(), 719 __varcov.begin(), __varcov.end()); 720 else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) 721 _M_init_lower(__mean.begin(), __mean.end(), 722 __varcov.begin(), __varcov.end()); 723 else 724 { 725 __glibcxx_assert(__varcov.size() == _Dimen); 726 _M_init_diagonal(__mean.begin(), __mean.end(), 727 __varcov.begin(), __varcov.end()); 728 } 729 } 730 731 std::array<_RealType, _Dimen> 732 mean() const 733 { return _M_mean; } 734 735 std::array<_RealType, _M_t_size> 736 varcov() const 737 { return _M_t; } 738 739 friend bool 740 operator==(const param_type& __p1, const param_type& __p2) 741 { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } 742 743 #if __cpp_impl_three_way_comparison < 201907L 744 friend bool 745 operator!=(const param_type& __p1, const param_type& __p2) 746 { return !(__p1 == __p2); } 747 #endif 748 749 private: 750 template <typename _InputIterator1, typename _InputIterator2> 751 void _M_init_full(_InputIterator1 __meanbegin, 752 _InputIterator1 __meanend, 753 _InputIterator2 __varcovbegin, 754 _InputIterator2 __varcovend); 755 template <typename _InputIterator1, typename _InputIterator2> 756 void _M_init_lower(_InputIterator1 __meanbegin, 757 _InputIterator1 __meanend, 758 _InputIterator2 __varcovbegin, 759 _InputIterator2 __varcovend); 760 template <typename _InputIterator1, typename _InputIterator2> 761 void _M_init_diagonal(_InputIterator1 __meanbegin, 762 _InputIterator1 __meanend, 763 _InputIterator2 __varbegin, 764 _InputIterator2 __varend); 765 766 // param_type constructors apply Cholesky decomposition to the 767 // varcov matrix in _M_init_full and _M_init_lower, but the 768 // varcov matrix output ot a stream is already decomposed, so 769 // we need means to restore it as-is when reading it back in. 770 template<size_t _Dimen1, typename _RealType1, 771 typename _CharT, typename _Traits> 772 friend std::basic_istream<_CharT, _Traits>& 773 operator>>(std::basic_istream<_CharT, _Traits>& __is, 774 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& 775 __x); 776 param_type(std::array<_RealType, _Dimen> const &__mean, 777 std::array<_RealType, _M_t_size> const &__varcov) 778 : _M_mean (__mean), _M_t (__varcov) 779 {} 780 781 std::array<_RealType, _Dimen> _M_mean; 782 std::array<_RealType, _M_t_size> _M_t; 783 }; 784 785 public: 786 normal_mv_distribution() 787 : _M_param(), _M_nd() 788 { } 789 790 template<typename _ForwardIterator1, typename _ForwardIterator2> 791 normal_mv_distribution(_ForwardIterator1 __meanbegin, 792 _ForwardIterator1 __meanend, 793 _ForwardIterator2 __varcovbegin, 794 _ForwardIterator2 __varcovend) 795 : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), 796 _M_nd() 797 { } 798 799 normal_mv_distribution(std::initializer_list<_RealType> __mean, 800 std::initializer_list<_RealType> __varcov) 801 : _M_param(__mean, __varcov), _M_nd() 802 { } 803 804 explicit 805 normal_mv_distribution(const param_type& __p) 806 : _M_param(__p), _M_nd() 807 { } 808 809 /** 810 * @brief Resets the distribution state. 811 */ 812 void 813 reset() 814 { _M_nd.reset(); } 815 816 /** 817 * @brief Returns the mean of the distribution. 818 */ 819 result_type 820 mean() const 821 { return _M_param.mean(); } 822 823 /** 824 * @brief Returns the compact form of the variance/covariance 825 * matrix of the distribution. 826 */ 827 std::array<_RealType, _Dimen * (_Dimen + 1) / 2> 828 varcov() const 829 { return _M_param.varcov(); } 830 831 /** 832 * @brief Returns the parameter set of the distribution. 833 */ 834 param_type 835 param() const 836 { return _M_param; } 837 838 /** 839 * @brief Sets the parameter set of the distribution. 840 * @param __param The new parameter set of the distribution. 841 */ 842 void 843 param(const param_type& __param) 844 { _M_param = __param; } 845 846 /** 847 * @brief Returns the greatest lower bound value of the distribution. 848 */ 849 result_type 850 min() const 851 { result_type __res; 852 __res.fill(std::numeric_limits<_RealType>::lowest()); 853 return __res; } 854 855 /** 856 * @brief Returns the least upper bound value of the distribution. 857 */ 858 result_type 859 max() const 860 { result_type __res; 861 __res.fill(std::numeric_limits<_RealType>::max()); 862 return __res; } 863 864 /** 865 * @brief Generating functions. 866 */ 867 template<typename _UniformRandomNumberGenerator> 868 result_type 869 operator()(_UniformRandomNumberGenerator& __urng) 870 { return this->operator()(__urng, _M_param); } 871 872 template<typename _UniformRandomNumberGenerator> 873 result_type 874 operator()(_UniformRandomNumberGenerator& __urng, 875 const param_type& __p); 876 877 template<typename _ForwardIterator, 878 typename _UniformRandomNumberGenerator> 879 void 880 __generate(_ForwardIterator __f, _ForwardIterator __t, 881 _UniformRandomNumberGenerator& __urng) 882 { return this->__generate_impl(__f, __t, __urng, _M_param); } 883 884 template<typename _ForwardIterator, 885 typename _UniformRandomNumberGenerator> 886 void 887 __generate(_ForwardIterator __f, _ForwardIterator __t, 888 _UniformRandomNumberGenerator& __urng, 889 const param_type& __p) 890 { return this->__generate_impl(__f, __t, __urng, __p); } 891 892 /** 893 * @brief Return true if two multi-variant normal distributions have 894 * the same parameters and the sequences that would 895 * be generated are equal. 896 */ 897 template<size_t _Dimen1, typename _RealType1> 898 friend bool 899 operator==(const 900 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& 901 __d1, 902 const 903 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& 904 __d2); 905 906 /** 907 * @brief Inserts a %normal_mv_distribution random number distribution 908 * @p __x into the output stream @p __os. 909 * 910 * @param __os An output stream. 911 * @param __x A %normal_mv_distribution random number distribution. 912 * 913 * @returns The output stream with the state of @p __x inserted or in 914 * an error state. 915 */ 916 template<size_t _Dimen1, typename _RealType1, 917 typename _CharT, typename _Traits> 918 friend std::basic_ostream<_CharT, _Traits>& 919 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 920 const 921 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& 922 __x); 923 924 /** 925 * @brief Extracts a %normal_mv_distribution random number distribution 926 * @p __x from the input stream @p __is. 927 * 928 * @param __is An input stream. 929 * @param __x A %normal_mv_distribution random number generator engine. 930 * 931 * @returns The input stream with @p __x extracted or in an error 932 * state. 933 */ 934 template<size_t _Dimen1, typename _RealType1, 935 typename _CharT, typename _Traits> 936 friend std::basic_istream<_CharT, _Traits>& 937 operator>>(std::basic_istream<_CharT, _Traits>& __is, 938 __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& 939 __x); 940 941 private: 942 template<typename _ForwardIterator, 943 typename _UniformRandomNumberGenerator> 944 void 945 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 946 _UniformRandomNumberGenerator& __urng, 947 const param_type& __p); 948 949 param_type _M_param; 950 std::normal_distribution<_RealType> _M_nd; 951 }; 952 953 #if __cpp_impl_three_way_comparison < 201907L 954 /** 955 * @brief Return true if two multi-variate normal distributions are 956 * different. 957 */ 958 template<size_t _Dimen, typename _RealType> 959 inline bool 960 operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& 961 __d1, 962 const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& 963 __d2) 964 { return !(__d1 == __d2); } 965 #endif 966 967 /** 968 * @brief A Rice continuous distribution for random numbers. 969 * 970 * The formula for the Rice probability density function is 971 * @f[ 972 * p(x|\nu,\sigma) = \frac{x}{\sigma^2} 973 * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) 974 * I_0\left(\frac{x \nu}{\sigma^2}\right) 975 * @f] 976 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind 977 * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. 978 * 979 * <table border=1 cellpadding=10 cellspacing=0> 980 * <caption align=top>Distribution Statistics</caption> 981 * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> 982 * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2 983 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> 984 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> 985 * </table> 986 * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. 987 */ 988 template<typename _RealType = double> 989 class 990 rice_distribution 991 { 992 static_assert(std::is_floating_point<_RealType>::value, 993 "template argument not a floating point type"); 994 public: 995 /** The type of the range of the distribution. */ 996 typedef _RealType result_type; 997 998 /** Parameter type. */ 999 struct param_type 1000 { 1001 typedef rice_distribution<result_type> distribution_type; 1002 1003 param_type() : param_type(0) { } 1004 1005 param_type(result_type __nu_val, 1006 result_type __sigma_val = result_type(1)) 1007 : _M_nu(__nu_val), _M_sigma(__sigma_val) 1008 { 1009 __glibcxx_assert(_M_nu >= result_type(0)); 1010 __glibcxx_assert(_M_sigma > result_type(0)); 1011 } 1012 1013 result_type 1014 nu() const 1015 { return _M_nu; } 1016 1017 result_type 1018 sigma() const 1019 { return _M_sigma; } 1020 1021 friend bool 1022 operator==(const param_type& __p1, const param_type& __p2) 1023 { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; } 1024 1025 #if __cpp_impl_three_way_comparison < 201907L 1026 friend bool 1027 operator!=(const param_type& __p1, const param_type& __p2) 1028 { return !(__p1 == __p2); } 1029 #endif 1030 1031 private: 1032 void _M_initialize(); 1033 1034 result_type _M_nu; 1035 result_type _M_sigma; 1036 }; 1037 1038 /** 1039 * @brief Constructors. 1040 * @{ 1041 */ 1042 1043 rice_distribution() : rice_distribution(0) { } 1044 1045 explicit 1046 rice_distribution(result_type __nu_val, 1047 result_type __sigma_val = result_type(1)) 1048 : _M_param(__nu_val, __sigma_val), 1049 _M_ndx(__nu_val, __sigma_val), 1050 _M_ndy(result_type(0), __sigma_val) 1051 { } 1052 1053 explicit 1054 rice_distribution(const param_type& __p) 1055 : _M_param(__p), 1056 _M_ndx(__p.nu(), __p.sigma()), 1057 _M_ndy(result_type(0), __p.sigma()) 1058 { } 1059 1060 /// @} 1061 1062 /** 1063 * @brief Resets the distribution state. 1064 */ 1065 void 1066 reset() 1067 { 1068 _M_ndx.reset(); 1069 _M_ndy.reset(); 1070 } 1071 1072 /** 1073 * @brief Return the parameters of the distribution. 1074 */ 1075 result_type 1076 nu() const 1077 { return _M_param.nu(); } 1078 1079 result_type 1080 sigma() const 1081 { return _M_param.sigma(); } 1082 1083 /** 1084 * @brief Returns the parameter set of the distribution. 1085 */ 1086 param_type 1087 param() const 1088 { return _M_param; } 1089 1090 /** 1091 * @brief Sets the parameter set of the distribution. 1092 * @param __param The new parameter set of the distribution. 1093 */ 1094 void 1095 param(const param_type& __param) 1096 { _M_param = __param; } 1097 1098 /** 1099 * @brief Returns the greatest lower bound value of the distribution. 1100 */ 1101 result_type 1102 min() const 1103 { return result_type(0); } 1104 1105 /** 1106 * @brief Returns the least upper bound value of the distribution. 1107 */ 1108 result_type 1109 max() const 1110 { return std::numeric_limits<result_type>::max(); } 1111 1112 /** 1113 * @brief Generating functions. 1114 */ 1115 template<typename _UniformRandomNumberGenerator> 1116 result_type 1117 operator()(_UniformRandomNumberGenerator& __urng) 1118 { 1119 result_type __x = this->_M_ndx(__urng); 1120 result_type __y = this->_M_ndy(__urng); 1121 #if _GLIBCXX_USE_C99_MATH_FUNCS 1122 return std::hypot(__x, __y); 1123 #else 1124 return std::sqrt(__x * __x + __y * __y); 1125 #endif 1126 } 1127 1128 template<typename _UniformRandomNumberGenerator> 1129 result_type 1130 operator()(_UniformRandomNumberGenerator& __urng, 1131 const param_type& __p) 1132 { 1133 typename std::normal_distribution<result_type>::param_type 1134 __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); 1135 result_type __x = this->_M_ndx(__px, __urng); 1136 result_type __y = this->_M_ndy(__py, __urng); 1137 #if _GLIBCXX_USE_C99_MATH_FUNCS 1138 return std::hypot(__x, __y); 1139 #else 1140 return std::sqrt(__x * __x + __y * __y); 1141 #endif 1142 } 1143 1144 template<typename _ForwardIterator, 1145 typename _UniformRandomNumberGenerator> 1146 void 1147 __generate(_ForwardIterator __f, _ForwardIterator __t, 1148 _UniformRandomNumberGenerator& __urng) 1149 { this->__generate(__f, __t, __urng, _M_param); } 1150 1151 template<typename _ForwardIterator, 1152 typename _UniformRandomNumberGenerator> 1153 void 1154 __generate(_ForwardIterator __f, _ForwardIterator __t, 1155 _UniformRandomNumberGenerator& __urng, 1156 const param_type& __p) 1157 { this->__generate_impl(__f, __t, __urng, __p); } 1158 1159 template<typename _UniformRandomNumberGenerator> 1160 void 1161 __generate(result_type* __f, result_type* __t, 1162 _UniformRandomNumberGenerator& __urng, 1163 const param_type& __p) 1164 { this->__generate_impl(__f, __t, __urng, __p); } 1165 1166 /** 1167 * @brief Return true if two Rice distributions have 1168 * the same parameters and the sequences that would 1169 * be generated are equal. 1170 */ 1171 friend bool 1172 operator==(const rice_distribution& __d1, 1173 const rice_distribution& __d2) 1174 { return (__d1._M_param == __d2._M_param 1175 && __d1._M_ndx == __d2._M_ndx 1176 && __d1._M_ndy == __d2._M_ndy); } 1177 1178 /** 1179 * @brief Inserts a %rice_distribution random number distribution 1180 * @p __x into the output stream @p __os. 1181 * 1182 * @param __os An output stream. 1183 * @param __x A %rice_distribution random number distribution. 1184 * 1185 * @returns The output stream with the state of @p __x inserted or in 1186 * an error state. 1187 */ 1188 template<typename _RealType1, typename _CharT, typename _Traits> 1189 friend std::basic_ostream<_CharT, _Traits>& 1190 operator<<(std::basic_ostream<_CharT, _Traits>&, 1191 const rice_distribution<_RealType1>&); 1192 1193 /** 1194 * @brief Extracts a %rice_distribution random number distribution 1195 * @p __x from the input stream @p __is. 1196 * 1197 * @param __is An input stream. 1198 * @param __x A %rice_distribution random number 1199 * generator engine. 1200 * 1201 * @returns The input stream with @p __x extracted or in an error state. 1202 */ 1203 template<typename _RealType1, typename _CharT, typename _Traits> 1204 friend std::basic_istream<_CharT, _Traits>& 1205 operator>>(std::basic_istream<_CharT, _Traits>&, 1206 rice_distribution<_RealType1>&); 1207 1208 private: 1209 template<typename _ForwardIterator, 1210 typename _UniformRandomNumberGenerator> 1211 void 1212 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1213 _UniformRandomNumberGenerator& __urng, 1214 const param_type& __p); 1215 1216 param_type _M_param; 1217 1218 std::normal_distribution<result_type> _M_ndx; 1219 std::normal_distribution<result_type> _M_ndy; 1220 }; 1221 1222 #if __cpp_impl_three_way_comparison < 201907L 1223 /** 1224 * @brief Return true if two Rice distributions are not equal. 1225 */ 1226 template<typename _RealType1> 1227 inline bool 1228 operator!=(const rice_distribution<_RealType1>& __d1, 1229 const rice_distribution<_RealType1>& __d2) 1230 { return !(__d1 == __d2); } 1231 #endif 1232 1233 /** 1234 * @brief A Nakagami continuous distribution for random numbers. 1235 * 1236 * The formula for the Nakagami probability density function is 1237 * @f[ 1238 * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} 1239 * x^{2\mu-1}e^{-\mu x / \omega} 1240 * @f] 1241 * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ 1242 * and @f$\omega > 0@f$. 1243 */ 1244 template<typename _RealType = double> 1245 class 1246 nakagami_distribution 1247 { 1248 static_assert(std::is_floating_point<_RealType>::value, 1249 "template argument not a floating point type"); 1250 1251 public: 1252 /** The type of the range of the distribution. */ 1253 typedef _RealType result_type; 1254 1255 /** Parameter type. */ 1256 struct param_type 1257 { 1258 typedef nakagami_distribution<result_type> distribution_type; 1259 1260 param_type() : param_type(1) { } 1261 1262 param_type(result_type __mu_val, 1263 result_type __omega_val = result_type(1)) 1264 : _M_mu(__mu_val), _M_omega(__omega_val) 1265 { 1266 __glibcxx_assert(_M_mu >= result_type(0.5L)); 1267 __glibcxx_assert(_M_omega > result_type(0)); 1268 } 1269 1270 result_type 1271 mu() const 1272 { return _M_mu; } 1273 1274 result_type 1275 omega() const 1276 { return _M_omega; } 1277 1278 friend bool 1279 operator==(const param_type& __p1, const param_type& __p2) 1280 { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; } 1281 1282 #if __cpp_impl_three_way_comparison < 201907L 1283 friend bool 1284 operator!=(const param_type& __p1, const param_type& __p2) 1285 { return !(__p1 == __p2); } 1286 #endif 1287 1288 private: 1289 void _M_initialize(); 1290 1291 result_type _M_mu; 1292 result_type _M_omega; 1293 }; 1294 1295 /** 1296 * @brief Constructors. 1297 * @{ 1298 */ 1299 1300 nakagami_distribution() : nakagami_distribution(1) { } 1301 1302 explicit 1303 nakagami_distribution(result_type __mu_val, 1304 result_type __omega_val = result_type(1)) 1305 : _M_param(__mu_val, __omega_val), 1306 _M_gd(__mu_val, __omega_val / __mu_val) 1307 { } 1308 1309 explicit 1310 nakagami_distribution(const param_type& __p) 1311 : _M_param(__p), 1312 _M_gd(__p.mu(), __p.omega() / __p.mu()) 1313 { } 1314 1315 /// @} 1316 1317 /** 1318 * @brief Resets the distribution state. 1319 */ 1320 void 1321 reset() 1322 { _M_gd.reset(); } 1323 1324 /** 1325 * @brief Return the parameters of the distribution. 1326 */ 1327 result_type 1328 mu() const 1329 { return _M_param.mu(); } 1330 1331 result_type 1332 omega() const 1333 { return _M_param.omega(); } 1334 1335 /** 1336 * @brief Returns the parameter set of the distribution. 1337 */ 1338 param_type 1339 param() const 1340 { return _M_param; } 1341 1342 /** 1343 * @brief Sets the parameter set of the distribution. 1344 * @param __param The new parameter set of the distribution. 1345 */ 1346 void 1347 param(const param_type& __param) 1348 { _M_param = __param; } 1349 1350 /** 1351 * @brief Returns the greatest lower bound value of the distribution. 1352 */ 1353 result_type 1354 min() const 1355 { return result_type(0); } 1356 1357 /** 1358 * @brief Returns the least upper bound value of the distribution. 1359 */ 1360 result_type 1361 max() const 1362 { return std::numeric_limits<result_type>::max(); } 1363 1364 /** 1365 * @brief Generating functions. 1366 */ 1367 template<typename _UniformRandomNumberGenerator> 1368 result_type 1369 operator()(_UniformRandomNumberGenerator& __urng) 1370 { return std::sqrt(this->_M_gd(__urng)); } 1371 1372 template<typename _UniformRandomNumberGenerator> 1373 result_type 1374 operator()(_UniformRandomNumberGenerator& __urng, 1375 const param_type& __p) 1376 { 1377 typename std::gamma_distribution<result_type>::param_type 1378 __pg(__p.mu(), __p.omega() / __p.mu()); 1379 return std::sqrt(this->_M_gd(__pg, __urng)); 1380 } 1381 1382 template<typename _ForwardIterator, 1383 typename _UniformRandomNumberGenerator> 1384 void 1385 __generate(_ForwardIterator __f, _ForwardIterator __t, 1386 _UniformRandomNumberGenerator& __urng) 1387 { this->__generate(__f, __t, __urng, _M_param); } 1388 1389 template<typename _ForwardIterator, 1390 typename _UniformRandomNumberGenerator> 1391 void 1392 __generate(_ForwardIterator __f, _ForwardIterator __t, 1393 _UniformRandomNumberGenerator& __urng, 1394 const param_type& __p) 1395 { this->__generate_impl(__f, __t, __urng, __p); } 1396 1397 template<typename _UniformRandomNumberGenerator> 1398 void 1399 __generate(result_type* __f, result_type* __t, 1400 _UniformRandomNumberGenerator& __urng, 1401 const param_type& __p) 1402 { this->__generate_impl(__f, __t, __urng, __p); } 1403 1404 /** 1405 * @brief Return true if two Nakagami distributions have 1406 * the same parameters and the sequences that would 1407 * be generated are equal. 1408 */ 1409 friend bool 1410 operator==(const nakagami_distribution& __d1, 1411 const nakagami_distribution& __d2) 1412 { return (__d1._M_param == __d2._M_param 1413 && __d1._M_gd == __d2._M_gd); } 1414 1415 /** 1416 * @brief Inserts a %nakagami_distribution random number distribution 1417 * @p __x into the output stream @p __os. 1418 * 1419 * @param __os An output stream. 1420 * @param __x A %nakagami_distribution random number distribution. 1421 * 1422 * @returns The output stream with the state of @p __x inserted or in 1423 * an error state. 1424 */ 1425 template<typename _RealType1, typename _CharT, typename _Traits> 1426 friend std::basic_ostream<_CharT, _Traits>& 1427 operator<<(std::basic_ostream<_CharT, _Traits>&, 1428 const nakagami_distribution<_RealType1>&); 1429 1430 /** 1431 * @brief Extracts a %nakagami_distribution random number distribution 1432 * @p __x from the input stream @p __is. 1433 * 1434 * @param __is An input stream. 1435 * @param __x A %nakagami_distribution random number 1436 * generator engine. 1437 * 1438 * @returns The input stream with @p __x extracted or in an error state. 1439 */ 1440 template<typename _RealType1, typename _CharT, typename _Traits> 1441 friend std::basic_istream<_CharT, _Traits>& 1442 operator>>(std::basic_istream<_CharT, _Traits>&, 1443 nakagami_distribution<_RealType1>&); 1444 1445 private: 1446 template<typename _ForwardIterator, 1447 typename _UniformRandomNumberGenerator> 1448 void 1449 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1450 _UniformRandomNumberGenerator& __urng, 1451 const param_type& __p); 1452 1453 param_type _M_param; 1454 1455 std::gamma_distribution<result_type> _M_gd; 1456 }; 1457 1458 #if __cpp_impl_three_way_comparison < 201907L 1459 /** 1460 * @brief Return true if two Nakagami distributions are not equal. 1461 */ 1462 template<typename _RealType> 1463 inline bool 1464 operator!=(const nakagami_distribution<_RealType>& __d1, 1465 const nakagami_distribution<_RealType>& __d2) 1466 { return !(__d1 == __d2); } 1467 #endif 1468 1469 /** 1470 * @brief A Pareto continuous distribution for random numbers. 1471 * 1472 * The formula for the Pareto cumulative probability function is 1473 * @f[ 1474 * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha 1475 * @f] 1476 * The formula for the Pareto probability density function is 1477 * @f[ 1478 * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} 1479 * \left(\frac{\mu}{x}\right)^{\alpha + 1} 1480 * @f] 1481 * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. 1482 * 1483 * <table border=1 cellpadding=10 cellspacing=0> 1484 * <caption align=top>Distribution Statistics</caption> 1485 * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$ 1486 * for @f$\alpha > 1@f$</td></tr> 1487 * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ 1488 * for @f$\alpha > 2@f$</td></tr> 1489 * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr> 1490 * </table> 1491 */ 1492 template<typename _RealType = double> 1493 class 1494 pareto_distribution 1495 { 1496 static_assert(std::is_floating_point<_RealType>::value, 1497 "template argument not a floating point type"); 1498 1499 public: 1500 /** The type of the range of the distribution. */ 1501 typedef _RealType result_type; 1502 1503 /** Parameter type. */ 1504 struct param_type 1505 { 1506 typedef pareto_distribution<result_type> distribution_type; 1507 1508 param_type() : param_type(1) { } 1509 1510 param_type(result_type __alpha_val, 1511 result_type __mu_val = result_type(1)) 1512 : _M_alpha(__alpha_val), _M_mu(__mu_val) 1513 { 1514 __glibcxx_assert(_M_alpha > result_type(0)); 1515 __glibcxx_assert(_M_mu > result_type(0)); 1516 } 1517 1518 result_type 1519 alpha() const 1520 { return _M_alpha; } 1521 1522 result_type 1523 mu() const 1524 { return _M_mu; } 1525 1526 friend bool 1527 operator==(const param_type& __p1, const param_type& __p2) 1528 { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } 1529 1530 #if __cpp_impl_three_way_comparison < 201907L 1531 friend bool 1532 operator!=(const param_type& __p1, const param_type& __p2) 1533 { return !(__p1 == __p2); } 1534 #endif 1535 1536 private: 1537 void _M_initialize(); 1538 1539 result_type _M_alpha; 1540 result_type _M_mu; 1541 }; 1542 1543 /** 1544 * @brief Constructors. 1545 * @{ 1546 */ 1547 1548 pareto_distribution() : pareto_distribution(1) { } 1549 1550 explicit 1551 pareto_distribution(result_type __alpha_val, 1552 result_type __mu_val = result_type(1)) 1553 : _M_param(__alpha_val, __mu_val), 1554 _M_ud() 1555 { } 1556 1557 explicit 1558 pareto_distribution(const param_type& __p) 1559 : _M_param(__p), 1560 _M_ud() 1561 { } 1562 1563 /// @} 1564 1565 /** 1566 * @brief Resets the distribution state. 1567 */ 1568 void 1569 reset() 1570 { 1571 _M_ud.reset(); 1572 } 1573 1574 /** 1575 * @brief Return the parameters of the distribution. 1576 */ 1577 result_type 1578 alpha() const 1579 { return _M_param.alpha(); } 1580 1581 result_type 1582 mu() const 1583 { return _M_param.mu(); } 1584 1585 /** 1586 * @brief Returns the parameter set of the distribution. 1587 */ 1588 param_type 1589 param() const 1590 { return _M_param; } 1591 1592 /** 1593 * @brief Sets the parameter set of the distribution. 1594 * @param __param The new parameter set of the distribution. 1595 */ 1596 void 1597 param(const param_type& __param) 1598 { _M_param = __param; } 1599 1600 /** 1601 * @brief Returns the greatest lower bound value of the distribution. 1602 */ 1603 result_type 1604 min() const 1605 { return this->mu(); } 1606 1607 /** 1608 * @brief Returns the least upper bound value of the distribution. 1609 */ 1610 result_type 1611 max() const 1612 { return std::numeric_limits<result_type>::max(); } 1613 1614 /** 1615 * @brief Generating functions. 1616 */ 1617 template<typename _UniformRandomNumberGenerator> 1618 result_type 1619 operator()(_UniformRandomNumberGenerator& __urng) 1620 { 1621 return this->mu() * std::pow(this->_M_ud(__urng), 1622 -result_type(1) / this->alpha()); 1623 } 1624 1625 template<typename _UniformRandomNumberGenerator> 1626 result_type 1627 operator()(_UniformRandomNumberGenerator& __urng, 1628 const param_type& __p) 1629 { 1630 return __p.mu() * std::pow(this->_M_ud(__urng), 1631 -result_type(1) / __p.alpha()); 1632 } 1633 1634 template<typename _ForwardIterator, 1635 typename _UniformRandomNumberGenerator> 1636 void 1637 __generate(_ForwardIterator __f, _ForwardIterator __t, 1638 _UniformRandomNumberGenerator& __urng) 1639 { this->__generate(__f, __t, __urng, _M_param); } 1640 1641 template<typename _ForwardIterator, 1642 typename _UniformRandomNumberGenerator> 1643 void 1644 __generate(_ForwardIterator __f, _ForwardIterator __t, 1645 _UniformRandomNumberGenerator& __urng, 1646 const param_type& __p) 1647 { this->__generate_impl(__f, __t, __urng, __p); } 1648 1649 template<typename _UniformRandomNumberGenerator> 1650 void 1651 __generate(result_type* __f, result_type* __t, 1652 _UniformRandomNumberGenerator& __urng, 1653 const param_type& __p) 1654 { this->__generate_impl(__f, __t, __urng, __p); } 1655 1656 /** 1657 * @brief Return true if two Pareto distributions have 1658 * the same parameters and the sequences that would 1659 * be generated are equal. 1660 */ 1661 friend bool 1662 operator==(const pareto_distribution& __d1, 1663 const pareto_distribution& __d2) 1664 { return (__d1._M_param == __d2._M_param 1665 && __d1._M_ud == __d2._M_ud); } 1666 1667 /** 1668 * @brief Inserts a %pareto_distribution random number distribution 1669 * @p __x into the output stream @p __os. 1670 * 1671 * @param __os An output stream. 1672 * @param __x A %pareto_distribution random number distribution. 1673 * 1674 * @returns The output stream with the state of @p __x inserted or in 1675 * an error state. 1676 */ 1677 template<typename _RealType1, typename _CharT, typename _Traits> 1678 friend std::basic_ostream<_CharT, _Traits>& 1679 operator<<(std::basic_ostream<_CharT, _Traits>&, 1680 const pareto_distribution<_RealType1>&); 1681 1682 /** 1683 * @brief Extracts a %pareto_distribution random number distribution 1684 * @p __x from the input stream @p __is. 1685 * 1686 * @param __is An input stream. 1687 * @param __x A %pareto_distribution random number 1688 * generator engine. 1689 * 1690 * @returns The input stream with @p __x extracted or in an error state. 1691 */ 1692 template<typename _RealType1, typename _CharT, typename _Traits> 1693 friend std::basic_istream<_CharT, _Traits>& 1694 operator>>(std::basic_istream<_CharT, _Traits>&, 1695 pareto_distribution<_RealType1>&); 1696 1697 private: 1698 template<typename _ForwardIterator, 1699 typename _UniformRandomNumberGenerator> 1700 void 1701 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1702 _UniformRandomNumberGenerator& __urng, 1703 const param_type& __p); 1704 1705 param_type _M_param; 1706 1707 std::uniform_real_distribution<result_type> _M_ud; 1708 }; 1709 1710 #if __cpp_impl_three_way_comparison < 201907L 1711 /** 1712 * @brief Return true if two Pareto distributions are not equal. 1713 */ 1714 template<typename _RealType> 1715 inline bool 1716 operator!=(const pareto_distribution<_RealType>& __d1, 1717 const pareto_distribution<_RealType>& __d2) 1718 { return !(__d1 == __d2); } 1719 #endif 1720 1721 /** 1722 * @brief A K continuous distribution for random numbers. 1723 * 1724 * The formula for the K probability density function is 1725 * @f[ 1726 * p(x|\lambda, \mu, \nu) = \frac{2}{x} 1727 * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} 1728 * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} 1729 * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) 1730 * @f] 1731 * where @f$I_0(z)@f$ is the modified Bessel function of the second kind 1732 * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ 1733 * and @f$\nu > 0@f$. 1734 * 1735 * <table border=1 cellpadding=10 cellspacing=0> 1736 * <caption align=top>Distribution Statistics</caption> 1737 * <tr><td>Mean</td><td>@f$\mu@f$</td></tr> 1738 * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr> 1739 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> 1740 * </table> 1741 */ 1742 template<typename _RealType = double> 1743 class 1744 k_distribution 1745 { 1746 static_assert(std::is_floating_point<_RealType>::value, 1747 "template argument not a floating point type"); 1748 1749 public: 1750 /** The type of the range of the distribution. */ 1751 typedef _RealType result_type; 1752 1753 /** Parameter type. */ 1754 struct param_type 1755 { 1756 typedef k_distribution<result_type> distribution_type; 1757 1758 param_type() : param_type(1) { } 1759 1760 param_type(result_type __lambda_val, 1761 result_type __mu_val = result_type(1), 1762 result_type __nu_val = result_type(1)) 1763 : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) 1764 { 1765 __glibcxx_assert(_M_lambda > result_type(0)); 1766 __glibcxx_assert(_M_mu > result_type(0)); 1767 __glibcxx_assert(_M_nu > result_type(0)); 1768 } 1769 1770 result_type 1771 lambda() const 1772 { return _M_lambda; } 1773 1774 result_type 1775 mu() const 1776 { return _M_mu; } 1777 1778 result_type 1779 nu() const 1780 { return _M_nu; } 1781 1782 friend bool 1783 operator==(const param_type& __p1, const param_type& __p2) 1784 { 1785 return __p1._M_lambda == __p2._M_lambda 1786 && __p1._M_mu == __p2._M_mu 1787 && __p1._M_nu == __p2._M_nu; 1788 } 1789 1790 #if __cpp_impl_three_way_comparison < 201907L 1791 friend bool 1792 operator!=(const param_type& __p1, const param_type& __p2) 1793 { return !(__p1 == __p2); } 1794 #endif 1795 1796 private: 1797 void _M_initialize(); 1798 1799 result_type _M_lambda; 1800 result_type _M_mu; 1801 result_type _M_nu; 1802 }; 1803 1804 /** 1805 * @brief Constructors. 1806 * @{ 1807 */ 1808 1809 k_distribution() : k_distribution(1) { } 1810 1811 explicit 1812 k_distribution(result_type __lambda_val, 1813 result_type __mu_val = result_type(1), 1814 result_type __nu_val = result_type(1)) 1815 : _M_param(__lambda_val, __mu_val, __nu_val), 1816 _M_gd1(__lambda_val, result_type(1) / __lambda_val), 1817 _M_gd2(__nu_val, __mu_val / __nu_val) 1818 { } 1819 1820 explicit 1821 k_distribution(const param_type& __p) 1822 : _M_param(__p), 1823 _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), 1824 _M_gd2(__p.nu(), __p.mu() / __p.nu()) 1825 { } 1826 1827 /// @} 1828 1829 /** 1830 * @brief Resets the distribution state. 1831 */ 1832 void 1833 reset() 1834 { 1835 _M_gd1.reset(); 1836 _M_gd2.reset(); 1837 } 1838 1839 /** 1840 * @brief Return the parameters of the distribution. 1841 */ 1842 result_type 1843 lambda() const 1844 { return _M_param.lambda(); } 1845 1846 result_type 1847 mu() const 1848 { return _M_param.mu(); } 1849 1850 result_type 1851 nu() const 1852 { return _M_param.nu(); } 1853 1854 /** 1855 * @brief Returns the parameter set of the distribution. 1856 */ 1857 param_type 1858 param() const 1859 { return _M_param; } 1860 1861 /** 1862 * @brief Sets the parameter set of the distribution. 1863 * @param __param The new parameter set of the distribution. 1864 */ 1865 void 1866 param(const param_type& __param) 1867 { _M_param = __param; } 1868 1869 /** 1870 * @brief Returns the greatest lower bound value of the distribution. 1871 */ 1872 result_type 1873 min() const 1874 { return result_type(0); } 1875 1876 /** 1877 * @brief Returns the least upper bound value of the distribution. 1878 */ 1879 result_type 1880 max() const 1881 { return std::numeric_limits<result_type>::max(); } 1882 1883 /** 1884 * @brief Generating functions. 1885 */ 1886 template<typename _UniformRandomNumberGenerator> 1887 result_type 1888 operator()(_UniformRandomNumberGenerator&); 1889 1890 template<typename _UniformRandomNumberGenerator> 1891 result_type 1892 operator()(_UniformRandomNumberGenerator&, const param_type&); 1893 1894 template<typename _ForwardIterator, 1895 typename _UniformRandomNumberGenerator> 1896 void 1897 __generate(_ForwardIterator __f, _ForwardIterator __t, 1898 _UniformRandomNumberGenerator& __urng) 1899 { this->__generate(__f, __t, __urng, _M_param); } 1900 1901 template<typename _ForwardIterator, 1902 typename _UniformRandomNumberGenerator> 1903 void 1904 __generate(_ForwardIterator __f, _ForwardIterator __t, 1905 _UniformRandomNumberGenerator& __urng, 1906 const param_type& __p) 1907 { this->__generate_impl(__f, __t, __urng, __p); } 1908 1909 template<typename _UniformRandomNumberGenerator> 1910 void 1911 __generate(result_type* __f, result_type* __t, 1912 _UniformRandomNumberGenerator& __urng, 1913 const param_type& __p) 1914 { this->__generate_impl(__f, __t, __urng, __p); } 1915 1916 /** 1917 * @brief Return true if two K distributions have 1918 * the same parameters and the sequences that would 1919 * be generated are equal. 1920 */ 1921 friend bool 1922 operator==(const k_distribution& __d1, 1923 const k_distribution& __d2) 1924 { return (__d1._M_param == __d2._M_param 1925 && __d1._M_gd1 == __d2._M_gd1 1926 && __d1._M_gd2 == __d2._M_gd2); } 1927 1928 /** 1929 * @brief Inserts a %k_distribution random number distribution 1930 * @p __x into the output stream @p __os. 1931 * 1932 * @param __os An output stream. 1933 * @param __x A %k_distribution random number distribution. 1934 * 1935 * @returns The output stream with the state of @p __x inserted or in 1936 * an error state. 1937 */ 1938 template<typename _RealType1, typename _CharT, typename _Traits> 1939 friend std::basic_ostream<_CharT, _Traits>& 1940 operator<<(std::basic_ostream<_CharT, _Traits>&, 1941 const k_distribution<_RealType1>&); 1942 1943 /** 1944 * @brief Extracts a %k_distribution random number distribution 1945 * @p __x from the input stream @p __is. 1946 * 1947 * @param __is An input stream. 1948 * @param __x A %k_distribution random number 1949 * generator engine. 1950 * 1951 * @returns The input stream with @p __x extracted or in an error state. 1952 */ 1953 template<typename _RealType1, typename _CharT, typename _Traits> 1954 friend std::basic_istream<_CharT, _Traits>& 1955 operator>>(std::basic_istream<_CharT, _Traits>&, 1956 k_distribution<_RealType1>&); 1957 1958 private: 1959 template<typename _ForwardIterator, 1960 typename _UniformRandomNumberGenerator> 1961 void 1962 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 1963 _UniformRandomNumberGenerator& __urng, 1964 const param_type& __p); 1965 1966 param_type _M_param; 1967 1968 std::gamma_distribution<result_type> _M_gd1; 1969 std::gamma_distribution<result_type> _M_gd2; 1970 }; 1971 1972 #if __cpp_impl_three_way_comparison < 201907L 1973 /** 1974 * @brief Return true if two K distributions are not equal. 1975 */ 1976 template<typename _RealType> 1977 inline bool 1978 operator!=(const k_distribution<_RealType>& __d1, 1979 const k_distribution<_RealType>& __d2) 1980 { return !(__d1 == __d2); } 1981 #endif 1982 1983 /** 1984 * @brief An arcsine continuous distribution for random numbers. 1985 * 1986 * The formula for the arcsine probability density function is 1987 * @f[ 1988 * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}} 1989 * @f] 1990 * where @f$x >= a@f$ and @f$x <= b@f$. 1991 * 1992 * <table border=1 cellpadding=10 cellspacing=0> 1993 * <caption align=top>Distribution Statistics</caption> 1994 * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr> 1995 * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr> 1996 * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr> 1997 * </table> 1998 */ 1999 template<typename _RealType = double> 2000 class 2001 arcsine_distribution 2002 { 2003 static_assert(std::is_floating_point<_RealType>::value, 2004 "template argument not a floating point type"); 2005 2006 public: 2007 /** The type of the range of the distribution. */ 2008 typedef _RealType result_type; 2009 2010 /** Parameter type. */ 2011 struct param_type 2012 { 2013 typedef arcsine_distribution<result_type> distribution_type; 2014 2015 param_type() : param_type(0) { } 2016 2017 param_type(result_type __a, result_type __b = result_type(1)) 2018 : _M_a(__a), _M_b(__b) 2019 { 2020 __glibcxx_assert(_M_a <= _M_b); 2021 } 2022 2023 result_type 2024 a() const 2025 { return _M_a; } 2026 2027 result_type 2028 b() const 2029 { return _M_b; } 2030 2031 friend bool 2032 operator==(const param_type& __p1, const param_type& __p2) 2033 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } 2034 2035 #if __cpp_impl_three_way_comparison < 201907L 2036 friend bool 2037 operator!=(const param_type& __p1, const param_type& __p2) 2038 { return !(__p1 == __p2); } 2039 #endif 2040 2041 private: 2042 void _M_initialize(); 2043 2044 result_type _M_a; 2045 result_type _M_b; 2046 }; 2047 2048 /** 2049 * @brief Constructors. 2050 * :{ 2051 */ 2052 2053 arcsine_distribution() : arcsine_distribution(0) { } 2054 2055 explicit 2056 arcsine_distribution(result_type __a, result_type __b = result_type(1)) 2057 : _M_param(__a, __b), 2058 _M_ud(-1.5707963267948966192313216916397514L, 2059 +1.5707963267948966192313216916397514L) 2060 { } 2061 2062 explicit 2063 arcsine_distribution(const param_type& __p) 2064 : _M_param(__p), 2065 _M_ud(-1.5707963267948966192313216916397514L, 2066 +1.5707963267948966192313216916397514L) 2067 { } 2068 2069 /// @} 2070 2071 /** 2072 * @brief Resets the distribution state. 2073 */ 2074 void 2075 reset() 2076 { _M_ud.reset(); } 2077 2078 /** 2079 * @brief Return the parameters of the distribution. 2080 */ 2081 result_type 2082 a() const 2083 { return _M_param.a(); } 2084 2085 result_type 2086 b() const 2087 { return _M_param.b(); } 2088 2089 /** 2090 * @brief Returns the parameter set of the distribution. 2091 */ 2092 param_type 2093 param() const 2094 { return _M_param; } 2095 2096 /** 2097 * @brief Sets the parameter set of the distribution. 2098 * @param __param The new parameter set of the distribution. 2099 */ 2100 void 2101 param(const param_type& __param) 2102 { _M_param = __param; } 2103 2104 /** 2105 * @brief Returns the greatest lower bound value of the distribution. 2106 */ 2107 result_type 2108 min() const 2109 { return this->a(); } 2110 2111 /** 2112 * @brief Returns the least upper bound value of the distribution. 2113 */ 2114 result_type 2115 max() const 2116 { return this->b(); } 2117 2118 /** 2119 * @brief Generating functions. 2120 */ 2121 template<typename _UniformRandomNumberGenerator> 2122 result_type 2123 operator()(_UniformRandomNumberGenerator& __urng) 2124 { 2125 result_type __x = std::sin(this->_M_ud(__urng)); 2126 return (__x * (this->b() - this->a()) 2127 + this->a() + this->b()) / result_type(2); 2128 } 2129 2130 template<typename _UniformRandomNumberGenerator> 2131 result_type 2132 operator()(_UniformRandomNumberGenerator& __urng, 2133 const param_type& __p) 2134 { 2135 result_type __x = std::sin(this->_M_ud(__urng)); 2136 return (__x * (__p.b() - __p.a()) 2137 + __p.a() + __p.b()) / result_type(2); 2138 } 2139 2140 template<typename _ForwardIterator, 2141 typename _UniformRandomNumberGenerator> 2142 void 2143 __generate(_ForwardIterator __f, _ForwardIterator __t, 2144 _UniformRandomNumberGenerator& __urng) 2145 { this->__generate(__f, __t, __urng, _M_param); } 2146 2147 template<typename _ForwardIterator, 2148 typename _UniformRandomNumberGenerator> 2149 void 2150 __generate(_ForwardIterator __f, _ForwardIterator __t, 2151 _UniformRandomNumberGenerator& __urng, 2152 const param_type& __p) 2153 { this->__generate_impl(__f, __t, __urng, __p); } 2154 2155 template<typename _UniformRandomNumberGenerator> 2156 void 2157 __generate(result_type* __f, result_type* __t, 2158 _UniformRandomNumberGenerator& __urng, 2159 const param_type& __p) 2160 { this->__generate_impl(__f, __t, __urng, __p); } 2161 2162 /** 2163 * @brief Return true if two arcsine distributions have 2164 * the same parameters and the sequences that would 2165 * be generated are equal. 2166 */ 2167 friend bool 2168 operator==(const arcsine_distribution& __d1, 2169 const arcsine_distribution& __d2) 2170 { return (__d1._M_param == __d2._M_param 2171 && __d1._M_ud == __d2._M_ud); } 2172 2173 /** 2174 * @brief Inserts a %arcsine_distribution random number distribution 2175 * @p __x into the output stream @p __os. 2176 * 2177 * @param __os An output stream. 2178 * @param __x A %arcsine_distribution random number distribution. 2179 * 2180 * @returns The output stream with the state of @p __x inserted or in 2181 * an error state. 2182 */ 2183 template<typename _RealType1, typename _CharT, typename _Traits> 2184 friend std::basic_ostream<_CharT, _Traits>& 2185 operator<<(std::basic_ostream<_CharT, _Traits>&, 2186 const arcsine_distribution<_RealType1>&); 2187 2188 /** 2189 * @brief Extracts a %arcsine_distribution random number distribution 2190 * @p __x from the input stream @p __is. 2191 * 2192 * @param __is An input stream. 2193 * @param __x A %arcsine_distribution random number 2194 * generator engine. 2195 * 2196 * @returns The input stream with @p __x extracted or in an error state. 2197 */ 2198 template<typename _RealType1, typename _CharT, typename _Traits> 2199 friend std::basic_istream<_CharT, _Traits>& 2200 operator>>(std::basic_istream<_CharT, _Traits>&, 2201 arcsine_distribution<_RealType1>&); 2202 2203 private: 2204 template<typename _ForwardIterator, 2205 typename _UniformRandomNumberGenerator> 2206 void 2207 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2208 _UniformRandomNumberGenerator& __urng, 2209 const param_type& __p); 2210 2211 param_type _M_param; 2212 2213 std::uniform_real_distribution<result_type> _M_ud; 2214 }; 2215 2216 #if __cpp_impl_three_way_comparison < 201907L 2217 /** 2218 * @brief Return true if two arcsine distributions are not equal. 2219 */ 2220 template<typename _RealType> 2221 inline bool 2222 operator!=(const arcsine_distribution<_RealType>& __d1, 2223 const arcsine_distribution<_RealType>& __d2) 2224 { return !(__d1 == __d2); } 2225 #endif 2226 2227 /** 2228 * @brief A Hoyt continuous distribution for random numbers. 2229 * 2230 * The formula for the Hoyt probability density function is 2231 * @f[ 2232 * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega} 2233 * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right) 2234 * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right) 2235 * @f] 2236 * where @f$I_0(z)@f$ is the modified Bessel function of the first kind 2237 * of order 0 and @f$0 < q < 1@f$. 2238 * 2239 * <table border=1 cellpadding=10 cellspacing=0> 2240 * <caption align=top>Distribution Statistics</caption> 2241 * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}} 2242 * E(1 - q^2) @f$</td></tr> 2243 * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)} 2244 * {\pi (1 + q^2)}\right) @f$</td></tr> 2245 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> 2246 * </table> 2247 * where @f$E(x)@f$ is the elliptic function of the second kind. 2248 */ 2249 template<typename _RealType = double> 2250 class 2251 hoyt_distribution 2252 { 2253 static_assert(std::is_floating_point<_RealType>::value, 2254 "template argument not a floating point type"); 2255 2256 public: 2257 /** The type of the range of the distribution. */ 2258 typedef _RealType result_type; 2259 2260 /** Parameter type. */ 2261 struct param_type 2262 { 2263 typedef hoyt_distribution<result_type> distribution_type; 2264 2265 param_type() : param_type(0.5) { } 2266 2267 param_type(result_type __q, result_type __omega = result_type(1)) 2268 : _M_q(__q), _M_omega(__omega) 2269 { 2270 __glibcxx_assert(_M_q > result_type(0)); 2271 __glibcxx_assert(_M_q < result_type(1)); 2272 } 2273 2274 result_type 2275 q() const 2276 { return _M_q; } 2277 2278 result_type 2279 omega() const 2280 { return _M_omega; } 2281 2282 friend bool 2283 operator==(const param_type& __p1, const param_type& __p2) 2284 { return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; } 2285 2286 #if __cpp_impl_three_way_comparison < 201907L 2287 friend bool 2288 operator!=(const param_type& __p1, const param_type& __p2) 2289 { return !(__p1 == __p2); } 2290 #endif 2291 2292 private: 2293 void _M_initialize(); 2294 2295 result_type _M_q; 2296 result_type _M_omega; 2297 }; 2298 2299 /** 2300 * @brief Constructors. 2301 * @{ 2302 */ 2303 2304 hoyt_distribution() : hoyt_distribution(0.5) { } 2305 2306 explicit 2307 hoyt_distribution(result_type __q, result_type __omega = result_type(1)) 2308 : _M_param(__q, __omega), 2309 _M_ad(result_type(0.5L) * (result_type(1) + __q * __q), 2310 result_type(0.5L) * (result_type(1) + __q * __q) 2311 / (__q * __q)), 2312 _M_ed(result_type(1)) 2313 { } 2314 2315 explicit 2316 hoyt_distribution(const param_type& __p) 2317 : _M_param(__p), 2318 _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()), 2319 result_type(0.5L) * (result_type(1) + __p.q() * __p.q()) 2320 / (__p.q() * __p.q())), 2321 _M_ed(result_type(1)) 2322 { } 2323 2324 /** 2325 * @brief Resets the distribution state. 2326 */ 2327 void 2328 reset() 2329 { 2330 _M_ad.reset(); 2331 _M_ed.reset(); 2332 } 2333 2334 /** 2335 * @brief Return the parameters of the distribution. 2336 */ 2337 result_type 2338 q() const 2339 { return _M_param.q(); } 2340 2341 result_type 2342 omega() const 2343 { return _M_param.omega(); } 2344 2345 /** 2346 * @brief Returns the parameter set of the distribution. 2347 */ 2348 param_type 2349 param() const 2350 { return _M_param; } 2351 2352 /** 2353 * @brief Sets the parameter set of the distribution. 2354 * @param __param The new parameter set of the distribution. 2355 */ 2356 void 2357 param(const param_type& __param) 2358 { _M_param = __param; } 2359 2360 /** 2361 * @brief Returns the greatest lower bound value of the distribution. 2362 */ 2363 result_type 2364 min() const 2365 { return result_type(0); } 2366 2367 /** 2368 * @brief Returns the least upper bound value of the distribution. 2369 */ 2370 result_type 2371 max() const 2372 { return std::numeric_limits<result_type>::max(); } 2373 2374 /** 2375 * @brief Generating functions. 2376 */ 2377 template<typename _UniformRandomNumberGenerator> 2378 result_type 2379 operator()(_UniformRandomNumberGenerator& __urng); 2380 2381 template<typename _UniformRandomNumberGenerator> 2382 result_type 2383 operator()(_UniformRandomNumberGenerator& __urng, 2384 const param_type& __p); 2385 2386 template<typename _ForwardIterator, 2387 typename _UniformRandomNumberGenerator> 2388 void 2389 __generate(_ForwardIterator __f, _ForwardIterator __t, 2390 _UniformRandomNumberGenerator& __urng) 2391 { this->__generate(__f, __t, __urng, _M_param); } 2392 2393 template<typename _ForwardIterator, 2394 typename _UniformRandomNumberGenerator> 2395 void 2396 __generate(_ForwardIterator __f, _ForwardIterator __t, 2397 _UniformRandomNumberGenerator& __urng, 2398 const param_type& __p) 2399 { this->__generate_impl(__f, __t, __urng, __p); } 2400 2401 template<typename _UniformRandomNumberGenerator> 2402 void 2403 __generate(result_type* __f, result_type* __t, 2404 _UniformRandomNumberGenerator& __urng, 2405 const param_type& __p) 2406 { this->__generate_impl(__f, __t, __urng, __p); } 2407 2408 /** 2409 * @brief Return true if two Hoyt distributions have 2410 * the same parameters and the sequences that would 2411 * be generated are equal. 2412 */ 2413 friend bool 2414 operator==(const hoyt_distribution& __d1, 2415 const hoyt_distribution& __d2) 2416 { return (__d1._M_param == __d2._M_param 2417 && __d1._M_ad == __d2._M_ad 2418 && __d1._M_ed == __d2._M_ed); } 2419 2420 /** 2421 * @brief Inserts a %hoyt_distribution random number distribution 2422 * @p __x into the output stream @p __os. 2423 * 2424 * @param __os An output stream. 2425 * @param __x A %hoyt_distribution random number distribution. 2426 * 2427 * @returns The output stream with the state of @p __x inserted or in 2428 * an error state. 2429 */ 2430 template<typename _RealType1, typename _CharT, typename _Traits> 2431 friend std::basic_ostream<_CharT, _Traits>& 2432 operator<<(std::basic_ostream<_CharT, _Traits>&, 2433 const hoyt_distribution<_RealType1>&); 2434 2435 /** 2436 * @brief Extracts a %hoyt_distribution random number distribution 2437 * @p __x from the input stream @p __is. 2438 * 2439 * @param __is An input stream. 2440 * @param __x A %hoyt_distribution random number 2441 * generator engine. 2442 * 2443 * @returns The input stream with @p __x extracted or in an error state. 2444 */ 2445 template<typename _RealType1, typename _CharT, typename _Traits> 2446 friend std::basic_istream<_CharT, _Traits>& 2447 operator>>(std::basic_istream<_CharT, _Traits>&, 2448 hoyt_distribution<_RealType1>&); 2449 2450 private: 2451 template<typename _ForwardIterator, 2452 typename _UniformRandomNumberGenerator> 2453 void 2454 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2455 _UniformRandomNumberGenerator& __urng, 2456 const param_type& __p); 2457 2458 param_type _M_param; 2459 2460 __gnu_cxx::arcsine_distribution<result_type> _M_ad; 2461 std::exponential_distribution<result_type> _M_ed; 2462 }; 2463 2464 #if __cpp_impl_three_way_comparison < 201907L 2465 /** 2466 * @brief Return true if two Hoyt distributions are not equal. 2467 */ 2468 template<typename _RealType> 2469 inline bool 2470 operator!=(const hoyt_distribution<_RealType>& __d1, 2471 const hoyt_distribution<_RealType>& __d2) 2472 { return !(__d1 == __d2); } 2473 #endif 2474 2475 /** 2476 * @brief A triangular distribution for random numbers. 2477 * 2478 * The formula for the triangular probability density function is 2479 * @f[ 2480 * / 0 for x < a 2481 * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b 2482 * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c 2483 * \ 0 for c < x 2484 * @f] 2485 * 2486 * <table border=1 cellpadding=10 cellspacing=0> 2487 * <caption align=top>Distribution Statistics</caption> 2488 * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr> 2489 * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc} 2490 * {18}@f$</td></tr> 2491 * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr> 2492 * </table> 2493 */ 2494 template<typename _RealType = double> 2495 class triangular_distribution 2496 { 2497 static_assert(std::is_floating_point<_RealType>::value, 2498 "template argument not a floating point type"); 2499 2500 public: 2501 /** The type of the range of the distribution. */ 2502 typedef _RealType result_type; 2503 2504 /** Parameter type. */ 2505 struct param_type 2506 { 2507 friend class triangular_distribution<_RealType>; 2508 2509 param_type() : param_type(0) { } 2510 2511 explicit 2512 param_type(_RealType __a, 2513 _RealType __b = _RealType(0.5), 2514 _RealType __c = _RealType(1)) 2515 : _M_a(__a), _M_b(__b), _M_c(__c) 2516 { 2517 __glibcxx_assert(_M_a <= _M_b); 2518 __glibcxx_assert(_M_b <= _M_c); 2519 __glibcxx_assert(_M_a < _M_c); 2520 2521 _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a); 2522 _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a); 2523 _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a); 2524 } 2525 2526 _RealType 2527 a() const 2528 { return _M_a; } 2529 2530 _RealType 2531 b() const 2532 { return _M_b; } 2533 2534 _RealType 2535 c() const 2536 { return _M_c; } 2537 2538 friend bool 2539 operator==(const param_type& __p1, const param_type& __p2) 2540 { 2541 return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b 2542 && __p1._M_c == __p2._M_c); 2543 } 2544 2545 #if __cpp_impl_three_way_comparison < 201907L 2546 friend bool 2547 operator!=(const param_type& __p1, const param_type& __p2) 2548 { return !(__p1 == __p2); } 2549 #endif 2550 2551 private: 2552 2553 _RealType _M_a; 2554 _RealType _M_b; 2555 _RealType _M_c; 2556 _RealType _M_r_ab; 2557 _RealType _M_f_ab_ac; 2558 _RealType _M_f_bc_ac; 2559 }; 2560 2561 triangular_distribution() : triangular_distribution(0.0) { } 2562 2563 /** 2564 * @brief Constructs a triangle distribution with parameters 2565 * @f$ a @f$, @f$ b @f$ and @f$ c @f$. 2566 */ 2567 explicit 2568 triangular_distribution(result_type __a, 2569 result_type __b = result_type(0.5), 2570 result_type __c = result_type(1)) 2571 : _M_param(__a, __b, __c) 2572 { } 2573 2574 explicit 2575 triangular_distribution(const param_type& __p) 2576 : _M_param(__p) 2577 { } 2578 2579 /** 2580 * @brief Resets the distribution state. 2581 */ 2582 void 2583 reset() 2584 { } 2585 2586 /** 2587 * @brief Returns the @f$ a @f$ of the distribution. 2588 */ 2589 result_type 2590 a() const 2591 { return _M_param.a(); } 2592 2593 /** 2594 * @brief Returns the @f$ b @f$ of the distribution. 2595 */ 2596 result_type 2597 b() const 2598 { return _M_param.b(); } 2599 2600 /** 2601 * @brief Returns the @f$ c @f$ of the distribution. 2602 */ 2603 result_type 2604 c() const 2605 { return _M_param.c(); } 2606 2607 /** 2608 * @brief Returns the parameter set of the distribution. 2609 */ 2610 param_type 2611 param() const 2612 { return _M_param; } 2613 2614 /** 2615 * @brief Sets the parameter set of the distribution. 2616 * @param __param The new parameter set of the distribution. 2617 */ 2618 void 2619 param(const param_type& __param) 2620 { _M_param = __param; } 2621 2622 /** 2623 * @brief Returns the greatest lower bound value of the distribution. 2624 */ 2625 result_type 2626 min() const 2627 { return _M_param._M_a; } 2628 2629 /** 2630 * @brief Returns the least upper bound value of the distribution. 2631 */ 2632 result_type 2633 max() const 2634 { return _M_param._M_c; } 2635 2636 /** 2637 * @brief Generating functions. 2638 */ 2639 template<typename _UniformRandomNumberGenerator> 2640 result_type 2641 operator()(_UniformRandomNumberGenerator& __urng) 2642 { return this->operator()(__urng, _M_param); } 2643 2644 template<typename _UniformRandomNumberGenerator> 2645 result_type 2646 operator()(_UniformRandomNumberGenerator& __urng, 2647 const param_type& __p) 2648 { 2649 std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> 2650 __aurng(__urng); 2651 result_type __rnd = __aurng(); 2652 if (__rnd <= __p._M_r_ab) 2653 return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac); 2654 else 2655 return __p.c() - std::sqrt((result_type(1) - __rnd) 2656 * __p._M_f_bc_ac); 2657 } 2658 2659 template<typename _ForwardIterator, 2660 typename _UniformRandomNumberGenerator> 2661 void 2662 __generate(_ForwardIterator __f, _ForwardIterator __t, 2663 _UniformRandomNumberGenerator& __urng) 2664 { this->__generate(__f, __t, __urng, _M_param); } 2665 2666 template<typename _ForwardIterator, 2667 typename _UniformRandomNumberGenerator> 2668 void 2669 __generate(_ForwardIterator __f, _ForwardIterator __t, 2670 _UniformRandomNumberGenerator& __urng, 2671 const param_type& __p) 2672 { this->__generate_impl(__f, __t, __urng, __p); } 2673 2674 template<typename _UniformRandomNumberGenerator> 2675 void 2676 __generate(result_type* __f, result_type* __t, 2677 _UniformRandomNumberGenerator& __urng, 2678 const param_type& __p) 2679 { this->__generate_impl(__f, __t, __urng, __p); } 2680 2681 /** 2682 * @brief Return true if two triangle distributions have the same 2683 * parameters and the sequences that would be generated 2684 * are equal. 2685 */ 2686 friend bool 2687 operator==(const triangular_distribution& __d1, 2688 const triangular_distribution& __d2) 2689 { return __d1._M_param == __d2._M_param; } 2690 2691 /** 2692 * @brief Inserts a %triangular_distribution random number distribution 2693 * @p __x into the output stream @p __os. 2694 * 2695 * @param __os An output stream. 2696 * @param __x A %triangular_distribution random number distribution. 2697 * 2698 * @returns The output stream with the state of @p __x inserted or in 2699 * an error state. 2700 */ 2701 template<typename _RealType1, typename _CharT, typename _Traits> 2702 friend std::basic_ostream<_CharT, _Traits>& 2703 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2704 const __gnu_cxx::triangular_distribution<_RealType1>& __x); 2705 2706 /** 2707 * @brief Extracts a %triangular_distribution random number distribution 2708 * @p __x from the input stream @p __is. 2709 * 2710 * @param __is An input stream. 2711 * @param __x A %triangular_distribution random number generator engine. 2712 * 2713 * @returns The input stream with @p __x extracted or in an error state. 2714 */ 2715 template<typename _RealType1, typename _CharT, typename _Traits> 2716 friend std::basic_istream<_CharT, _Traits>& 2717 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2718 __gnu_cxx::triangular_distribution<_RealType1>& __x); 2719 2720 private: 2721 template<typename _ForwardIterator, 2722 typename _UniformRandomNumberGenerator> 2723 void 2724 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2725 _UniformRandomNumberGenerator& __urng, 2726 const param_type& __p); 2727 2728 param_type _M_param; 2729 }; 2730 2731 #if __cpp_impl_three_way_comparison < 201907L 2732 /** 2733 * @brief Return true if two triangle distributions are different. 2734 */ 2735 template<typename _RealType> 2736 inline bool 2737 operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1, 2738 const __gnu_cxx::triangular_distribution<_RealType>& __d2) 2739 { return !(__d1 == __d2); } 2740 #endif 2741 2742 /** 2743 * @brief A von Mises distribution for random numbers. 2744 * 2745 * The formula for the von Mises probability density function is 2746 * @f[ 2747 * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}} 2748 * {2\pi I_0(\kappa)} 2749 * @f] 2750 * 2751 * The generating functions use the method according to: 2752 * 2753 * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the 2754 * von Mises Distribution", Journal of the Royal Statistical Society. 2755 * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157. 2756 * 2757 * <table border=1 cellpadding=10 cellspacing=0> 2758 * <caption align=top>Distribution Statistics</caption> 2759 * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr> 2760 * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr> 2761 * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr> 2762 * </table> 2763 */ 2764 template<typename _RealType = double> 2765 class von_mises_distribution 2766 { 2767 static_assert(std::is_floating_point<_RealType>::value, 2768 "template argument not a floating point type"); 2769 2770 public: 2771 /** The type of the range of the distribution. */ 2772 typedef _RealType result_type; 2773 2774 /** Parameter type. */ 2775 struct param_type 2776 { 2777 friend class von_mises_distribution<_RealType>; 2778 2779 param_type() : param_type(0) { } 2780 2781 explicit 2782 param_type(_RealType __mu, _RealType __kappa = _RealType(1)) 2783 : _M_mu(__mu), _M_kappa(__kappa) 2784 { 2785 const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi; 2786 __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi); 2787 __glibcxx_assert(_M_kappa >= _RealType(0)); 2788 2789 auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa 2790 + _RealType(1)) + _RealType(1); 2791 auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau)) 2792 / (_RealType(2) * _M_kappa)); 2793 _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho); 2794 } 2795 2796 _RealType 2797 mu() const 2798 { return _M_mu; } 2799 2800 _RealType 2801 kappa() const 2802 { return _M_kappa; } 2803 2804 friend bool 2805 operator==(const param_type& __p1, const param_type& __p2) 2806 { return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; } 2807 2808 #if __cpp_impl_three_way_comparison < 201907L 2809 friend bool 2810 operator!=(const param_type& __p1, const param_type& __p2) 2811 { return !(__p1 == __p2); } 2812 #endif 2813 2814 private: 2815 _RealType _M_mu; 2816 _RealType _M_kappa; 2817 _RealType _M_r; 2818 }; 2819 2820 von_mises_distribution() : von_mises_distribution(0.0) { } 2821 2822 /** 2823 * @brief Constructs a von Mises distribution with parameters 2824 * @f$\mu@f$ and @f$\kappa@f$. 2825 */ 2826 explicit 2827 von_mises_distribution(result_type __mu, 2828 result_type __kappa = result_type(1)) 2829 : _M_param(__mu, __kappa) 2830 { } 2831 2832 explicit 2833 von_mises_distribution(const param_type& __p) 2834 : _M_param(__p) 2835 { } 2836 2837 /** 2838 * @brief Resets the distribution state. 2839 */ 2840 void 2841 reset() 2842 { } 2843 2844 /** 2845 * @brief Returns the @f$ \mu @f$ of the distribution. 2846 */ 2847 result_type 2848 mu() const 2849 { return _M_param.mu(); } 2850 2851 /** 2852 * @brief Returns the @f$ \kappa @f$ of the distribution. 2853 */ 2854 result_type 2855 kappa() const 2856 { return _M_param.kappa(); } 2857 2858 /** 2859 * @brief Returns the parameter set of the distribution. 2860 */ 2861 param_type 2862 param() const 2863 { return _M_param; } 2864 2865 /** 2866 * @brief Sets the parameter set of the distribution. 2867 * @param __param The new parameter set of the distribution. 2868 */ 2869 void 2870 param(const param_type& __param) 2871 { _M_param = __param; } 2872 2873 /** 2874 * @brief Returns the greatest lower bound value of the distribution. 2875 */ 2876 result_type 2877 min() const 2878 { 2879 return -__gnu_cxx::__math_constants<result_type>::__pi; 2880 } 2881 2882 /** 2883 * @brief Returns the least upper bound value of the distribution. 2884 */ 2885 result_type 2886 max() const 2887 { 2888 return __gnu_cxx::__math_constants<result_type>::__pi; 2889 } 2890 2891 /** 2892 * @brief Generating functions. 2893 */ 2894 template<typename _UniformRandomNumberGenerator> 2895 result_type 2896 operator()(_UniformRandomNumberGenerator& __urng) 2897 { return this->operator()(__urng, _M_param); } 2898 2899 template<typename _UniformRandomNumberGenerator> 2900 result_type 2901 operator()(_UniformRandomNumberGenerator& __urng, 2902 const param_type& __p); 2903 2904 template<typename _ForwardIterator, 2905 typename _UniformRandomNumberGenerator> 2906 void 2907 __generate(_ForwardIterator __f, _ForwardIterator __t, 2908 _UniformRandomNumberGenerator& __urng) 2909 { this->__generate(__f, __t, __urng, _M_param); } 2910 2911 template<typename _ForwardIterator, 2912 typename _UniformRandomNumberGenerator> 2913 void 2914 __generate(_ForwardIterator __f, _ForwardIterator __t, 2915 _UniformRandomNumberGenerator& __urng, 2916 const param_type& __p) 2917 { this->__generate_impl(__f, __t, __urng, __p); } 2918 2919 template<typename _UniformRandomNumberGenerator> 2920 void 2921 __generate(result_type* __f, result_type* __t, 2922 _UniformRandomNumberGenerator& __urng, 2923 const param_type& __p) 2924 { this->__generate_impl(__f, __t, __urng, __p); } 2925 2926 /** 2927 * @brief Return true if two von Mises distributions have the same 2928 * parameters and the sequences that would be generated 2929 * are equal. 2930 */ 2931 friend bool 2932 operator==(const von_mises_distribution& __d1, 2933 const von_mises_distribution& __d2) 2934 { return __d1._M_param == __d2._M_param; } 2935 2936 /** 2937 * @brief Inserts a %von_mises_distribution random number distribution 2938 * @p __x into the output stream @p __os. 2939 * 2940 * @param __os An output stream. 2941 * @param __x A %von_mises_distribution random number distribution. 2942 * 2943 * @returns The output stream with the state of @p __x inserted or in 2944 * an error state. 2945 */ 2946 template<typename _RealType1, typename _CharT, typename _Traits> 2947 friend std::basic_ostream<_CharT, _Traits>& 2948 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 2949 const __gnu_cxx::von_mises_distribution<_RealType1>& __x); 2950 2951 /** 2952 * @brief Extracts a %von_mises_distribution random number distribution 2953 * @p __x from the input stream @p __is. 2954 * 2955 * @param __is An input stream. 2956 * @param __x A %von_mises_distribution random number generator engine. 2957 * 2958 * @returns The input stream with @p __x extracted or in an error state. 2959 */ 2960 template<typename _RealType1, typename _CharT, typename _Traits> 2961 friend std::basic_istream<_CharT, _Traits>& 2962 operator>>(std::basic_istream<_CharT, _Traits>& __is, 2963 __gnu_cxx::von_mises_distribution<_RealType1>& __x); 2964 2965 private: 2966 template<typename _ForwardIterator, 2967 typename _UniformRandomNumberGenerator> 2968 void 2969 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 2970 _UniformRandomNumberGenerator& __urng, 2971 const param_type& __p); 2972 2973 param_type _M_param; 2974 }; 2975 2976 #if __cpp_impl_three_way_comparison < 201907L 2977 /** 2978 * @brief Return true if two von Mises distributions are different. 2979 */ 2980 template<typename _RealType> 2981 inline bool 2982 operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1, 2983 const __gnu_cxx::von_mises_distribution<_RealType>& __d2) 2984 { return !(__d1 == __d2); } 2985 #endif 2986 2987 /** 2988 * @brief A discrete hypergeometric random number distribution. 2989 * 2990 * The hypergeometric distribution is a discrete probability distribution 2991 * that describes the probability of @p k successes in @p n draws @a without 2992 * replacement from a finite population of size @p N containing exactly @p K 2993 * successes. 2994 * 2995 * The formula for the hypergeometric probability density function is 2996 * @f[ 2997 * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}} 2998 * @f] 2999 * where @f$N@f$ is the total population of the distribution, 3000 * @f$K@f$ is the total population of the distribution. 3001 * 3002 * <table border=1 cellpadding=10 cellspacing=0> 3003 * <caption align=top>Distribution Statistics</caption> 3004 * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr> 3005 * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1} 3006 * @f$</td></tr> 3007 * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr> 3008 * </table> 3009 */ 3010 template<typename _UIntType = unsigned int> 3011 class hypergeometric_distribution 3012 { 3013 static_assert(std::is_unsigned<_UIntType>::value, "template argument " 3014 "substituting _UIntType not an unsigned integral type"); 3015 3016 public: 3017 /** The type of the range of the distribution. */ 3018 typedef _UIntType result_type; 3019 3020 /** Parameter type. */ 3021 struct param_type 3022 { 3023 typedef hypergeometric_distribution<_UIntType> distribution_type; 3024 friend class hypergeometric_distribution<_UIntType>; 3025 3026 param_type() : param_type(10) { } 3027 3028 explicit 3029 param_type(result_type __N, result_type __K = 5, 3030 result_type __n = 1) 3031 : _M_N{__N}, _M_K{__K}, _M_n{__n} 3032 { 3033 __glibcxx_assert(_M_N >= _M_K); 3034 __glibcxx_assert(_M_N >= _M_n); 3035 } 3036 3037 result_type 3038 total_size() const 3039 { return _M_N; } 3040 3041 result_type 3042 successful_size() const 3043 { return _M_K; } 3044 3045 result_type 3046 unsuccessful_size() const 3047 { return _M_N - _M_K; } 3048 3049 result_type 3050 total_draws() const 3051 { return _M_n; } 3052 3053 friend bool 3054 operator==(const param_type& __p1, const param_type& __p2) 3055 { return (__p1._M_N == __p2._M_N) 3056 && (__p1._M_K == __p2._M_K) 3057 && (__p1._M_n == __p2._M_n); } 3058 3059 #if __cpp_impl_three_way_comparison < 201907L 3060 friend bool 3061 operator!=(const param_type& __p1, const param_type& __p2) 3062 { return !(__p1 == __p2); } 3063 #endif 3064 3065 private: 3066 3067 result_type _M_N; 3068 result_type _M_K; 3069 result_type _M_n; 3070 }; 3071 3072 // constructors and member functions 3073 3074 hypergeometric_distribution() : hypergeometric_distribution(10) { } 3075 3076 explicit 3077 hypergeometric_distribution(result_type __N, result_type __K = 5, 3078 result_type __n = 1) 3079 : _M_param{__N, __K, __n} 3080 { } 3081 3082 explicit 3083 hypergeometric_distribution(const param_type& __p) 3084 : _M_param{__p} 3085 { } 3086 3087 /** 3088 * @brief Resets the distribution state. 3089 */ 3090 void 3091 reset() 3092 { } 3093 3094 /** 3095 * @brief Returns the distribution parameter @p N, 3096 * the total number of items. 3097 */ 3098 result_type 3099 total_size() const 3100 { return this->_M_param.total_size(); } 3101 3102 /** 3103 * @brief Returns the distribution parameter @p K, 3104 * the total number of successful items. 3105 */ 3106 result_type 3107 successful_size() const 3108 { return this->_M_param.successful_size(); } 3109 3110 /** 3111 * @brief Returns the total number of unsuccessful items @f$ N - K @f$. 3112 */ 3113 result_type 3114 unsuccessful_size() const 3115 { return this->_M_param.unsuccessful_size(); } 3116 3117 /** 3118 * @brief Returns the distribution parameter @p n, 3119 * the total number of draws. 3120 */ 3121 result_type 3122 total_draws() const 3123 { return this->_M_param.total_draws(); } 3124 3125 /** 3126 * @brief Returns the parameter set of the distribution. 3127 */ 3128 param_type 3129 param() const 3130 { return this->_M_param; } 3131 3132 /** 3133 * @brief Sets the parameter set of the distribution. 3134 * @param __param The new parameter set of the distribution. 3135 */ 3136 void 3137 param(const param_type& __param) 3138 { this->_M_param = __param; } 3139 3140 /** 3141 * @brief Returns the greatest lower bound value of the distribution. 3142 */ 3143 result_type 3144 min() const 3145 { 3146 using _IntType = typename std::make_signed<result_type>::type; 3147 return static_cast<result_type>(std::max(static_cast<_IntType>(0), 3148 static_cast<_IntType>(this->total_draws() 3149 - this->unsuccessful_size()))); 3150 } 3151 3152 /** 3153 * @brief Returns the least upper bound value of the distribution. 3154 */ 3155 result_type 3156 max() const 3157 { return std::min(this->successful_size(), this->total_draws()); } 3158 3159 /** 3160 * @brief Generating functions. 3161 */ 3162 template<typename _UniformRandomNumberGenerator> 3163 result_type 3164 operator()(_UniformRandomNumberGenerator& __urng) 3165 { return this->operator()(__urng, this->_M_param); } 3166 3167 template<typename _UniformRandomNumberGenerator> 3168 result_type 3169 operator()(_UniformRandomNumberGenerator& __urng, 3170 const param_type& __p); 3171 3172 template<typename _ForwardIterator, 3173 typename _UniformRandomNumberGenerator> 3174 void 3175 __generate(_ForwardIterator __f, _ForwardIterator __t, 3176 _UniformRandomNumberGenerator& __urng) 3177 { this->__generate(__f, __t, __urng, this->_M_param); } 3178 3179 template<typename _ForwardIterator, 3180 typename _UniformRandomNumberGenerator> 3181 void 3182 __generate(_ForwardIterator __f, _ForwardIterator __t, 3183 _UniformRandomNumberGenerator& __urng, 3184 const param_type& __p) 3185 { this->__generate_impl(__f, __t, __urng, __p); } 3186 3187 template<typename _UniformRandomNumberGenerator> 3188 void 3189 __generate(result_type* __f, result_type* __t, 3190 _UniformRandomNumberGenerator& __urng, 3191 const param_type& __p) 3192 { this->__generate_impl(__f, __t, __urng, __p); } 3193 3194 /** 3195 * @brief Return true if two hypergeometric distributions have the same 3196 * parameters and the sequences that would be generated 3197 * are equal. 3198 */ 3199 friend bool 3200 operator==(const hypergeometric_distribution& __d1, 3201 const hypergeometric_distribution& __d2) 3202 { return __d1._M_param == __d2._M_param; } 3203 3204 /** 3205 * @brief Inserts a %hypergeometric_distribution random number 3206 * distribution @p __x into the output stream @p __os. 3207 * 3208 * @param __os An output stream. 3209 * @param __x A %hypergeometric_distribution random number 3210 * distribution. 3211 * 3212 * @returns The output stream with the state of @p __x inserted or in 3213 * an error state. 3214 */ 3215 template<typename _UIntType1, typename _CharT, typename _Traits> 3216 friend std::basic_ostream<_CharT, _Traits>& 3217 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3218 const __gnu_cxx::hypergeometric_distribution<_UIntType1>& 3219 __x); 3220 3221 /** 3222 * @brief Extracts a %hypergeometric_distribution random number 3223 * distribution @p __x from the input stream @p __is. 3224 * 3225 * @param __is An input stream. 3226 * @param __x A %hypergeometric_distribution random number generator 3227 * distribution. 3228 * 3229 * @returns The input stream with @p __x extracted or in an error 3230 * state. 3231 */ 3232 template<typename _UIntType1, typename _CharT, typename _Traits> 3233 friend std::basic_istream<_CharT, _Traits>& 3234 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3235 __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); 3236 3237 private: 3238 3239 template<typename _ForwardIterator, 3240 typename _UniformRandomNumberGenerator> 3241 void 3242 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3243 _UniformRandomNumberGenerator& __urng, 3244 const param_type& __p); 3245 3246 param_type _M_param; 3247 }; 3248 3249 #if __cpp_impl_three_way_comparison < 201907L 3250 /** 3251 * @brief Return true if two hypergeometric distributions are different. 3252 */ 3253 template<typename _UIntType> 3254 inline bool 3255 operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1, 3256 const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2) 3257 { return !(__d1 == __d2); } 3258 #endif 3259 3260 /** 3261 * @brief A logistic continuous distribution for random numbers. 3262 * 3263 * The formula for the logistic probability density function is 3264 * @f[ 3265 * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2} 3266 * @f] 3267 * where @f$b > 0@f$. 3268 * 3269 * The formula for the logistic probability function is 3270 * @f[ 3271 * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}} 3272 * @f] 3273 * where @f$b > 0@f$. 3274 * 3275 * <table border=1 cellpadding=10 cellspacing=0> 3276 * <caption align=top>Distribution Statistics</caption> 3277 * <tr><td>Mean</td><td>@f$a@f$</td></tr> 3278 * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr> 3279 * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> 3280 * </table> 3281 */ 3282 template<typename _RealType = double> 3283 class 3284 logistic_distribution 3285 { 3286 static_assert(std::is_floating_point<_RealType>::value, 3287 "template argument not a floating point type"); 3288 3289 public: 3290 /** The type of the range of the distribution. */ 3291 typedef _RealType result_type; 3292 3293 /** Parameter type. */ 3294 struct param_type 3295 { 3296 typedef logistic_distribution<result_type> distribution_type; 3297 3298 param_type() : param_type(0) { } 3299 3300 explicit 3301 param_type(result_type __a, result_type __b = result_type(1)) 3302 : _M_a(__a), _M_b(__b) 3303 { 3304 __glibcxx_assert(_M_b > result_type(0)); 3305 } 3306 3307 result_type 3308 a() const 3309 { return _M_a; } 3310 3311 result_type 3312 b() const 3313 { return _M_b; } 3314 3315 friend bool 3316 operator==(const param_type& __p1, const param_type& __p2) 3317 { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } 3318 3319 #if __cpp_impl_three_way_comparison < 201907L 3320 friend bool 3321 operator!=(const param_type& __p1, const param_type& __p2) 3322 { return !(__p1 == __p2); } 3323 #endif 3324 3325 private: 3326 void _M_initialize(); 3327 3328 result_type _M_a; 3329 result_type _M_b; 3330 }; 3331 3332 /** 3333 * @brief Constructors. 3334 * @{ 3335 */ 3336 logistic_distribution() : logistic_distribution(0.0) { } 3337 3338 explicit 3339 logistic_distribution(result_type __a, result_type __b = result_type(1)) 3340 : _M_param(__a, __b) 3341 { } 3342 3343 explicit 3344 logistic_distribution(const param_type& __p) 3345 : _M_param(__p) 3346 { } 3347 3348 /// @} 3349 3350 /** 3351 * @brief Resets the distribution state. 3352 */ 3353 void 3354 reset() 3355 { } 3356 3357 /** 3358 * @brief Return the parameters of the distribution. 3359 */ 3360 result_type 3361 a() const 3362 { return _M_param.a(); } 3363 3364 result_type 3365 b() const 3366 { return _M_param.b(); } 3367 3368 /** 3369 * @brief Returns the parameter set of the distribution. 3370 */ 3371 param_type 3372 param() const 3373 { return _M_param; } 3374 3375 /** 3376 * @brief Sets the parameter set of the distribution. 3377 * @param __param The new parameter set of the distribution. 3378 */ 3379 void 3380 param(const param_type& __param) 3381 { _M_param = __param; } 3382 3383 /** 3384 * @brief Returns the greatest lower bound value of the distribution. 3385 */ 3386 result_type 3387 min() const 3388 { return -std::numeric_limits<result_type>::max(); } 3389 3390 /** 3391 * @brief Returns the least upper bound value of the distribution. 3392 */ 3393 result_type 3394 max() const 3395 { return std::numeric_limits<result_type>::max(); } 3396 3397 /** 3398 * @brief Generating functions. 3399 */ 3400 template<typename _UniformRandomNumberGenerator> 3401 result_type 3402 operator()(_UniformRandomNumberGenerator& __urng) 3403 { return this->operator()(__urng, this->_M_param); } 3404 3405 template<typename _UniformRandomNumberGenerator> 3406 result_type 3407 operator()(_UniformRandomNumberGenerator&, 3408 const param_type&); 3409 3410 template<typename _ForwardIterator, 3411 typename _UniformRandomNumberGenerator> 3412 void 3413 __generate(_ForwardIterator __f, _ForwardIterator __t, 3414 _UniformRandomNumberGenerator& __urng) 3415 { this->__generate(__f, __t, __urng, this->param()); } 3416 3417 template<typename _ForwardIterator, 3418 typename _UniformRandomNumberGenerator> 3419 void 3420 __generate(_ForwardIterator __f, _ForwardIterator __t, 3421 _UniformRandomNumberGenerator& __urng, 3422 const param_type& __p) 3423 { this->__generate_impl(__f, __t, __urng, __p); } 3424 3425 template<typename _UniformRandomNumberGenerator> 3426 void 3427 __generate(result_type* __f, result_type* __t, 3428 _UniformRandomNumberGenerator& __urng, 3429 const param_type& __p) 3430 { this->__generate_impl(__f, __t, __urng, __p); } 3431 3432 /** 3433 * @brief Return true if two logistic distributions have 3434 * the same parameters and the sequences that would 3435 * be generated are equal. 3436 */ 3437 template<typename _RealType1> 3438 friend bool 3439 operator==(const logistic_distribution<_RealType1>& __d1, 3440 const logistic_distribution<_RealType1>& __d2) 3441 { return __d1.param() == __d2.param(); } 3442 3443 /** 3444 * @brief Inserts a %logistic_distribution random number distribution 3445 * @p __x into the output stream @p __os. 3446 * 3447 * @param __os An output stream. 3448 * @param __x A %logistic_distribution random number distribution. 3449 * 3450 * @returns The output stream with the state of @p __x inserted or in 3451 * an error state. 3452 */ 3453 template<typename _RealType1, typename _CharT, typename _Traits> 3454 friend std::basic_ostream<_CharT, _Traits>& 3455 operator<<(std::basic_ostream<_CharT, _Traits>&, 3456 const logistic_distribution<_RealType1>&); 3457 3458 /** 3459 * @brief Extracts a %logistic_distribution random number distribution 3460 * @p __x from the input stream @p __is. 3461 * 3462 * @param __is An input stream. 3463 * @param __x A %logistic_distribution random number 3464 * generator engine. 3465 * 3466 * @returns The input stream with @p __x extracted or in an error state. 3467 */ 3468 template<typename _RealType1, typename _CharT, typename _Traits> 3469 friend std::basic_istream<_CharT, _Traits>& 3470 operator>>(std::basic_istream<_CharT, _Traits>&, 3471 logistic_distribution<_RealType1>&); 3472 3473 private: 3474 template<typename _ForwardIterator, 3475 typename _UniformRandomNumberGenerator> 3476 void 3477 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3478 _UniformRandomNumberGenerator& __urng, 3479 const param_type& __p); 3480 3481 param_type _M_param; 3482 }; 3483 3484 #if __cpp_impl_three_way_comparison < 201907L 3485 /** 3486 * @brief Return true if two logistic distributions are not equal. 3487 */ 3488 template<typename _RealType1> 3489 inline bool 3490 operator!=(const logistic_distribution<_RealType1>& __d1, 3491 const logistic_distribution<_RealType1>& __d2) 3492 { return !(__d1 == __d2); } 3493 #endif 3494 3495 /** 3496 * @brief A distribution for random coordinates on a unit sphere. 3497 * 3498 * The method used in the generation function is attributed by Donald Knuth 3499 * to G. W. Brown, Modern Mathematics for the Engineer (1956). 3500 */ 3501 template<std::size_t _Dimen, typename _RealType = double> 3502 class uniform_on_sphere_distribution 3503 { 3504 static_assert(std::is_floating_point<_RealType>::value, 3505 "template argument not a floating point type"); 3506 static_assert(_Dimen != 0, "dimension is zero"); 3507 3508 public: 3509 /** The type of the range of the distribution. */ 3510 typedef std::array<_RealType, _Dimen> result_type; 3511 3512 /** Parameter type. */ 3513 struct param_type 3514 { 3515 param_type() { } 3516 3517 friend bool 3518 operator==(const param_type&, const param_type&) 3519 { return true; } 3520 3521 #if __cpp_impl_three_way_comparison < 201907L 3522 friend bool 3523 operator!=(const param_type&, const param_type&) 3524 { return false; } 3525 #endif 3526 }; 3527 3528 /** 3529 * @brief Constructs a uniform on sphere distribution. 3530 */ 3531 uniform_on_sphere_distribution() 3532 : _M_param(), _M_nd() 3533 { } 3534 3535 explicit 3536 uniform_on_sphere_distribution(const param_type& __p) 3537 : _M_param(__p), _M_nd() 3538 { } 3539 3540 /** 3541 * @brief Resets the distribution state. 3542 */ 3543 void 3544 reset() 3545 { _M_nd.reset(); } 3546 3547 /** 3548 * @brief Returns the parameter set of the distribution. 3549 */ 3550 param_type 3551 param() const 3552 { return _M_param; } 3553 3554 /** 3555 * @brief Sets the parameter set of the distribution. 3556 * @param __param The new parameter set of the distribution. 3557 */ 3558 void 3559 param(const param_type& __param) 3560 { _M_param = __param; } 3561 3562 /** 3563 * @brief Returns the greatest lower bound value of the distribution. 3564 * This function makes no sense for this distribution. 3565 */ 3566 result_type 3567 min() const 3568 { 3569 result_type __res; 3570 __res.fill(0); 3571 return __res; 3572 } 3573 3574 /** 3575 * @brief Returns the least upper bound value of the distribution. 3576 * This function makes no sense for this distribution. 3577 */ 3578 result_type 3579 max() const 3580 { 3581 result_type __res; 3582 __res.fill(0); 3583 return __res; 3584 } 3585 3586 /** 3587 * @brief Generating functions. 3588 */ 3589 template<typename _UniformRandomNumberGenerator> 3590 result_type 3591 operator()(_UniformRandomNumberGenerator& __urng) 3592 { return this->operator()(__urng, _M_param); } 3593 3594 template<typename _UniformRandomNumberGenerator> 3595 result_type 3596 operator()(_UniformRandomNumberGenerator& __urng, 3597 const param_type& __p); 3598 3599 template<typename _ForwardIterator, 3600 typename _UniformRandomNumberGenerator> 3601 void 3602 __generate(_ForwardIterator __f, _ForwardIterator __t, 3603 _UniformRandomNumberGenerator& __urng) 3604 { this->__generate(__f, __t, __urng, this->param()); } 3605 3606 template<typename _ForwardIterator, 3607 typename _UniformRandomNumberGenerator> 3608 void 3609 __generate(_ForwardIterator __f, _ForwardIterator __t, 3610 _UniformRandomNumberGenerator& __urng, 3611 const param_type& __p) 3612 { this->__generate_impl(__f, __t, __urng, __p); } 3613 3614 template<typename _UniformRandomNumberGenerator> 3615 void 3616 __generate(result_type* __f, result_type* __t, 3617 _UniformRandomNumberGenerator& __urng, 3618 const param_type& __p) 3619 { this->__generate_impl(__f, __t, __urng, __p); } 3620 3621 /** 3622 * @brief Return true if two uniform on sphere distributions have 3623 * the same parameters and the sequences that would be 3624 * generated are equal. 3625 */ 3626 friend bool 3627 operator==(const uniform_on_sphere_distribution& __d1, 3628 const uniform_on_sphere_distribution& __d2) 3629 { return __d1._M_nd == __d2._M_nd; } 3630 3631 /** 3632 * @brief Inserts a %uniform_on_sphere_distribution random number 3633 * distribution @p __x into the output stream @p __os. 3634 * 3635 * @param __os An output stream. 3636 * @param __x A %uniform_on_sphere_distribution random number 3637 * distribution. 3638 * 3639 * @returns The output stream with the state of @p __x inserted or in 3640 * an error state. 3641 */ 3642 template<size_t _Dimen1, typename _RealType1, typename _CharT, 3643 typename _Traits> 3644 friend std::basic_ostream<_CharT, _Traits>& 3645 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3646 const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, 3647 _RealType1>& 3648 __x); 3649 3650 /** 3651 * @brief Extracts a %uniform_on_sphere_distribution random number 3652 * distribution 3653 * @p __x from the input stream @p __is. 3654 * 3655 * @param __is An input stream. 3656 * @param __x A %uniform_on_sphere_distribution random number 3657 * generator engine. 3658 * 3659 * @returns The input stream with @p __x extracted or in an error state. 3660 */ 3661 template<std::size_t _Dimen1, typename _RealType1, typename _CharT, 3662 typename _Traits> 3663 friend std::basic_istream<_CharT, _Traits>& 3664 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3665 __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, 3666 _RealType1>& __x); 3667 3668 private: 3669 template<typename _ForwardIterator, 3670 typename _UniformRandomNumberGenerator> 3671 void 3672 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3673 _UniformRandomNumberGenerator& __urng, 3674 const param_type& __p); 3675 3676 param_type _M_param; 3677 std::normal_distribution<_RealType> _M_nd; 3678 }; 3679 3680 #if __cpp_impl_three_way_comparison < 201907L 3681 /** 3682 * @brief Return true if two uniform on sphere distributions are different. 3683 */ 3684 template<std::size_t _Dimen, typename _RealType> 3685 inline bool 3686 operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, 3687 _RealType>& __d1, 3688 const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, 3689 _RealType>& __d2) 3690 { return !(__d1 == __d2); } 3691 #endif 3692 3693 /** 3694 * @brief A distribution for random coordinates inside a unit sphere. 3695 */ 3696 template<std::size_t _Dimen, typename _RealType = double> 3697 class uniform_inside_sphere_distribution 3698 { 3699 static_assert(std::is_floating_point<_RealType>::value, 3700 "template argument not a floating point type"); 3701 static_assert(_Dimen != 0, "dimension is zero"); 3702 3703 public: 3704 /** The type of the range of the distribution. */ 3705 using result_type = std::array<_RealType, _Dimen>; 3706 3707 /** Parameter type. */ 3708 struct param_type 3709 { 3710 using distribution_type 3711 = uniform_inside_sphere_distribution<_Dimen, _RealType>; 3712 friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; 3713 3714 param_type() : param_type(1.0) { } 3715 3716 explicit 3717 param_type(_RealType __radius) 3718 : _M_radius(__radius) 3719 { 3720 __glibcxx_assert(_M_radius > _RealType(0)); 3721 } 3722 3723 _RealType 3724 radius() const 3725 { return _M_radius; } 3726 3727 friend bool 3728 operator==(const param_type& __p1, const param_type& __p2) 3729 { return __p1._M_radius == __p2._M_radius; } 3730 3731 #if __cpp_impl_three_way_comparison < 201907L 3732 friend bool 3733 operator!=(const param_type& __p1, const param_type& __p2) 3734 { return !(__p1 == __p2); } 3735 #endif 3736 3737 private: 3738 _RealType _M_radius; 3739 }; 3740 3741 /** 3742 * @brief Constructors. 3743 * @{ 3744 */ 3745 3746 uniform_inside_sphere_distribution() 3747 : uniform_inside_sphere_distribution(1.0) 3748 { } 3749 3750 explicit 3751 uniform_inside_sphere_distribution(_RealType __radius) 3752 : _M_param(__radius), _M_uosd() 3753 { } 3754 3755 explicit 3756 uniform_inside_sphere_distribution(const param_type& __p) 3757 : _M_param(__p), _M_uosd() 3758 { } 3759 3760 /// @} 3761 3762 /** 3763 * @brief Resets the distribution state. 3764 */ 3765 void 3766 reset() 3767 { _M_uosd.reset(); } 3768 3769 /** 3770 * @brief Returns the @f$radius@f$ of the distribution. 3771 */ 3772 _RealType 3773 radius() const 3774 { return _M_param.radius(); } 3775 3776 /** 3777 * @brief Returns the parameter set of the distribution. 3778 */ 3779 param_type 3780 param() const 3781 { return _M_param; } 3782 3783 /** 3784 * @brief Sets the parameter set of the distribution. 3785 * @param __param The new parameter set of the distribution. 3786 */ 3787 void 3788 param(const param_type& __param) 3789 { _M_param = __param; } 3790 3791 /** 3792 * @brief Returns the greatest lower bound value of the distribution. 3793 * This function makes no sense for this distribution. 3794 */ 3795 result_type 3796 min() const 3797 { 3798 result_type __res; 3799 __res.fill(0); 3800 return __res; 3801 } 3802 3803 /** 3804 * @brief Returns the least upper bound value of the distribution. 3805 * This function makes no sense for this distribution. 3806 */ 3807 result_type 3808 max() const 3809 { 3810 result_type __res; 3811 __res.fill(0); 3812 return __res; 3813 } 3814 3815 /** 3816 * @brief Generating functions. 3817 */ 3818 template<typename _UniformRandomNumberGenerator> 3819 result_type 3820 operator()(_UniformRandomNumberGenerator& __urng) 3821 { return this->operator()(__urng, _M_param); } 3822 3823 template<typename _UniformRandomNumberGenerator> 3824 result_type 3825 operator()(_UniformRandomNumberGenerator& __urng, 3826 const param_type& __p); 3827 3828 template<typename _ForwardIterator, 3829 typename _UniformRandomNumberGenerator> 3830 void 3831 __generate(_ForwardIterator __f, _ForwardIterator __t, 3832 _UniformRandomNumberGenerator& __urng) 3833 { this->__generate(__f, __t, __urng, this->param()); } 3834 3835 template<typename _ForwardIterator, 3836 typename _UniformRandomNumberGenerator> 3837 void 3838 __generate(_ForwardIterator __f, _ForwardIterator __t, 3839 _UniformRandomNumberGenerator& __urng, 3840 const param_type& __p) 3841 { this->__generate_impl(__f, __t, __urng, __p); } 3842 3843 template<typename _UniformRandomNumberGenerator> 3844 void 3845 __generate(result_type* __f, result_type* __t, 3846 _UniformRandomNumberGenerator& __urng, 3847 const param_type& __p) 3848 { this->__generate_impl(__f, __t, __urng, __p); } 3849 3850 /** 3851 * @brief Return true if two uniform on sphere distributions have 3852 * the same parameters and the sequences that would be 3853 * generated are equal. 3854 */ 3855 friend bool 3856 operator==(const uniform_inside_sphere_distribution& __d1, 3857 const uniform_inside_sphere_distribution& __d2) 3858 { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; } 3859 3860 /** 3861 * @brief Inserts a %uniform_inside_sphere_distribution random number 3862 * distribution @p __x into the output stream @p __os. 3863 * 3864 * @param __os An output stream. 3865 * @param __x A %uniform_inside_sphere_distribution random number 3866 * distribution. 3867 * 3868 * @returns The output stream with the state of @p __x inserted or in 3869 * an error state. 3870 */ 3871 template<size_t _Dimen1, typename _RealType1, typename _CharT, 3872 typename _Traits> 3873 friend std::basic_ostream<_CharT, _Traits>& 3874 operator<<(std::basic_ostream<_CharT, _Traits>& __os, 3875 const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, 3876 _RealType1>& 3877 ); 3878 3879 /** 3880 * @brief Extracts a %uniform_inside_sphere_distribution random number 3881 * distribution 3882 * @p __x from the input stream @p __is. 3883 * 3884 * @param __is An input stream. 3885 * @param __x A %uniform_inside_sphere_distribution random number 3886 * generator engine. 3887 * 3888 * @returns The input stream with @p __x extracted or in an error state. 3889 */ 3890 template<std::size_t _Dimen1, typename _RealType1, typename _CharT, 3891 typename _Traits> 3892 friend std::basic_istream<_CharT, _Traits>& 3893 operator>>(std::basic_istream<_CharT, _Traits>& __is, 3894 __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, 3895 _RealType1>&); 3896 3897 private: 3898 template<typename _ForwardIterator, 3899 typename _UniformRandomNumberGenerator> 3900 void 3901 __generate_impl(_ForwardIterator __f, _ForwardIterator __t, 3902 _UniformRandomNumberGenerator& __urng, 3903 const param_type& __p); 3904 3905 param_type _M_param; 3906 uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd; 3907 }; 3908 3909 #if __cpp_impl_three_way_comparison < 201907L 3910 /** 3911 * @brief Return true if two uniform on sphere distributions are different. 3912 */ 3913 template<std::size_t _Dimen, typename _RealType> 3914 inline bool 3915 operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, 3916 _RealType>& __d1, 3917 const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, 3918 _RealType>& __d2) 3919 { return !(__d1 == __d2); } 3920 #endif 3921 3922 _GLIBCXX_END_NAMESPACE_VERSION 3923 } // namespace __gnu_cxx 3924 3925 #include <ext/opt_random.h> 3926 #include <ext/random.tcc> 3927 3928 #endif // UINT32_C 3929 3930 #endif // C++11 3931 3932 #endif // _EXT_RANDOM