From acd07b6346ff7d0aa6c8b98e175a0646c6b7cc65 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 25 Nov 2020 15:26:06 +0000 Subject: [PATCH] frng constexpr sampling --- lean/include/rng.h | 13 +++++++++- lean/include/rng/frng.hpp | 47 ++++++++++++++++++++++++++++++++++- lean/include/rng/impl.hpp | 4 +-- lean/src/main.c | 3 +++ lean/src/rng/frng.cpp | 52 +++++++++++---------------------------- 5 files changed, 78 insertions(+), 41 deletions(-) diff --git a/lean/include/rng.h b/lean/include/rng.h index 8334d6c..7535119 100644 --- a/lean/include/rng.h +++ b/lean/include/rng.h @@ -1,6 +1,17 @@ #ifndef _RNG_H #define _RNG_H -// C interface to C++ RNG impls +#ifdef __cplusplus +extern "C" { +#endif + +// Tests +void frng_test(); +#ifdef __cplusplus +} +// RNG interfaces +#include + +#endif #endif /* _RNG_H */ diff --git a/lean/include/rng/frng.hpp b/lean/include/rng/frng.hpp index 7a634a6..335a2ee 100644 --- a/lean/include/rng/frng.hpp +++ b/lean/include/rng/frng.hpp @@ -1,17 +1,62 @@ #include "impl.hpp" +#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); + } + inline frng(double s1, double s2) : state({s1, s2}){} inline frng(const std::array& ar) : state(ar){} inline frng(std::array&& ar) : state(ar){} inline frng(const double (&ar)[2]) : state({ar[0], ar[1]}) {} + + inline constexpr double next_double() override { return sample(); } + inline constexpr float next_float() override { return (float)sample(); } protected: - double sample(); + 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); + } }; } diff --git a/lean/include/rng/impl.hpp b/lean/include/rng/impl.hpp index ca10bd8..5cf223d 100644 --- a/lean/include/rng/impl.hpp +++ b/lean/include/rng/impl.hpp @@ -27,8 +27,8 @@ struct RNG { 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(); } + inline virtual float next_float() { return (float)sample(); } + inline virtual double next_double() { return sample(); } protected: virtual double sample() = 0; }; diff --git a/lean/src/main.c b/lean/src/main.c index b8f4452..b603a48 100644 --- a/lean/src/main.c +++ b/lean/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include _Static_assert(sizeof(float)==sizeof(uint32_t), "float is not 32 bits"); @@ -42,6 +43,8 @@ int main(int argc, char** argv) { struct prog_args args = {.argc = argc, .argv = argv}; + frng_test(); + if( argv[1] ) { map_and_then(argv[1], &map_callback, &args); } diff --git a/lean/src/rng/frng.cpp b/lean/src/rng/frng.cpp index f20cb1f..29aa0d2 100644 --- a/lean/src/rng/frng.cpp +++ b/lean/src/rng/frng.cpp @@ -1,48 +1,26 @@ #include #include -#include +#include -template -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); + cout << "Sampled: " << d << endl; + cout << "Long: " << l << endl; + } } - inline 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); - } - double frng::sample() - { - double res = sample_double(state); - update_state(state, res); - return res; - } +extern "C" void frng_test() +{ + rng::test(); }