parent
ffa3402ea7
commit
160c736289
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _RNG_H
|
||||||
|
#define _RNG_H
|
||||||
|
|
||||||
|
// C interface to C++ RNG impls
|
||||||
|
|
||||||
|
#endif /* _RNG_H */
|
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
#include "impl.hpp"
|
||||||
|
|
||||||
|
namespace rng
|
||||||
|
{
|
||||||
|
struct frng : public RNG
|
||||||
|
{
|
||||||
|
inline frng(double s1, double s2) : state({s1, s2}){}
|
||||||
|
inline frng(const std::array<double, 2>& ar) : state(ar){}
|
||||||
|
inline frng(std::array<double, 2>&& ar) : state(ar){}
|
||||||
|
inline frng(const double (&ar)[2]) : state({ar[0], ar[1]}) {}
|
||||||
|
protected:
|
||||||
|
double sample();
|
||||||
|
private:
|
||||||
|
std::array<double, 2> state;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/// Base class for RNG impls
|
||||||
|
struct RNG {
|
||||||
|
virtual unsigned char byte();
|
||||||
|
virtual void bytes(unsigned char* ptr, std::size_t len);
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
inline void bytes(unsigned char (&arr)[N]) { return bytes(arr, N); }
|
||||||
|
template<std::size_t N>
|
||||||
|
inline void bytes(std::array<unsigned char, N>& array) { return bytes(&array[0], N); }
|
||||||
|
inline void bytes(std::vector<unsigned char>& vec) { return bytes(&vec[0], vec.size()); }
|
||||||
|
|
||||||
|
bool chance();
|
||||||
|
virtual bool chance(double chance);
|
||||||
|
|
||||||
|
virtual std::int32_t next_int();
|
||||||
|
inline std::int32_t next_int(std::int32_t max) { return next_int(0, max); }
|
||||||
|
std::int32_t next_int(std::int32_t min, std::int32_t max);
|
||||||
|
|
||||||
|
virtual std::int64_t next_long();
|
||||||
|
|
||||||
|
inline std::int64_t next_long(std::int64_t max) { return next_long(0, max); }
|
||||||
|
std::int64_t next_long(std::int64_t min, std::int64_t max);
|
||||||
|
|
||||||
|
inline float next_float() { return (float)sample(); }
|
||||||
|
inline double next_double() { return sample(); }
|
||||||
|
protected:
|
||||||
|
virtual double sample() = 0;
|
||||||
|
};
|
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
#include <rng/impl.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
inline unsigned char RNG::byte()
|
||||||
|
{
|
||||||
|
return (unsigned char)next_int(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RNG::bytes(unsigned char* ptr, std::size_t len)
|
||||||
|
{
|
||||||
|
for(std::size_t i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
ptr[i] = byte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RNG::chance()
|
||||||
|
{
|
||||||
|
return next_long() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RNG::chance(double d)
|
||||||
|
{
|
||||||
|
if (d<=0) return false;
|
||||||
|
return sample() <= d;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int32_t RNG::next_int(std::int32_t min, std::int32_t max)
|
||||||
|
{
|
||||||
|
return (std::int32_t)floor(sample() * (double)(max-min))+min;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int32_t RNG::next_int()
|
||||||
|
{
|
||||||
|
return next_int(INT32_MIN, INT32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int64_t RNG::next_long(std::int64_t min, std::int64_t max)
|
||||||
|
{
|
||||||
|
return (std::int64_t)floor(sample() * (double)(max-min))+min;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int64_t RNG::next_long()
|
||||||
|
{
|
||||||
|
return next_long(INT64_MIN, INT32_MAX);
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
#include <rng/impl.hpp>
|
||||||
|
#include <rng/frng.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
constexpr inline double dot(const std::array<double, N>& v, const std::array<double, N>& u)
|
||||||
|
{
|
||||||
|
double res=0;
|
||||||
|
for(std::size_t i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
res += v[i] * u[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr double fract(double x)
|
||||||
|
{
|
||||||
|
return x - floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace rng {
|
||||||
|
inline constexpr double sample_double(const std::array<double, 2>& state)
|
||||||
|
{
|
||||||
|
const constexpr std::array<double, 2> vec2 = { 12.9898, 78.223 };
|
||||||
|
return fract(sin(dot(state, vec2)) * 43758.5453);
|
||||||
|
}
|
||||||
|
inline void update_state(std::array<double, 2>& state, double r)
|
||||||
|
{
|
||||||
|
float v1 = (float)state[0];
|
||||||
|
float v2 = (float)state[1];
|
||||||
|
|
||||||
|
std::array<double, 2> nvec = {
|
||||||
|
r,
|
||||||
|
(double)v2,
|
||||||
|
};
|
||||||
|
|
||||||
|
state[0] = sample_double(nvec);
|
||||||
|
|
||||||
|
nvec[1] = (double)v1;
|
||||||
|
state[1] = sample_double(nvec);
|
||||||
|
}
|
||||||
|
double frng::sample()
|
||||||
|
{
|
||||||
|
double res = sample_double(state);
|
||||||
|
update_state(state, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue