32 #ifndef MCKL_RANDOM_U01_DISTRIBUTION_HPP 33 #define MCKL_RANDOM_U01_DISTRIBUTION_HPP 41 #ifndef MCKL_U01_USE_FIXED_POINT 42 #define MCKL_U01_USE_FIXED_POINT 0 47 #ifndef MCKL_U01_USE_64BITS_DOUBLE 48 #define MCKL_U01_USE_64BITS_DOUBLE 0 51 #define MCKL_DEFINE_RANDOM_U01_DISTRIBUTION(Name, name) \ 52 template <typename RealType> \ 53 class Name##Distribution \ 55 MCKL_DEFINE_RANDOM_DISTRIBUTION_ASSERT_REAL_TYPE(Name) \ 56 MCKL_DEFINE_RANDOM_DISTRIBUTION_0(Name, name, RealType) \ 57 MCKL_DEFINE_RANDOM_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 MCKL_DEFINE_RANDOM_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 alignas(MCKL_ALIGNMENT) std::array<UIntType, K> s; \ 87 uniform_bits_distribution(rng, n, s.data()); \ 88 name<UIntType, RealType>(n, s.data(), r); \ 95 #if MCKL_U01_USE_64BITS_DOUBLE 97 template <
typename RNGType,
typename RealType>
100 std::is_same<typename std::remove_cv_t<RealType>,
101 long double>::value ||
102 std::is_same<typename std::remove_cv_t<RealType>,
double>::value),
105 #else // MCKL_U01_USE_64BITS_DOUBLE 107 template <
typename RNGType,
typename RealType>
109 std::conditional_t<(RNGTraits<RNGType>::bits >= 64 ||
110 std::is_same<RealType, long double>::value),
113 #endif // MCKL_U01_USE_64BITS_DOUBLE 115 template <std::
size_t K,
typename RealType,
typename RNGType>
117 RNGType &rng, std::size_t n, RealType *r)
121 constexpr
int W = std::numeric_limits<UIntType>::digits;
122 constexpr
int M = std::numeric_limits<RealType>::digits;
123 constexpr
int P = (M + W - 1) / W;
124 constexpr
int Q = 1 > P ? 1 : P;
128 u01_canonical<UIntType, RealType, Q>(n, s.data(), r);
146 template <typename RealType>
160 template <
typename RNGType>
165 constexpr
int W = std::numeric_limits<UIntType>::digits;
166 constexpr
int M = std::numeric_limits<RealType>::digits;
167 constexpr
int P = (M + W - 1) / W;
168 constexpr
int Q = 1 > P ? 1 : P;
170 std::array<UIntType, Q> u;
171 generate<0>(rng, u, std::true_type());
173 return u01_canonical<UIntType, RealType, Q>(u.data());
176 template <std::
size_t,
typename RNGType,
typename UIntType, std::
size_t Q>
177 void generate(RNGType &, std::array<UIntType, Q> &, std::false_type)
181 template <std::size_t N,
typename RNGType,
typename UIntType,
183 void generate(RNGType &rng, std::array<UIntType, Q> &u, std::true_type)
186 std::get<N>(u) = ubits(rng);
187 generate<N + 1>(rng, u, std::integral_constant<bool, N + 1 < Q>());
213 #if MCKL_U01_USE_FIXED_POINT 215 template <
typename RealType>
218 template <
typename RealType,
typename RNGType>
224 #else // MCKL_U01_USE_FIXED_POINT 226 template <
typename RealType>
229 template <
typename RealType,
typename RNGType>
235 #endif // MCKL_U01_USE_FIXED_POINT 239 #endif // MCKL_RANDOM_U01_DISTRIBUTION_HPP std::conditional_t<(RNGTraits< RNGType >::bits >=64||std::is_same< RealType, long double >::value), std::uint64_t, std::uint32_t > U01UIntType
Standard uniform distribution on [0, 1)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_BATCH_0(Name, name, T)
#define MCKL_DEFINE_RANDOM_U01_DISTRIBUTION_IMPL(name)
void uniform_bits_distribution(RNGType &rng, std::size_t n, UIntType *r)
RealType u01_cc(UIntType u)
Convert uniform unsigned integers to floating points on [0, 1].
RealType u01_oc(UIntType u)
Convert uniform unsigned integers to floating points on (0, 1].
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_RAND(Name, T)
#define MCKL_DEFINE_RANDOM_U01_DISTRIBUTION(Name, name)
void u01_canonical_distribution(RNGType &rng, std::size_t n, RealType *r)
RealType u01_co(UIntType u)
Convert uniform unsigned integers to floating points on [0, 1)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_0(Name, name, T)
void u01_co_distribution(RNGType &rng, std::size_t n, RealType *r)
#define MCKL_ALIGNMENT
The default alignment for scalar type.
Standard uniform distribution on [0, 1)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_MEMBER_0
RealType u01_canonical(const UIntType *u)
Convert uniform multiple unsigned integers to one floating points within [0, 1].
RealType u01_oo(UIntType u)
Convert uniform unsigned integers to floating points on (0, 1)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_ASSERT_REAL_TYPE(Name)
void u01_canonical_distribution_impl(RNGType &rng, std::size_t n, RealType *r)
static constexpr int bits
void u01_distribution(RNGType &rng, std::size_t n, RealType *r)