// Random number extensions -*- C++ -*- // Copyright (C) 2012 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/random * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_RANDOM #define _EXT_RANDOM 1 #pragma GCC system_header #ifndef __GXX_EXPERIMENTAL_CXX0X__ # include #else #include #include #ifdef __SSE2__ # include #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /* Mersenne twister implementation optimized for vector operations. * * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ */ template class simd_fast_mersenne_twister_engine { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__sr1 < 32, "first right shift too large"); static_assert(__sr2 < 16, "second right shift too large"); static_assert(__sl1 < 32, "first left shift too large"); static_assert(__sl2 < 16, "second left shift too large"); public: typedef _UIntType result_type; private: static constexpr size_t m_w = sizeof(result_type) * 8; static constexpr size_t _M_nstate = __m / 128 + 1; static constexpr size_t _M_nstate32 = _M_nstate * 4; static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); static_assert(16 % sizeof(_UIntType) == 0, "UIntType size must divide 16"); public: static constexpr size_t state_size = _M_nstate * (16 / sizeof(result_type)); static constexpr result_type default_seed = 5489u; // constructors and member function explicit simd_fast_mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); } template::value> ::type> explicit simd_fast_mersenne_twister_engine(_Sseq& __q) { seed(__q); } void seed(result_type __sd = default_seed); template typename std::enable_if::value>::type seed(_Sseq& __q); static constexpr result_type min() { return 0; }; static constexpr result_type max() { return std::numeric_limits::max(); } void discard(unsigned long long __z); result_type operator()() { if (__builtin_expect(_M_pos >= state_size, 0)) _M_gen_rand(); return _M_stateT[_M_pos++]; } template friend bool operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine <_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); private: union { #ifdef __SSE2__ __m128i _M_state[_M_nstate]; #endif uint32_t _M_state32[_M_nstate32]; result_type _M_stateT[state_size]; } __attribute__ ((__aligned__ (16))); size_t _M_pos; void _M_gen_rand(void); void _M_period_certification(); }; template inline bool operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { return !(__lhs == __rhs); } /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined * in the C implementation by Daito and Matsumoto, as both a 32-bit * and 64-bit version. */ typedef simd_fast_mersenne_twister_engine sfmt607; typedef simd_fast_mersenne_twister_engine sfmt607_64; typedef simd_fast_mersenne_twister_engine sfmt1279; typedef simd_fast_mersenne_twister_engine sfmt1279_64; typedef simd_fast_mersenne_twister_engine sfmt2281; typedef simd_fast_mersenne_twister_engine sfmt2281_64; typedef simd_fast_mersenne_twister_engine sfmt4253; typedef simd_fast_mersenne_twister_engine sfmt4253_64; typedef simd_fast_mersenne_twister_engine sfmt11213; typedef simd_fast_mersenne_twister_engine sfmt11213_64; typedef simd_fast_mersenne_twister_engine sfmt19937; typedef simd_fast_mersenne_twister_engine sfmt19937_64; typedef simd_fast_mersenne_twister_engine sfmt44497; typedef simd_fast_mersenne_twister_engine sfmt44497_64; typedef simd_fast_mersenne_twister_engine sfmt86243; typedef simd_fast_mersenne_twister_engine sfmt86243_64; typedef simd_fast_mersenne_twister_engine sfmt132049; typedef simd_fast_mersenne_twister_engine sfmt132049_64; typedef simd_fast_mersenne_twister_engine sfmt216091; typedef simd_fast_mersenne_twister_engine sfmt216091_64; /** * @brief A beta continuous distribution for random numbers. * * The formula for the beta probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} * x^{\alpha - 1} (1 - x)^{\beta - 1} * @f] */ template class beta_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef beta_distribution<_RealType> distribution_type; friend class beta_distribution<_RealType>; explicit param_type(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_alpha(__alpha_val), _M_beta(__beta_val) { _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0)); _GLIBCXX_DEBUG_ASSERT(_M_beta > _RealType(0)); } _RealType alpha() const { return _M_alpha; } _RealType beta() const { return _M_beta; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_alpha == __p2._M_alpha && __p1._M_beta == __p2._M_beta); } private: void _M_initialize(); _RealType _M_alpha; _RealType _M_beta; }; public: /** * @brief Constructs a beta distribution with parameters * @f$\alpha@f$ and @f$\beta@f$. */ explicit beta_distribution(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_param(__alpha_val, __beta_val) { } explicit beta_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$\alpha@f$ of the distribution. */ _RealType alpha() const { return _M_param.alpha(); } /** * @brief Returns the @f$\beta@f$ of the distribution. */ _RealType beta() const { return _M_param.beta(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return result_type(1); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->param()); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Inserts a %beta_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %beta_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType1>& __x); /** * @brief Extracts a %beta_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %beta_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two beta distributions have the same * parameters and the sequences that would be generated * are equal. */ template inline bool operator==(const __gnu_cxx::beta_distribution<_RealType>& __d1, const __gnu_cxx::beta_distribution<_RealType>& __d2) { return __d1.param() == __d2.param(); } /** * @brief Return true if two beta distributions are different. */ template inline bool operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, const __gnu_cxx::beta_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A multi-variate normal continuous distribution for random numbers. * * The formula for the normal probability density function is * @f[ * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} * @f] * * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance * matrix (which must be positive-definite). */ template class normal_mv_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ class param_type { static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; public: typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; friend class normal_mv_distribution<_Dimen, _RealType>; param_type() { std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); auto __it = _M_t.begin(); for (size_t __i = 0; __i < _Dimen; ++__i) { std::fill_n(__it, __i, _RealType(0)); __it += __i; *__it++ = _RealType(1); } } template param_type(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) { __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator2>) _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) <= _Dimen); const auto __dist = std::distance(__varcovbegin, __varcovend); _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen || __dist == _Dimen * (_Dimen + 1) / 2 || __dist == _Dimen); if (__dist == _Dimen * _Dimen) _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); else if (__dist == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); else _M_init_diagonal(__meanbegin, __meanend, __varcovbegin, __varcovend); } param_type(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) { _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen || __varcov.size() == _Dimen * (_Dimen + 1) / 2 || __varcov.size() == _Dimen); if (__varcov.size() == _Dimen * _Dimen) _M_init_full(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else _M_init_diagonal(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); } std::array<_RealType, _Dimen> mean() const { return _M_mean; } std::array<_RealType, _M_t_size> varcov() const { return _M_t; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } private: template void _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend); std::array<_RealType, _Dimen> _M_mean; std::array<_RealType, _M_t_size> _M_t; }; public: normal_mv_distribution() : _M_param(), _M_nd() { } template normal_mv_distribution(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), _M_nd() { } normal_mv_distribution(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) : _M_param(__mean, __varcov), _M_nd() { } explicit normal_mv_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the mean of the distribution. */ result_type mean() const { return _M_param.mean(); } /** * @brief Returns the compact form of the variance/covariance * matrix of the distribution. */ std::array<_RealType, _Dimen * (_Dimen + 1) / 2> varcov() const { return _M_param.varcov(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::min()); return __res; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::max()); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->param()); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { return this->__generate_impl(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { return this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two multi-variant normal distributions have * the same parameters and the sequences that would * be generated are equal. */ template friend bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d2); /** * @brief Inserts a %normal_mv_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %normal_mv_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %normal_mv_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %normal_mv_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two multi-variate normal distributions are * different. */ template inline bool operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Rice continuous distribution for random numbers. * * The formula for the Rice probability density function is * @f[ * p(x|\nu,\sigma) = \frac{x}{\sigma^2} * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) * I_0\left(\frac{x \nu}{\sigma^2}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$
Variance@f$2\sigma^2 + \nu^2 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$
Range@f$[0, \infty)@f$
* where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. */ template class rice_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef rice_distribution distribution_type; param_type(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_nu(__nu_val), _M_sigma(__sigma_val) { _GLIBCXX_DEBUG_ASSERT(_M_nu >= result_type(0)); _GLIBCXX_DEBUG_ASSERT(_M_sigma > result_type(0)); } result_type nu() const { return _M_nu; } result_type sigma() const { return _M_sigma; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; } private: void _M_initialize(); result_type _M_nu; result_type _M_sigma; }; /** * @brief Constructors. */ explicit rice_distribution(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_param(__nu_val, __sigma_val), _M_ndx(__nu_val, __sigma_val), _M_ndy(result_type(0), __sigma_val) { } explicit rice_distribution(const param_type& __p) : _M_param(__p), _M_ndx(__p.nu(), __p.sigma()), _M_ndy(result_type(0), __p.sigma()) { } /** * @brief Resets the distribution state. */ void reset() { _M_ndx.reset(); _M_ndy.reset(); } /** * @brief Return the parameters of the distribution. */ result_type nu() const { return _M_param.nu(); } result_type sigma() const { return _M_param.sigma(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ndx(__urng); result_type __y = this->_M_ndy(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::normal_distribution::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Rice distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const rice_distribution& __d1, const rice_distribution& __d2) { return (__d1.param() == __d2.param() && __d1._M_ndx == __d2._M_ndx && __d1._M_ndy == __d2._M_ndy); } /** * @brief Inserts a %rice_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %rice_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const rice_distribution<_RealType1>&); /** * @brief Extracts a %rice_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %rice_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, rice_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution _M_ndx; std::normal_distribution _M_ndy; }; /** * @brief Return true if two Rice distributions are not equal. */ template inline bool operator!=(const rice_distribution<_RealType1>& __d1, const rice_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A Nakagami continuous distribution for random numbers. * * The formula for the Nakagami probability density function is * @f[ * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} * x^{2\mu-1}e^{-\mu x / \omega} * @f] * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ * and @f$\omega > 0@f$. */ template class nakagami_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef nakagami_distribution distribution_type; param_type(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_mu(__mu_val), _M_omega(__omega_val) { _GLIBCXX_DEBUG_ASSERT(_M_mu >= result_type(0.5L)); _GLIBCXX_DEBUG_ASSERT(_M_omega > result_type(0)); } result_type mu() const { return _M_mu; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; } private: void _M_initialize(); result_type _M_mu; result_type _M_omega; }; /** * @brief Constructors. */ explicit nakagami_distribution(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_param(__mu_val, __omega_val), _M_gd(__mu_val, __omega_val / __mu_val) { } explicit nakagami_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.mu(), __p.omega() / __p.mu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * @brief Return the parameters of the distribution. */ result_type mu() const { return _M_param.mu(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return std::sqrt(this->_M_gd(__urng)); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution::param_type __pg(__p.mu(), __p.omega() / __p.mu()); return std::sqrt(this->_M_gd(__pg, __urng)); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Nakagami distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const nakagami_distribution& __d1, const nakagami_distribution& __d2) { return (__d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd); } /** * @brief Inserts a %nakagami_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %nakagami_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const nakagami_distribution<_RealType1>&); /** * @brief Extracts a %nakagami_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %nakagami_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, nakagami_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd; }; /** * @brief Return true if two Nakagami distributions are not equal. */ template inline bool operator!=(const nakagami_distribution<_RealType>& __d1, const nakagami_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Pareto continuous distribution for random numbers. * * The formula for the Pareto cumulative probability function is * @f[ * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha * @f] * The formula for the Pareto probability density function is * @f[ * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} * \left(\frac{\mu}{x}\right)^{\alpha + 1} * @f] * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\alpha \mu / (\alpha - 1)@f$ * for @f$\alpha > 1@f$
Variance@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ * for @f$\alpha > 2@f$
Range@f$[\mu, \infty)@f$
*/ template class pareto_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef pareto_distribution distribution_type; param_type(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_alpha(__alpha_val), _M_mu(__mu_val) { _GLIBCXX_DEBUG_ASSERT(_M_alpha > result_type(0)); _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0)); } result_type alpha() const { return _M_alpha; } result_type mu() const { return _M_mu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } private: void _M_initialize(); result_type _M_alpha; result_type _M_mu; }; /** * @brief Constructors. */ explicit pareto_distribution(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_param(__alpha_val, __mu_val), _M_ud() { } explicit pareto_distribution(const param_type& __p) : _M_param(__p), _M_ud() { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type alpha() const { return _M_param.alpha(); } result_type mu() const { return _M_param.mu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->mu(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->mu() * std::pow(this->_M_ud(__urng), -result_type(1) / this->alpha()); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { return __p.mu() * std::pow(this->_M_ud(__urng), -result_type(1) / __p.alpha()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Pareto distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const pareto_distribution& __d1, const pareto_distribution& __d2) { return (__d1.param() == __d2.param() && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %pareto_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %pareto_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const pareto_distribution<_RealType1>&); /** * @brief Extracts a %pareto_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %pareto_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, pareto_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution _M_ud; }; /** * @brief Return true if two Pareto distributions are not equal. */ template inline bool operator!=(const pareto_distribution<_RealType>& __d1, const pareto_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A K continuous distribution for random numbers. * * The formula for the K probability density function is * @f[ * p(x|\lambda, \mu, \nu) = \frac{2}{x} * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the second kind * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ * and @f$\nu > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\mu@f$
Variance@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$
Range@f$[0, \infty)@f$
*/ template class k_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef k_distribution distribution_type; param_type(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) { _GLIBCXX_DEBUG_ASSERT(_M_lambda > result_type(0)); _GLIBCXX_DEBUG_ASSERT(_M_mu > result_type(0)); _GLIBCXX_DEBUG_ASSERT(_M_nu > result_type(0)); } result_type lambda() const { return _M_lambda; } result_type mu() const { return _M_mu; } result_type nu() const { return _M_nu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_lambda == __p2._M_lambda && __p1._M_mu == __p2._M_mu && __p1._M_nu == __p2._M_nu; } private: void _M_initialize(); result_type _M_lambda; result_type _M_mu; result_type _M_nu; }; /** * @brief Constructors. */ explicit k_distribution(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_param(__lambda_val, __mu_val, __nu_val), _M_gd1(__lambda_val, result_type(1) / __lambda_val), _M_gd2(__nu_val, __mu_val / __nu_val) { } explicit k_distribution(const param_type& __p) : _M_param(__p), _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), _M_gd2(__p.nu(), __p.mu() / __p.nu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd1.reset(); _M_gd2.reset(); } /** * @brief Return the parameters of the distribution. */ result_type lambda() const { return _M_param.lambda(); } result_type mu() const { return _M_param.mu(); } result_type nu() const { return _M_param.nu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator&); template result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two K distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const k_distribution& __d1, const k_distribution& __d2) { return (__d1.param() == __d2.param() && __d1._M_gd1 == __d2._M_gd1 && __d1._M_gd2 == __d2._M_gd2); } /** * @brief Inserts a %k_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %k_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const k_distribution<_RealType1>&); /** * @brief Extracts a %k_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %k_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, k_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd1; std::gamma_distribution _M_gd2; }; /** * @brief Return true if two K distributions are not equal. */ template inline bool operator!=(const k_distribution<_RealType>& __d1, const k_distribution<_RealType>& __d2) { return !(__d1 == __d2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #include "opt_random.h" #include "random.tcc" #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // __GXX_EXPERIMENTAL_CXX0X__ #endif // _EXT_RANDOM