32 #ifndef VSMC_RNG_NORMAL_DISTRIBUTION_HPP 33 #define VSMC_RNG_NORMAL_DISTRIBUTION_HPP 45 template <
typename RealType>
55 template <
typename RealType>
62 result_type min()
const 64 return std::numeric_limits<result_type>::lowest();
76 template <
typename RNGType>
99 template <std::
size_t K,
typename RealType,
typename RNGType>
101 RNGType &rng, std::size_t n, RealType *r, RealType mean, RealType stddev)
103 Array<RealType, K / 2> s;
104 const std::size_t nu = n / 2;
105 RealType *
const u1 = r;
106 RealType *
const u2 = r + nu;
108 log(nu, u1, s.data());
109 mul(nu, static_cast<RealType>(-2), s.data(), s.data());
110 sqrt(nu, s.data(), s.data());
111 mul(nu, const_pi_2<RealType>(), u2, u2);
114 mul(nu, stddev, s.data(), s.data());
116 fma(nu, s.data(), u1, mean, u1);
117 fma(nu, s.data(), u2, mean, u2);
119 mul(nu, s.data(), u1, u1);
120 mul(nu, s.data(), u2, u2);
128 template <
typename RealType,
typename RNGType>
130 RNGType &rng, std::size_t n, RealType *r, RealType mean, RealType stddev)
132 static_assert(std::is_floating_point<RealType>::value,
133 "**normal_distribution** USED WITH RealType OTHER THAN FLOATING POINT " 137 const std::size_t m = n / k;
138 const std::size_t l = n % k;
139 for (std::size_t i = 0; i != m; ++i, r += k)
140 internal::normal_distribution_impl<k>(rng, k, r, mean, stddev);
141 internal::normal_distribution_impl<k>(rng, l, r, mean, stddev);
144 RealType u =
u01(rng);
145 RealType v =
u01(rng);
148 std::cos(const_pi_2<RealType>() * v);
156 #endif // VSMC_RNG_NORMAL_DISTRIBUTION_HPP
void mul(std::size_t n, const float *a, const float *b, float *y)
#define VSMC_DEFINE_RNG_DISTRIBUTION_2(Name, name, p1, v1, p2, v2)
void sqrt(std::size_t n, const float *a, float *y)
#define VSMC_DEFINE_RNG_DISTRIBUTION_MEMBER_2(T1, m1, T2, m2)
Standard uniform distribution on (0, 1].
void normal_distribution_impl(RNGType &rng, std::size_t n, RealType *r, RealType mean, RealType stddev)
result_type stddev() const
void normal_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating Normal random variates.
RealType u01(UIntType u) noexcept
Convert uniform unsigned integers to floating points within [0, 1].
void cos(std::size_t n, const float *a, float *y)
bool normal_distribution_check_param(RealType, RealType stddev)
void fma(std::size_t n, const T *a, const T *b, const T *c, T *y)
For , compute .
void sincos(std::size_t n, const float *a, float *y, float *z)
void sin(std::size_t n, const float *a, float *y)
#define VSMC_DEFINE_RNG_DISTRIBUTION_RAND_2(Name, name, p1, p2)
std::array with proper alignment
void u01_oc_distribution(RNGType &rng, std::size_t n, RealType *r)
Generate standard uniform random variates on (0, 1].
void log(std::size_t n, const float *a, float *y)