#include "impl.hpp" #include #include namespace rng { struct frng : public RNG { template static constexpr inline double dot(const std::array& v, const std::array& u) { double res=0; for(std::size_t i=0;i& state) { const constexpr std::array vec2 = { 12.9898, 78.223 }; return fract(sin(dot(state, vec2)) * 43758.5453); } #define P D_dprintf("frng: seeded with (%f, %f)", state[0], state[1]); inline constexpr frng(double s1, double s2) : state({s1, s2}){P} inline constexpr frng(const std::array& ar) : state(ar){P} inline constexpr frng(std::array&& ar) : state(ar){P} inline constexpr frng(const double (&ar)[2]) : state({ar[0], ar[1]}) {P} constexpr virtual ~frng() = default; #undef P inline constexpr double next_double() override { return sample(); } inline constexpr float next_float() override { return (float)sample(); } protected: inline constexpr double sample() override { double res = sample_double(state); update_state(state, res); return res; } private: std::array state; static inline constexpr void update_state(std::array& state, double r) { float v1 = (float)state[0]; float v2 = (float)state[1]; std::array nvec = { r, (double)v2, }; state[0] = sample_double(nvec); nvec[1] = (double)v1; state[1] = sample_double(nvec); } }; }