32 #ifndef VSMC_RNG_U01_DISTRIBUTION_HPP 33 #define VSMC_RNG_U01_DISTRIBUTION_HPP 41 #ifndef VSMC_RNG_U01_USE_FIXED_POINT 42 #define VSMC_RNG_U01_USE_FIXED_POINT 1 47 #ifndef VSMC_RNG_U01_USE_64BITS_DOUBLE 48 #define VSMC_RNG_U01_USE_64BITS_DOUBLE 0 51 #define VSMC_DEFINE_U01_DISTRIBUTION(Name, name) \ 52 template <typename RealType> \ 53 class Name##Distribution \ 55 VSMC_DEFINE_RNG_DISTRIBUTION_0( \ 56 Name, name, RealType, floating_point, FLOATING_POINT) \ 57 VSMC_DEFINE_RNG_DISTRIBUTION_MEMBER_0 \ 60 result_type min() const { return 0; } \ 62 result_type max() const { return 1; } \ 67 template <typename RNGType> \ 68 result_type generate(RNGType &rng, const param_type &) \ 71 typename internal::U01UIntType<RNGType, RealType>; \ 73 UniformBitsDistribution<UIntType> ubits; \ 75 return name<UIntType, result_type>(ubits(rng)); \ 79 #define VSMC_DEFINE_U01_DISTRIBUTION_IMPL(name) \ 80 template <std::size_t K, typename RealType, typename RNGType> \ 81 inline void name##_distribution_impl( \ 82 RNGType &rng, std::size_t n, RealType *r) \ 84 using UIntType = U01UIntType<RNGType, RealType>; \ 86 Array<UIntType, K> s; \ 87 uniform_bits_distribution(rng, n, s.data()); \ 88 name<UIntType, RealType>(n, s.data(), r); \ 97 #if VSMC_RNG_U01_USE_64BITS_DOUBLE 99 template <
typename RNGType,
typename RealType>
101 typename std::conditional<(RNGTraits<RNGType>::bits >= 64 ||
102 std::is_same<RealType, long double>::value ||
103 std::is_same<RealType, double>::value),
106 #else // VSMC_RNG_U01_USE_64BITS_DOUBLE 108 template <
typename RNGType,
typename RealType>
110 typename std::conditional<(RNGTraits<RNGType>::bits >= 64 ||
111 std::is_same<RealType, long double>::value),
114 #endif // VSMC_RNG_U01_USE_64BITS_DOUBLE 134 #if VSMC_RNG_U01_USE_FIXED_POINT 136 template <
typename RealType>
141 #else // VSMC_RNG_U01_USE_FIXED_POINT 145 template <
typename RealType>
149 U01,
u01, RealType, floating_point, FLOATING_POINT)
158 template <
typename RNGType>
161 return generate<0>(rng, std::true_type());
164 template <std::
size_t,
typename RNGType>
170 template <std::
size_t N,
typename RNGType>
177 static constexpr
int W = std::numeric_limits<UIntType>::digits;
178 static constexpr
int M = std::numeric_limits<RealType>::digits;
179 static constexpr
int P = (W + M - 1) / W;
180 static constexpr
int Q = 1 > P ? 1 : P;
182 return static_cast<RealType
>(ubits(rng)) *
184 generate<N + 1>(rng, std::integral_constant<bool, N + 1 < Q>());
188 #endif // VSMC_RNG_U01_USE_FIXED_POINT 198 #if VSMC_RNG_U01_USE_FIXED_POINT 200 template <std::
size_t K,
typename RealType,
typename RNGType>
203 u01_co_distribution_impl<K>(rng, n, r);
206 #else // VSMC_RNG_U01_USE_FIXED_POINT 208 template <std::
size_t,
typename RealType,
typename UIntType>
214 template <std::
size_t N,
typename RealType,
typename UIntType>
217 static constexpr
int W = std::numeric_limits<UIntType>::digits;
218 static constexpr
int M = std::numeric_limits<RealType>::digits;
219 static constexpr
int P = (M + W - 1) / W;
220 static constexpr
int Q = 1 > P ? 1 : P;
222 return static_cast<RealType
>(u[N]) *
224 u01_distribution_impl<N + 1, RealType>(
225 u, std::integral_constant<bool, N + 1 < Q>());
228 template <std::
size_t K,
typename RealType,
typename RNGType>
233 static constexpr
int W = std::numeric_limits<UIntType>::digits;
234 static constexpr
int M = std::numeric_limits<RealType>::digits;
235 static constexpr
int P = (M + W - 1) / W;
236 static constexpr
int Q = 1 > P ? 1 : P;
240 const UIntType *u = s.data();
241 for (std::size_t i = 0; i != n; ++i, u += Q)
242 r[i] = u01_distribution_impl<0, RealType>(u, std::true_type());
245 #endif // VSMC_RNG_U01_USE_FIXED_POINT 276 #endif // VSMC_RNG_U01_HPP
RealType u01_oo(UIntType u) noexcept
Convert uniform unsigned integers to floating points on (0, 1)
#define VSMC_DEFINE_RNG_DISTRIBUTION_RAND_0(Name, name, T)
#define VSMC_DEFINE_RNG_DISTRIBUTION_0(Name, name, T, t, Type)
RealType u01_co(UIntType u) noexcept
Convert uniform unsigned integers to floating points on [0, 1)
#define VSMC_DEFINE_U01_DISTRIBUTION(Name, name)
RealType u01(UIntType u) noexcept
Convert uniform unsigned integers to floating points within [0, 1].
#define VSMC_DEFINE_RNG_DISTRIBUTION_IMPL_0(name)
RealType u01_oc(UIntType u) noexcept
Convert uniform unsigned integers to floating points on (0, 1].
#define VSMC_DEFINE_U01_DISTRIBUTION_IMPL(name)
RealType u01_cc(UIntType u) noexcept
Convert uniform unsigned integers to floating points on [0, 1].
typename std::conditional<(RNGTraits< RNGType >::bits >=64||std::is_same< RealType, long double >::value), std::uint64_t, std::uint32_t >::type U01UIntType
void uniform_bits_distribution(RNGType &, std::size_t, UIntType *)
std::array with proper alignment
void u01_distribution_impl(RNGType &rng, std::size_t n, RealType *r)
Standard uniform distribution on [0, 1)