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