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