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