mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-02 18:53:22 +00:00
3120 lines
90 KiB
C++
3120 lines
90 KiB
C++
// Random number extensions -*- C++ -*-
|
|
|
|
// Copyright (C) 2012-2014 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
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
/** @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
|
|
|
|
#if __cplusplus < 201103L
|
|
# include <bits/c++0x_warning.h>
|
|
#else
|
|
|
|
#include <random>
|
|
#include <array>
|
|
#include <ext/cmath>
|
|
#ifdef __SSE2__
|
|
# include <x86intrin.h>
|
|
#endif
|
|
|
|
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
|
|
|
|
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|
|
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
/* Mersenne twister implementation optimized for vector operations.
|
|
*
|
|
* Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
|
|
*/
|
|
template<typename _UIntType, size_t __m,
|
|
size_t __pos1, size_t __sl1, size_t __sl2,
|
|
size_t __sr1, size_t __sr2,
|
|
uint32_t __msk1, uint32_t __msk2,
|
|
uint32_t __msk3, uint32_t __msk4,
|
|
uint32_t __parity1, uint32_t __parity2,
|
|
uint32_t __parity3, uint32_t __parity4>
|
|
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<typename _Sseq, typename = typename
|
|
std::enable_if<!std::is_same<_Sseq,
|
|
simd_fast_mersenne_twister_engine>::value>
|
|
::type>
|
|
explicit
|
|
simd_fast_mersenne_twister_engine(_Sseq& __q)
|
|
{ seed(__q); }
|
|
|
|
void
|
|
seed(result_type __sd = default_seed);
|
|
|
|
template<typename _Sseq>
|
|
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
|
seed(_Sseq& __q);
|
|
|
|
static constexpr result_type
|
|
min()
|
|
{ return 0; };
|
|
|
|
static constexpr result_type
|
|
max()
|
|
{ return std::numeric_limits<result_type>::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<typename _UIntType_2, size_t __m_2,
|
|
size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
|
|
size_t __sr1_2, size_t __sr2_2,
|
|
uint32_t __msk1_2, uint32_t __msk2_2,
|
|
uint32_t __msk3_2, uint32_t __msk4_2,
|
|
uint32_t __parity1_2, uint32_t __parity2_2,
|
|
uint32_t __parity3_2, uint32_t __parity4_2>
|
|
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<typename _UIntType_2, size_t __m_2,
|
|
size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
|
|
size_t __sr1_2, size_t __sr2_2,
|
|
uint32_t __msk1_2, uint32_t __msk2_2,
|
|
uint32_t __msk3_2, uint32_t __msk4_2,
|
|
uint32_t __parity1_2, uint32_t __parity2_2,
|
|
uint32_t __parity3_2, uint32_t __parity4_2,
|
|
typename _CharT, typename _Traits>
|
|
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<typename _UIntType_2, size_t __m_2,
|
|
size_t __pos1_2, size_t __sl1_2, size_t __sl2_2,
|
|
size_t __sr1_2, size_t __sr2_2,
|
|
uint32_t __msk1_2, uint32_t __msk2_2,
|
|
uint32_t __msk3_2, uint32_t __msk4_2,
|
|
uint32_t __parity1_2, uint32_t __parity2_2,
|
|
uint32_t __parity3_2, uint32_t __parity4_2,
|
|
typename _CharT, typename _Traits>
|
|
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<typename _UIntType, size_t __m,
|
|
size_t __pos1, size_t __sl1, size_t __sl2,
|
|
size_t __sr1, size_t __sr2,
|
|
uint32_t __msk1, uint32_t __msk2,
|
|
uint32_t __msk3, uint32_t __msk4,
|
|
uint32_t __parity1, uint32_t __parity2,
|
|
uint32_t __parity3, uint32_t __parity4>
|
|
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<uint32_t, 607, 2,
|
|
15, 3, 13, 3,
|
|
0xfdff37ffU, 0xef7f3f7dU,
|
|
0xff777b7dU, 0x7ff7fb2fU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x5986f054U>
|
|
sfmt607;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2,
|
|
15, 3, 13, 3,
|
|
0xfdff37ffU, 0xef7f3f7dU,
|
|
0xff777b7dU, 0x7ff7fb2fU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x5986f054U>
|
|
sfmt607_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7,
|
|
14, 3, 5, 1,
|
|
0xf7fefffdU, 0x7fefcfffU,
|
|
0xaff3ef3fU, 0xb5ffff7fU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x20000000U>
|
|
sfmt1279;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7,
|
|
14, 3, 5, 1,
|
|
0xf7fefffdU, 0x7fefcfffU,
|
|
0xaff3ef3fU, 0xb5ffff7fU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x20000000U>
|
|
sfmt1279_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12,
|
|
19, 1, 5, 1,
|
|
0xbff7ffbfU, 0xfdfffffeU,
|
|
0xf7ffef7fU, 0xf2f7cbbfU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x41dfa600U>
|
|
sfmt2281;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12,
|
|
19, 1, 5, 1,
|
|
0xbff7ffbfU, 0xfdfffffeU,
|
|
0xf7ffef7fU, 0xf2f7cbbfU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x41dfa600U>
|
|
sfmt2281_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17,
|
|
20, 1, 7, 1,
|
|
0x9f7bffffU, 0x9fffff5fU,
|
|
0x3efffffbU, 0xfffff7bbU,
|
|
0xa8000001U, 0xaf5390a3U,
|
|
0xb740b3f8U, 0x6c11486dU>
|
|
sfmt4253;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17,
|
|
20, 1, 7, 1,
|
|
0x9f7bffffU, 0x9fffff5fU,
|
|
0x3efffffbU, 0xfffff7bbU,
|
|
0xa8000001U, 0xaf5390a3U,
|
|
0xb740b3f8U, 0x6c11486dU>
|
|
sfmt4253_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68,
|
|
14, 3, 7, 3,
|
|
0xeffff7fbU, 0xffffffefU,
|
|
0xdfdfbfffU, 0x7fffdbfdU,
|
|
0x00000001U, 0x00000000U,
|
|
0xe8148000U, 0xd0c7afa3U>
|
|
sfmt11213;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68,
|
|
14, 3, 7, 3,
|
|
0xeffff7fbU, 0xffffffefU,
|
|
0xdfdfbfffU, 0x7fffdbfdU,
|
|
0x00000001U, 0x00000000U,
|
|
0xe8148000U, 0xd0c7afa3U>
|
|
sfmt11213_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122,
|
|
18, 1, 11, 1,
|
|
0xdfffffefU, 0xddfecb7fU,
|
|
0xbffaffffU, 0xbffffff6U,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x13c9e684U>
|
|
sfmt19937;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122,
|
|
18, 1, 11, 1,
|
|
0xdfffffefU, 0xddfecb7fU,
|
|
0xbffaffffU, 0xbffffff6U,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0x13c9e684U>
|
|
sfmt19937_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330,
|
|
5, 3, 9, 3,
|
|
0xeffffffbU, 0xdfbebfffU,
|
|
0xbfbf7befU, 0x9ffd7bffU,
|
|
0x00000001U, 0x00000000U,
|
|
0xa3ac4000U, 0xecc1327aU>
|
|
sfmt44497;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330,
|
|
5, 3, 9, 3,
|
|
0xeffffffbU, 0xdfbebfffU,
|
|
0xbfbf7befU, 0x9ffd7bffU,
|
|
0x00000001U, 0x00000000U,
|
|
0xa3ac4000U, 0xecc1327aU>
|
|
sfmt44497_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366,
|
|
6, 7, 19, 1,
|
|
0xfdbffbffU, 0xbff7ff3fU,
|
|
0xfd77efffU, 0xbf9ff3ffU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0xe9528d85U>
|
|
sfmt86243;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366,
|
|
6, 7, 19, 1,
|
|
0xfdbffbffU, 0xbff7ff3fU,
|
|
0xfd77efffU, 0xbf9ff3ffU,
|
|
0x00000001U, 0x00000000U,
|
|
0x00000000U, 0xe9528d85U>
|
|
sfmt86243_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110,
|
|
19, 1, 21, 1,
|
|
0xffffbb5fU, 0xfb6ebf95U,
|
|
0xfffefffaU, 0xcff77fffU,
|
|
0x00000001U, 0x00000000U,
|
|
0xcb520000U, 0xc7e91c7dU>
|
|
sfmt132049;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110,
|
|
19, 1, 21, 1,
|
|
0xffffbb5fU, 0xfb6ebf95U,
|
|
0xfffefffaU, 0xcff77fffU,
|
|
0x00000001U, 0x00000000U,
|
|
0xcb520000U, 0xc7e91c7dU>
|
|
sfmt132049_64;
|
|
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627,
|
|
11, 3, 10, 1,
|
|
0xbff7bff7U, 0xbfffffffU,
|
|
0xbffffa7fU, 0xffddfbfbU,
|
|
0xf8000001U, 0x89e80709U,
|
|
0x3bd2b64bU, 0x0c64b1e4U>
|
|
sfmt216091;
|
|
|
|
typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627,
|
|
11, 3, 10, 1,
|
|
0xbff7bff7U, 0xbfffffffU,
|
|
0xbffffa7fU, 0xffddfbfbU,
|
|
0xf8000001U, 0x89e80709U,
|
|
0x3bd2b64bU, 0x0c64b1e4U>
|
|
sfmt216091_64;
|
|
|
|
#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
|
|
/**
|
|
* @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<typename _RealType = double>
|
|
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<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return this->operator()(__urng, _M_param); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 beta distributions have the same
|
|
* parameters and the sequences that would be generated
|
|
* are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const beta_distribution& __d1,
|
|
const beta_distribution& __d2)
|
|
{ return __d1._M_param == __d2._M_param; }
|
|
|
|
/**
|
|
* @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<typename _RealType1, typename _CharT, typename _Traits>
|
|
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<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>& __is,
|
|
__gnu_cxx::beta_distribution<_RealType1>& __x);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two beta distributions are different.
|
|
*/
|
|
template<typename _RealType>
|
|
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<std::size_t _Dimen, typename _RealType = double>
|
|
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<typename _ForwardIterator1, typename _ForwardIterator2>
|
|
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 <typename _InputIterator1, typename _InputIterator2>
|
|
void _M_init_full(_InputIterator1 __meanbegin,
|
|
_InputIterator1 __meanend,
|
|
_InputIterator2 __varcovbegin,
|
|
_InputIterator2 __varcovend);
|
|
template <typename _InputIterator1, typename _InputIterator2>
|
|
void _M_init_lower(_InputIterator1 __meanbegin,
|
|
_InputIterator1 __meanend,
|
|
_InputIterator2 __varcovbegin,
|
|
_InputIterator2 __varcovend);
|
|
template <typename _InputIterator1, typename _InputIterator2>
|
|
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<typename _ForwardIterator1, typename _ForwardIterator2>
|
|
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>::lowest());
|
|
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<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return this->operator()(__urng, _M_param); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ return this->__generate_impl(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
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<size_t _Dimen1, typename _RealType1>
|
|
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<size_t _Dimen1, typename _RealType1,
|
|
typename _CharT, typename _Traits>
|
|
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<size_t _Dimen1, typename _RealType1,
|
|
typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>& __is,
|
|
__gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
|
|
__x);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
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<size_t _Dimen, typename _RealType>
|
|
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$.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2
|
|
* + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
|
|
* </table>
|
|
* where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2.
|
|
*/
|
|
template<typename _RealType = double>
|
|
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<result_type> 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<result_type>::max(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
typename std::normal_distribution<result_type>::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<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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._M_param == __d2._M_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<typename _RealType1, typename _CharT, typename _Traits>
|
|
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<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
rice_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
std::normal_distribution<result_type> _M_ndx;
|
|
std::normal_distribution<result_type> _M_ndy;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two Rice distributions are not equal.
|
|
*/
|
|
template<typename _RealType1>
|
|
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<typename _RealType = double>
|
|
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<result_type> 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<result_type>::max(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return std::sqrt(this->_M_gd(__urng)); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
typename std::gamma_distribution<result_type>::param_type
|
|
__pg(__p.mu(), __p.omega() / __p.mu());
|
|
return std::sqrt(this->_M_gd(__pg, __urng));
|
|
}
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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._M_param == __d2._M_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<typename _RealType1, typename _CharT, typename _Traits>
|
|
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<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
nakagami_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
std::gamma_distribution<result_type> _M_gd;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two Nakagami distributions are not equal.
|
|
*/
|
|
template<typename _RealType>
|
|
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$.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$
|
|
* for @f$\alpha > 1@f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$
|
|
* for @f$\alpha > 2@f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _RealType = double>
|
|
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<result_type> 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<result_type>::max(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{
|
|
return this->mu() * std::pow(this->_M_ud(__urng),
|
|
-result_type(1) / this->alpha());
|
|
}
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
return __p.mu() * std::pow(this->_M_ud(__urng),
|
|
-result_type(1) / __p.alpha());
|
|
}
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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._M_param == __d2._M_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<typename _RealType1, typename _CharT, typename _Traits>
|
|
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<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
pareto_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
std::uniform_real_distribution<result_type> _M_ud;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two Pareto distributions are not equal.
|
|
*/
|
|
template<typename _RealType>
|
|
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$.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$\mu@f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _RealType = double>
|
|
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<result_type> 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<result_type>::max(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator&);
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator&, const param_type&);
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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._M_param == __d2._M_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<typename _RealType1, typename _CharT, typename _Traits>
|
|
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<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
k_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
std::gamma_distribution<result_type> _M_gd1;
|
|
std::gamma_distribution<result_type> _M_gd2;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two K distributions are not equal.
|
|
*/
|
|
template<typename _RealType>
|
|
inline bool
|
|
operator!=(const k_distribution<_RealType>& __d1,
|
|
const k_distribution<_RealType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
|
|
/**
|
|
* @brief An arcsine continuous distribution for random numbers.
|
|
*
|
|
* The formula for the arcsine probability density function is
|
|
* @f[
|
|
* p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}}
|
|
* @f]
|
|
* where @f$x >= a@f$ and @f$x <= b@f$.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[a, b]@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _RealType = double>
|
|
class
|
|
arcsine_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 arcsine_distribution<result_type> distribution_type;
|
|
|
|
param_type(result_type __a = result_type(0),
|
|
result_type __b = result_type(1))
|
|
: _M_a(__a), _M_b(__b)
|
|
{
|
|
_GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
|
|
}
|
|
|
|
result_type
|
|
a() const
|
|
{ return _M_a; }
|
|
|
|
result_type
|
|
b() const
|
|
{ return _M_b; }
|
|
|
|
friend bool
|
|
operator==(const param_type& __p1, const param_type& __p2)
|
|
{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
|
|
|
|
private:
|
|
void _M_initialize();
|
|
|
|
result_type _M_a;
|
|
result_type _M_b;
|
|
};
|
|
|
|
/**
|
|
* @brief Constructors.
|
|
*/
|
|
explicit
|
|
arcsine_distribution(result_type __a = result_type(0),
|
|
result_type __b = result_type(1))
|
|
: _M_param(__a, __b),
|
|
_M_ud(-1.5707963267948966192313216916397514L,
|
|
+1.5707963267948966192313216916397514L)
|
|
{ }
|
|
|
|
explicit
|
|
arcsine_distribution(const param_type& __p)
|
|
: _M_param(__p),
|
|
_M_ud(-1.5707963267948966192313216916397514L,
|
|
+1.5707963267948966192313216916397514L)
|
|
{ }
|
|
|
|
/**
|
|
* @brief Resets the distribution state.
|
|
*/
|
|
void
|
|
reset()
|
|
{ _M_ud.reset(); }
|
|
|
|
/**
|
|
* @brief Return the parameters of the distribution.
|
|
*/
|
|
result_type
|
|
a() const
|
|
{ return _M_param.a(); }
|
|
|
|
result_type
|
|
b() const
|
|
{ return _M_param.b(); }
|
|
|
|
/**
|
|
* @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->a(); }
|
|
|
|
/**
|
|
* @brief Returns the least upper bound value of the distribution.
|
|
*/
|
|
result_type
|
|
max() const
|
|
{ return this->b(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{
|
|
result_type __x = std::sin(this->_M_ud(__urng));
|
|
return (__x * (this->b() - this->a())
|
|
+ this->a() + this->b()) / result_type(2);
|
|
}
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
result_type __x = std::sin(this->_M_ud(__urng));
|
|
return (__x * (__p.b() - __p.a())
|
|
+ __p.a() + __p.b()) / result_type(2);
|
|
}
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 arcsine distributions have
|
|
* the same parameters and the sequences that would
|
|
* be generated are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const arcsine_distribution& __d1,
|
|
const arcsine_distribution& __d2)
|
|
{ return (__d1._M_param == __d2._M_param
|
|
&& __d1._M_ud == __d2._M_ud); }
|
|
|
|
/**
|
|
* @brief Inserts a %arcsine_distribution random number distribution
|
|
* @p __x into the output stream @p __os.
|
|
*
|
|
* @param __os An output stream.
|
|
* @param __x A %arcsine_distribution random number distribution.
|
|
*
|
|
* @returns The output stream with the state of @p __x inserted or in
|
|
* an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_ostream<_CharT, _Traits>&
|
|
operator<<(std::basic_ostream<_CharT, _Traits>&,
|
|
const arcsine_distribution<_RealType1>&);
|
|
|
|
/**
|
|
* @brief Extracts a %arcsine_distribution random number distribution
|
|
* @p __x from the input stream @p __is.
|
|
*
|
|
* @param __is An input stream.
|
|
* @param __x A %arcsine_distribution random number
|
|
* generator engine.
|
|
*
|
|
* @returns The input stream with @p __x extracted or in an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
arcsine_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
std::uniform_real_distribution<result_type> _M_ud;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two arcsine distributions are not equal.
|
|
*/
|
|
template<typename _RealType>
|
|
inline bool
|
|
operator!=(const arcsine_distribution<_RealType>& __d1,
|
|
const arcsine_distribution<_RealType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
|
|
/**
|
|
* @brief A Hoyt continuous distribution for random numbers.
|
|
*
|
|
* The formula for the Hoyt probability density function is
|
|
* @f[
|
|
* p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega}
|
|
* \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right)
|
|
* I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right)
|
|
* @f]
|
|
* where @f$I_0(z)@f$ is the modified Bessel function of the first kind
|
|
* of order 0 and @f$0 < q < 1@f$.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}}
|
|
* E(1 - q^2) @f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)}
|
|
* {\pi (1 + q^2)}\right) @f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr>
|
|
* </table>
|
|
* where @f$E(x)@f$ is the elliptic function of the second kind.
|
|
*/
|
|
template<typename _RealType = double>
|
|
class
|
|
hoyt_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 hoyt_distribution<result_type> distribution_type;
|
|
|
|
param_type(result_type __q = result_type(0.5L),
|
|
result_type __omega = result_type(1))
|
|
: _M_q(__q), _M_omega(__omega)
|
|
{
|
|
_GLIBCXX_DEBUG_ASSERT(_M_q > result_type(0));
|
|
_GLIBCXX_DEBUG_ASSERT(_M_q < result_type(1));
|
|
}
|
|
|
|
result_type
|
|
q() const
|
|
{ return _M_q; }
|
|
|
|
result_type
|
|
omega() const
|
|
{ return _M_omega; }
|
|
|
|
friend bool
|
|
operator==(const param_type& __p1, const param_type& __p2)
|
|
{ return __p1._M_q == __p2._M_q
|
|
&& __p1._M_omega == __p2._M_omega; }
|
|
|
|
private:
|
|
void _M_initialize();
|
|
|
|
result_type _M_q;
|
|
result_type _M_omega;
|
|
};
|
|
|
|
/**
|
|
* @brief Constructors.
|
|
*/
|
|
explicit
|
|
hoyt_distribution(result_type __q = result_type(0.5L),
|
|
result_type __omega = result_type(1))
|
|
: _M_param(__q, __omega),
|
|
_M_ad(result_type(0.5L) * (result_type(1) + __q * __q),
|
|
result_type(0.5L) * (result_type(1) + __q * __q)
|
|
/ (__q * __q)),
|
|
_M_ed(result_type(1))
|
|
{ }
|
|
|
|
explicit
|
|
hoyt_distribution(const param_type& __p)
|
|
: _M_param(__p),
|
|
_M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()),
|
|
result_type(0.5L) * (result_type(1) + __p.q() * __p.q())
|
|
/ (__p.q() * __p.q())),
|
|
_M_ed(result_type(1))
|
|
{ }
|
|
|
|
/**
|
|
* @brief Resets the distribution state.
|
|
*/
|
|
void
|
|
reset()
|
|
{
|
|
_M_ad.reset();
|
|
_M_ed.reset();
|
|
}
|
|
|
|
/**
|
|
* @brief Return the parameters of the distribution.
|
|
*/
|
|
result_type
|
|
q() const
|
|
{ return _M_param.q(); }
|
|
|
|
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<result_type>::max(); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng);
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 Hoyt distributions have
|
|
* the same parameters and the sequences that would
|
|
* be generated are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const hoyt_distribution& __d1,
|
|
const hoyt_distribution& __d2)
|
|
{ return (__d1._M_param == __d2._M_param
|
|
&& __d1._M_ad == __d2._M_ad
|
|
&& __d1._M_ed == __d2._M_ed); }
|
|
|
|
/**
|
|
* @brief Inserts a %hoyt_distribution random number distribution
|
|
* @p __x into the output stream @p __os.
|
|
*
|
|
* @param __os An output stream.
|
|
* @param __x A %hoyt_distribution random number distribution.
|
|
*
|
|
* @returns The output stream with the state of @p __x inserted or in
|
|
* an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_ostream<_CharT, _Traits>&
|
|
operator<<(std::basic_ostream<_CharT, _Traits>&,
|
|
const hoyt_distribution<_RealType1>&);
|
|
|
|
/**
|
|
* @brief Extracts a %hoyt_distribution random number distribution
|
|
* @p __x from the input stream @p __is.
|
|
*
|
|
* @param __is An input stream.
|
|
* @param __x A %hoyt_distribution random number
|
|
* generator engine.
|
|
*
|
|
* @returns The input stream with @p __x extracted or in an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>&,
|
|
hoyt_distribution<_RealType1>&);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
|
|
__gnu_cxx::arcsine_distribution<result_type> _M_ad;
|
|
std::exponential_distribution<result_type> _M_ed;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two Hoyt distributions are not equal.
|
|
*/
|
|
template<typename _RealType>
|
|
inline bool
|
|
operator!=(const hoyt_distribution<_RealType>& __d1,
|
|
const hoyt_distribution<_RealType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
|
|
/**
|
|
* @brief A triangular distribution for random numbers.
|
|
*
|
|
* The formula for the triangular probability density function is
|
|
* @f[
|
|
* / 0 for x < a
|
|
* p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b
|
|
* | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c
|
|
* \ 0 for c < x
|
|
* @f]
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc}
|
|
* {18}@f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[a, c]@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _RealType = double>
|
|
class triangular_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
|
|
{
|
|
friend class triangular_distribution<_RealType>;
|
|
|
|
explicit
|
|
param_type(_RealType __a = _RealType(0),
|
|
_RealType __b = _RealType(0.5),
|
|
_RealType __c = _RealType(1))
|
|
: _M_a(__a), _M_b(__b), _M_c(__c)
|
|
{
|
|
_GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
|
|
_GLIBCXX_DEBUG_ASSERT(_M_b <= _M_c);
|
|
_GLIBCXX_DEBUG_ASSERT(_M_a < _M_c);
|
|
|
|
_M_r_ab = (_M_b - _M_a) / (_M_c - _M_a);
|
|
_M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a);
|
|
_M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a);
|
|
}
|
|
|
|
_RealType
|
|
a() const
|
|
{ return _M_a; }
|
|
|
|
_RealType
|
|
b() const
|
|
{ return _M_b; }
|
|
|
|
_RealType
|
|
c() const
|
|
{ return _M_c; }
|
|
|
|
friend bool
|
|
operator==(const param_type& __p1, const param_type& __p2)
|
|
{ return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b
|
|
&& __p1._M_c == __p2._M_c); }
|
|
|
|
private:
|
|
|
|
_RealType _M_a;
|
|
_RealType _M_b;
|
|
_RealType _M_c;
|
|
_RealType _M_r_ab;
|
|
_RealType _M_f_ab_ac;
|
|
_RealType _M_f_bc_ac;
|
|
};
|
|
|
|
/**
|
|
* @brief Constructs a triangle distribution with parameters
|
|
* @f$ a @f$, @f$ b @f$ and @f$ c @f$.
|
|
*/
|
|
explicit
|
|
triangular_distribution(result_type __a = result_type(0),
|
|
result_type __b = result_type(0.5),
|
|
result_type __c = result_type(1))
|
|
: _M_param(__a, __b, __c)
|
|
{ }
|
|
|
|
explicit
|
|
triangular_distribution(const param_type& __p)
|
|
: _M_param(__p)
|
|
{ }
|
|
|
|
/**
|
|
* @brief Resets the distribution state.
|
|
*/
|
|
void
|
|
reset()
|
|
{ }
|
|
|
|
/**
|
|
* @brief Returns the @f$ a @f$ of the distribution.
|
|
*/
|
|
result_type
|
|
a() const
|
|
{ return _M_param.a(); }
|
|
|
|
/**
|
|
* @brief Returns the @f$ b @f$ of the distribution.
|
|
*/
|
|
result_type
|
|
b() const
|
|
{ return _M_param.b(); }
|
|
|
|
/**
|
|
* @brief Returns the @f$ c @f$ of the distribution.
|
|
*/
|
|
result_type
|
|
c() const
|
|
{ return _M_param.c(); }
|
|
|
|
/**
|
|
* @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 _M_param._M_a; }
|
|
|
|
/**
|
|
* @brief Returns the least upper bound value of the distribution.
|
|
*/
|
|
result_type
|
|
max() const
|
|
{ return _M_param._M_c; }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return this->operator()(__urng, _M_param); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
|
|
__aurng(__urng);
|
|
result_type __rnd = __aurng();
|
|
if (__rnd <= __p._M_r_ab)
|
|
return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac);
|
|
else
|
|
return __p.c() - std::sqrt((result_type(1) - __rnd)
|
|
* __p._M_f_bc_ac);
|
|
}
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 triangle distributions have the same
|
|
* parameters and the sequences that would be generated
|
|
* are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const triangular_distribution& __d1,
|
|
const triangular_distribution& __d2)
|
|
{ return __d1._M_param == __d2._M_param; }
|
|
|
|
/**
|
|
* @brief Inserts a %triangular_distribution random number distribution
|
|
* @p __x into the output stream @p __os.
|
|
*
|
|
* @param __os An output stream.
|
|
* @param __x A %triangular_distribution random number distribution.
|
|
*
|
|
* @returns The output stream with the state of @p __x inserted or in
|
|
* an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_ostream<_CharT, _Traits>&
|
|
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
|
const __gnu_cxx::triangular_distribution<_RealType1>& __x);
|
|
|
|
/**
|
|
* @brief Extracts a %triangular_distribution random number distribution
|
|
* @p __x from the input stream @p __is.
|
|
*
|
|
* @param __is An input stream.
|
|
* @param __x A %triangular_distribution random number generator engine.
|
|
*
|
|
* @returns The input stream with @p __x extracted or in an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>& __is,
|
|
__gnu_cxx::triangular_distribution<_RealType1>& __x);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two triangle distributions are different.
|
|
*/
|
|
template<typename _RealType>
|
|
inline bool
|
|
operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
|
|
const __gnu_cxx::triangular_distribution<_RealType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
|
|
/**
|
|
* @brief A von Mises distribution for random numbers.
|
|
*
|
|
* The formula for the von Mises probability density function is
|
|
* @f[
|
|
* p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}}
|
|
* {2\pi I_0(\kappa)}
|
|
* @f]
|
|
*
|
|
* The generating functions use the method according to:
|
|
*
|
|
* D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the
|
|
* von Mises Distribution", Journal of the Royal Statistical Society.
|
|
* Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$ \mu @f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _RealType = double>
|
|
class von_mises_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
|
|
{
|
|
friend class von_mises_distribution<_RealType>;
|
|
|
|
explicit
|
|
param_type(_RealType __mu = _RealType(0),
|
|
_RealType __kappa = _RealType(1))
|
|
: _M_mu(__mu), _M_kappa(__kappa)
|
|
{
|
|
const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi;
|
|
_GLIBCXX_DEBUG_ASSERT(_M_mu >= -__pi && _M_mu <= __pi);
|
|
_GLIBCXX_DEBUG_ASSERT(_M_kappa >= _RealType(0));
|
|
|
|
auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa
|
|
+ _RealType(1)) + _RealType(1);
|
|
auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau))
|
|
/ (_RealType(2) * _M_kappa));
|
|
_M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho);
|
|
}
|
|
|
|
_RealType
|
|
mu() const
|
|
{ return _M_mu; }
|
|
|
|
_RealType
|
|
kappa() const
|
|
{ return _M_kappa; }
|
|
|
|
friend bool
|
|
operator==(const param_type& __p1, const param_type& __p2)
|
|
{ return (__p1._M_mu == __p2._M_mu
|
|
&& __p1._M_kappa == __p2._M_kappa); }
|
|
|
|
private:
|
|
_RealType _M_mu;
|
|
_RealType _M_kappa;
|
|
_RealType _M_r;
|
|
};
|
|
|
|
/**
|
|
* @brief Constructs a von Mises distribution with parameters
|
|
* @f$\mu@f$ and @f$\kappa@f$.
|
|
*/
|
|
explicit
|
|
von_mises_distribution(result_type __mu = result_type(0),
|
|
result_type __kappa = result_type(1))
|
|
: _M_param(__mu, __kappa)
|
|
{ }
|
|
|
|
explicit
|
|
von_mises_distribution(const param_type& __p)
|
|
: _M_param(__p)
|
|
{ }
|
|
|
|
/**
|
|
* @brief Resets the distribution state.
|
|
*/
|
|
void
|
|
reset()
|
|
{ }
|
|
|
|
/**
|
|
* @brief Returns the @f$ \mu @f$ of the distribution.
|
|
*/
|
|
result_type
|
|
mu() const
|
|
{ return _M_param.mu(); }
|
|
|
|
/**
|
|
* @brief Returns the @f$ \kappa @f$ of the distribution.
|
|
*/
|
|
result_type
|
|
kappa() const
|
|
{ return _M_param.kappa(); }
|
|
|
|
/**
|
|
* @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 -__gnu_cxx::__math_constants<result_type>::__pi;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the least upper bound value of the distribution.
|
|
*/
|
|
result_type
|
|
max() const
|
|
{
|
|
return __gnu_cxx::__math_constants<result_type>::__pi;
|
|
}
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return this->operator()(__urng, _M_param); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{
|
|
const result_type __pi
|
|
= __gnu_cxx::__math_constants<result_type>::__pi;
|
|
std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
|
|
__aurng(__urng);
|
|
|
|
result_type __f;
|
|
while (1)
|
|
{
|
|
result_type __rnd = std::cos(__pi * __aurng());
|
|
__f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd);
|
|
result_type __c = __p._M_kappa * (__p._M_r - __f);
|
|
|
|
result_type __rnd2 = __aurng();
|
|
if (__c * (result_type(2) - __c) > __rnd2)
|
|
break;
|
|
if (std::log(__c / __rnd2) >= __c - result_type(1))
|
|
break;
|
|
}
|
|
|
|
result_type __res = std::acos(__f);
|
|
#if _GLIBCXX_USE_C99_MATH_TR1
|
|
__res = std::copysign(__res, __aurng() - result_type(0.5));
|
|
#else
|
|
if (__aurng() < result_type(0.5))
|
|
__res = -__res;
|
|
#endif
|
|
__res += __p._M_mu;
|
|
if (__res > __pi)
|
|
__res -= result_type(2) * __pi;
|
|
else if (__res < -__pi)
|
|
__res += result_type(2) * __pi;
|
|
return __res;
|
|
}
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, _M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 von Mises distributions have the same
|
|
* parameters and the sequences that would be generated
|
|
* are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const von_mises_distribution& __d1,
|
|
const von_mises_distribution& __d2)
|
|
{ return __d1._M_param == __d2._M_param; }
|
|
|
|
/**
|
|
* @brief Inserts a %von_mises_distribution random number distribution
|
|
* @p __x into the output stream @p __os.
|
|
*
|
|
* @param __os An output stream.
|
|
* @param __x A %von_mises_distribution random number distribution.
|
|
*
|
|
* @returns The output stream with the state of @p __x inserted or in
|
|
* an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_ostream<_CharT, _Traits>&
|
|
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
|
const __gnu_cxx::von_mises_distribution<_RealType1>& __x);
|
|
|
|
/**
|
|
* @brief Extracts a %von_mises_distribution random number distribution
|
|
* @p __x from the input stream @p __is.
|
|
*
|
|
* @param __is An input stream.
|
|
* @param __x A %von_mises_distribution random number generator engine.
|
|
*
|
|
* @returns The input stream with @p __x extracted or in an error state.
|
|
*/
|
|
template<typename _RealType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>& __is,
|
|
__gnu_cxx::von_mises_distribution<_RealType1>& __x);
|
|
|
|
private:
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two von Mises distributions are different.
|
|
*/
|
|
template<typename _RealType>
|
|
inline bool
|
|
operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
|
|
const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
|
|
/**
|
|
* @brief A discrete hypergeometric random number distribution.
|
|
*
|
|
* The hypergeometric distribution is a discrete probability distribution
|
|
* that describes the probability of @p k successes in @p n draws @a without
|
|
* replacement from a finite population of size @p N containing exactly @p K
|
|
* successes.
|
|
*
|
|
* The formula for the hypergeometric probability density function is
|
|
* @f[
|
|
* p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}}
|
|
* @f]
|
|
* where @f$N@f$ is the total population of the distribution,
|
|
* @f$K@f$ is the total population of the distribution.
|
|
*
|
|
* <table border=1 cellpadding=10 cellspacing=0>
|
|
* <caption align=top>Distribution Statistics</caption>
|
|
* <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr>
|
|
* <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1}
|
|
* @f$</td></tr>
|
|
* <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr>
|
|
* </table>
|
|
*/
|
|
template<typename _UIntType = unsigned int>
|
|
class hypergeometric_distribution
|
|
{
|
|
static_assert(std::is_unsigned<_UIntType>::value, "template argument "
|
|
"substituting _UIntType not an unsigned integral type");
|
|
|
|
public:
|
|
/** The type of the range of the distribution. */
|
|
typedef _UIntType result_type;
|
|
|
|
/** Parameter type. */
|
|
struct param_type
|
|
{
|
|
typedef hypergeometric_distribution<_UIntType> distribution_type;
|
|
friend class hypergeometric_distribution<_UIntType>;
|
|
|
|
explicit
|
|
param_type(result_type __N = 10, result_type __K = 5,
|
|
result_type __n = 1)
|
|
: _M_N{__N}, _M_K{__K}, _M_n{__n}
|
|
{
|
|
_GLIBCXX_DEBUG_ASSERT(_M_N >= _M_K);
|
|
_GLIBCXX_DEBUG_ASSERT(_M_N >= _M_n);
|
|
}
|
|
|
|
result_type
|
|
total_size() const
|
|
{ return _M_N; }
|
|
|
|
result_type
|
|
successful_size() const
|
|
{ return _M_K; }
|
|
|
|
result_type
|
|
unsuccessful_size() const
|
|
{ return _M_N - _M_K; }
|
|
|
|
result_type
|
|
total_draws() const
|
|
{ return _M_n; }
|
|
|
|
friend bool
|
|
operator==(const param_type& __p1, const param_type& __p2)
|
|
{ return (__p1._M_N == __p2._M_N)
|
|
&& (__p1._M_K == __p2._M_K)
|
|
&& (__p1._M_n == __p2._M_n); }
|
|
|
|
private:
|
|
|
|
result_type _M_N;
|
|
result_type _M_K;
|
|
result_type _M_n;
|
|
};
|
|
|
|
// constructors and member function
|
|
explicit
|
|
hypergeometric_distribution(result_type __N = 10, result_type __K = 5,
|
|
result_type __n = 1)
|
|
: _M_param{__N, __K, __n}
|
|
{ }
|
|
|
|
explicit
|
|
hypergeometric_distribution(const param_type& __p)
|
|
: _M_param{__p}
|
|
{ }
|
|
|
|
/**
|
|
* @brief Resets the distribution state.
|
|
*/
|
|
void
|
|
reset()
|
|
{ }
|
|
|
|
/**
|
|
* @brief Returns the distribution parameter @p N,
|
|
* the total number of items.
|
|
*/
|
|
result_type
|
|
total_size() const
|
|
{ return this->_M_param.total_size(); }
|
|
|
|
/**
|
|
* @brief Returns the distribution parameter @p K,
|
|
* the total number of successful items.
|
|
*/
|
|
result_type
|
|
successful_size() const
|
|
{ return this->_M_param.successful_size(); }
|
|
|
|
/**
|
|
* @brief Returns the total number of unsuccessful items @f$ N - K @f$.
|
|
*/
|
|
result_type
|
|
unsuccessful_size() const
|
|
{ return this->_M_param.unsuccessful_size(); }
|
|
|
|
/**
|
|
* @brief Returns the distribution parameter @p n,
|
|
* the total number of draws.
|
|
*/
|
|
result_type
|
|
total_draws() const
|
|
{ return this->_M_param.total_draws(); }
|
|
|
|
/**
|
|
* @brief Returns the parameter set of the distribution.
|
|
*/
|
|
param_type
|
|
param() const
|
|
{ return this->_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)
|
|
{ this->_M_param = __param; }
|
|
|
|
/**
|
|
* @brief Returns the greatest lower bound value of the distribution.
|
|
*/
|
|
result_type
|
|
min() const
|
|
{
|
|
using _IntType = typename std::make_signed<result_type>::type;
|
|
return static_cast<result_type>(std::max(static_cast<_IntType>(0),
|
|
static_cast<_IntType>(this->total_draws()
|
|
- this->unsuccessful_size())));
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the least upper bound value of the distribution.
|
|
*/
|
|
result_type
|
|
max() const
|
|
{ return std::min(this->successful_size(), this->total_draws()); }
|
|
|
|
/**
|
|
* @brief Generating functions.
|
|
*/
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng)
|
|
{ return this->operator()(__urng, this->_M_param); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
result_type
|
|
operator()(_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng)
|
|
{ this->__generate(__f, __t, __urng, this->_M_param); }
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p)
|
|
{ this->__generate_impl(__f, __t, __urng, __p); }
|
|
|
|
template<typename _UniformRandomNumberGenerator>
|
|
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 hypergeometric distributions have the same
|
|
* parameters and the sequences that would be generated
|
|
* are equal.
|
|
*/
|
|
friend bool
|
|
operator==(const hypergeometric_distribution& __d1,
|
|
const hypergeometric_distribution& __d2)
|
|
{ return __d1._M_param == __d2._M_param; }
|
|
|
|
/**
|
|
* @brief Inserts a %hypergeometric_distribution random number
|
|
* distribution @p __x into the output stream @p __os.
|
|
*
|
|
* @param __os An output stream.
|
|
* @param __x A %hypergeometric_distribution random number
|
|
* distribution.
|
|
*
|
|
* @returns The output stream with the state of @p __x inserted or in
|
|
* an error state.
|
|
*/
|
|
template<typename _UIntType1, typename _CharT, typename _Traits>
|
|
friend std::basic_ostream<_CharT, _Traits>&
|
|
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
|
|
const __gnu_cxx::hypergeometric_distribution<_UIntType1>&
|
|
__x);
|
|
|
|
/**
|
|
* @brief Extracts a %hypergeometric_distribution random number
|
|
* distribution @p __x from the input stream @p __is.
|
|
*
|
|
* @param __is An input stream.
|
|
* @param __x A %hypergeometric_distribution random number generator
|
|
* distribution.
|
|
*
|
|
* @returns The input stream with @p __x extracted or in an error
|
|
* state.
|
|
*/
|
|
template<typename _UIntType1, typename _CharT, typename _Traits>
|
|
friend std::basic_istream<_CharT, _Traits>&
|
|
operator>>(std::basic_istream<_CharT, _Traits>& __is,
|
|
__gnu_cxx::hypergeometric_distribution<_UIntType1>& __x);
|
|
|
|
private:
|
|
|
|
template<typename _ForwardIterator,
|
|
typename _UniformRandomNumberGenerator>
|
|
void
|
|
__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
|
|
_UniformRandomNumberGenerator& __urng,
|
|
const param_type& __p);
|
|
|
|
param_type _M_param;
|
|
};
|
|
|
|
/**
|
|
* @brief Return true if two hypergeometric distributions are different.
|
|
*/
|
|
template<typename _UIntType>
|
|
inline bool
|
|
operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
|
|
const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
|
|
{ return !(__d1 == __d2); }
|
|
|
|
_GLIBCXX_END_NAMESPACE_VERSION
|
|
} // namespace __gnu_cxx
|
|
|
|
#include "ext/opt_random.h"
|
|
#include "random.tcc"
|
|
|
|
#endif // _GLIBCXX_USE_C99_STDINT_TR1
|
|
|
|
#endif // C++11
|
|
|
|
#endif // _EXT_RANDOM
|