32 #ifndef VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP 33 #define VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP 47 template <
typename UIntType>
48 class UniformBitsDistribution
51 UniformBits, uniform_bits, UIntType,
unsigned, UNSIGNED)
62 template <
typename RNGType>
69 template <
typename RNGType>
70 static UIntType generate(RNGType &rng, std::false_type)
72 std::independent_bits_engine<RNGType,
73 std::numeric_limits<UIntType>::digits, UIntType>
76 rng = std::move(eng.base());
81 template <
typename RNGType>
82 static UIntType generate(RNGType &rng, std::true_type)
84 static constexpr
int w = std::numeric_limits<UIntType>::digits;
87 return generate_patch(rng, std::integral_constant<
bool, (w <= r)>());
90 template <
typename RNGType>
91 static UIntType generate_patch(RNGType &rng, std::true_type)
93 return static_cast<UIntType
>(rng() - RNGType::min());
96 template <
typename RNGType>
97 static UIntType generate_patch(RNGType &rng, std::false_type)
99 return patch<0>(rng, std::true_type());
102 template <
int,
typename RNGType>
103 static UIntType patch(RNGType &, std::false_type)
108 template <
int N,
typename RNGType>
109 static UIntType patch(RNGType &rng, std::true_type)
111 static constexpr
int w = std::numeric_limits<UIntType>::digits;
113 static constexpr
int p = r * N;
114 static constexpr
int q = r * N + r;
116 UIntType u =
static_cast<UIntType
>(rng() - RNGType::min())
117 << static_cast<UIntType>(p);
119 return u + patch<N + 1>(rng, std::integral_constant<bool, (q < w)>());
126 template <
typename UIntType,
typename RNGType>
128 RNGType &rng, std::size_t n, UIntType *r, std::false_type)
131 for (std::size_t i = 0; i != n; ++i)
135 template <
typename UIntType,
typename RNGType>
137 RNGType &rng, std::size_t n, UIntType *r, std::true_type)
140 static constexpr
int ubits = std::numeric_limits<UIntType>::digits;
141 static constexpr std::size_t rate = ubits / rbits;
142 const std::size_t m = n * rate;
143 rand(rng, m, reinterpret_cast<typename RNGType::result_type *>(r));
148 template <
typename UIntType,
typename RNGType>
151 static_assert(std::is_unsigned<UIntType>::value,
152 "**uniform_bits_distribution** USED WITH UIntType OTHER THAN UNSIGNED " 156 static constexpr
int ubits = std::numeric_limits<UIntType>::digits;
157 static constexpr
int tbits =
158 std::numeric_limits<typename RNGType::result_type>::digits;
159 static constexpr std::size_t ualign =
alignof(UIntType);
160 static constexpr std::size_t talign =
alignof(UIntType);
164 std::integral_constant<
166 rbits == tbits && ubits >= tbits && ubits % tbits == 0 &&
167 ualign >= talign && ualign % talign == 0)>());
174 #endif // VSMC_RNG_UNIFORM_BITS_DISTRIBUTION_HPP
void uniform_bits_distribution_impl(RNGType &rng, std::size_t n, UIntType *r, std::false_type)
#define VSMC_DEFINE_RNG_DISTRIBUTION_RAND_0(Name, name, T)
#define VSMC_DEFINE_RNG_DISTRIBUTION_0(Name, name, T, t, Type)
void uniform_bits_distribution_impl(RNGType &rng, std::size_t n, UIntType *r, std::true_type)
#define VSMC_DEFINE_RNG_DISTRIBUTION_MEMBER_0
void rand(RNGType &rng, ArcsineDistribution< RealType > &dist, std::size_t N, RealType *r)
void uniform_bits_distribution(RNGType &, std::size_t, UIntType *)