28 #ifndef OPENRAND_BASE_STATE_H_
29 #define OPENRAND_BASE_STATE_H_
31 #include <openrand/util.h>
35 #include <type_traits>
49 template <
typename RNG>
52 using result_type = uint32_t;
54 static constexpr result_type min() {
57 static constexpr result_type max() {
58 return ~((result_type)0);
69 return gen().template draw<uint32_t>();
83 template <
typename T =
float>
85 if constexpr (
sizeof(T) <= 4) {
86 const uint32_t x = gen().template draw<uint32_t>();
87 if constexpr (std::is_integral_v<T>)
88 return static_cast<T
>(x);
90 return u01<float, uint32_t>(x);
92 const uint64_t x = gen().template draw<uint64_t>();
93 if constexpr (std::is_integral_v<T>)
94 return static_cast<T
>(x);
96 return u01<double, uint64_t>(x);
111 template <
typename T =
float>
112 OPENRAND_DEVICE T
uniform(
const T low,
const T high) {
114 static_assert(!(std::is_integral_v<T> &&
sizeof(T) >
sizeof(int32_t)),
115 "64 bit int not yet supported");
119 if constexpr (std::is_floating_point_v<T>) {
120 return low + r * rand<T>();
121 }
else if constexpr (std::is_integral_v<T>) {
122 return low + range<true, T>(r);
131 template <
typename T =
float>
132 OPENRAND_DEVICE
void fill_random(T *array,
const int N) {
133 for (
int i = 0; i < N; i++) array[i] = rand<T>();
147 template <
typename T =
float>
149 static_assert(std::is_floating_point_v<T>);
150 constexpr T M_PI2 = 2 *
static_cast<T
>(M_PI);
154 T r = openrand::sqrt(T(-2.0) * openrand::log(u));
156 return r * openrand::cos(theta);
165 template <
typename T =
float>
168 static_assert(std::is_floating_point_v<T>);
169 constexpr T M_PI2 = 2 *
static_cast<T
>(M_PI);
173 T r = sqrt(T(-2.0) * log(u));
175 return {r * cos(theta), r * sin(theta)};
187 template <
typename T =
float>
188 OPENRAND_DEVICE T
randn(
const T mean,
const T std_dev) {
189 return mean + randn<T>() * std_dev;
215 template <
bool biased = true,
typename T =
int>
216 OPENRAND_DEVICE T
range(
const T N) {
220 uint32_t x = gen().template draw<uint32_t>();
221 uint64_t res =
static_cast<uint64_t
>(x) *
static_cast<uint64_t
>(N);
223 if constexpr (biased) {
224 return static_cast<T
>(res >> 32);
226 uint32_t leftover =
static_cast<uint32_t
>(res);
228 uint32_t threshold = -N % N;
229 while (leftover < threshold) {
230 x = gen().template draw<uint32_t>();
231 res =
static_cast<uint64_t
>(x) *
static_cast<uint64_t
>(N);
232 leftover =
static_cast<uint32_t
>(res);
235 return static_cast<T
>(res);
252 template <
typename T =
float>
253 OPENRAND_DEVICE
inline T
gamma(T alpha, T b) {
254 T d = alpha - T((1. / 3.));
255 T c = T(1.) / sqrt(9.f * d);
261 }
while (v <= T(0.));
266 if (u < 1.0f - 0.0331f * x2 * x2)
return (d * v * b);
268 if (log(u) < 0.5f * x2 + d * (1.0f - v + log(v)))
return (d * v * b);
282 template <
typename T = RNG>
285 RNG rng = *
static_cast<const RNG *
>(
this);
294 template <
typename Ftype,
typename Utype>
295 inline OPENRAND_DEVICE Ftype u01(
const Utype in)
const {
296 constexpr Ftype factor =
297 Ftype(1.) / (Ftype(~
static_cast<Utype
>(0)) + Ftype(1.));
298 constexpr Ftype halffactor = Ftype(0.5) * factor;
299 return static_cast<Ftype
>(in) * factor + halffactor;
306 OPENRAND_DEVICE __inline__ RNG &gen() {
307 return *
static_cast<RNG *
>(
this);
Base class for random number generators.
Definition: base_state.h:50
OPENRAND_DEVICE T rand()
Generates a random number from a uniform distribution between 0 and 1.
Definition: base_state.h:84
OPENRAND_DEVICE T uniform(const T low, const T high)
Generates a number from a uniform distribution between a and b.
Definition: base_state.h:112
OPENRAND_DEVICE vec2< T > randn2()
More efficient version of randn, returns two values at once.
Definition: base_state.h:166
OPENRAND_DEVICE T range(const T N)
Generates a random integer of certain range.
Definition: base_state.h:216
OPENRAND_DEVICE T gamma(T alpha, T b)
Generates a random number from a gamma distribution with shape alpha and scale b.
Definition: base_state.h:253
OPENRAND_DEVICE T randn()
Generates a random number from a normal distribution with mean 0 and std 1.
Definition: base_state.h:148
OPENRAND_DEVICE result_type operator()()
Generates a 32 bit unsigned integer from a uniform distribution.
Definition: base_state.h:68
std::enable_if_t< has_counter< T >::value, RNG > forward_state(int n) const
Returns a new generator with the internal state forwarded by a given number.
Definition: base_state.h:283
OPENRAND_DEVICE T randn(const T mean, const T std_dev)
Generates a random number from a normal distribution with mean and std.
Definition: base_state.h:188