parent
160c736289
commit
acd07b6346
@ -1,6 +1,17 @@
|
|||||||
#ifndef _RNG_H
|
#ifndef _RNG_H
|
||||||
#define _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 <rng/frng.hpp>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _RNG_H */
|
#endif /* _RNG_H */
|
||||||
|
@ -1,17 +1,62 @@
|
|||||||
|
|
||||||
#include "impl.hpp"
|
#include "impl.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace rng
|
namespace rng
|
||||||
{
|
{
|
||||||
struct frng : public RNG
|
struct frng : public RNG
|
||||||
{
|
{
|
||||||
|
template<std::size_t N>
|
||||||
|
static 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline constexpr double fract(double x)
|
||||||
|
{
|
||||||
|
return x - floor(x);
|
||||||
|
}
|
||||||
|
static 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 frng(double s1, double s2) : state({s1, s2}){}
|
inline frng(double s1, double s2) : state({s1, s2}){}
|
||||||
inline frng(const std::array<double, 2>& ar) : state(ar){}
|
inline frng(const std::array<double, 2>& ar) : state(ar){}
|
||||||
inline frng(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]}) {}
|
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:
|
protected:
|
||||||
double sample();
|
inline constexpr double sample() override
|
||||||
|
{
|
||||||
|
double res = sample_double(state);
|
||||||
|
update_state(state, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::array<double, 2> state;
|
std::array<double, 2> state;
|
||||||
|
static inline constexpr 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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,26 @@
|
|||||||
#include <rng/impl.hpp>
|
#include <rng/impl.hpp>
|
||||||
#include <rng/frng.hpp>
|
#include <rng/frng.hpp>
|
||||||
#include <cmath>
|
#include <iostream>
|
||||||
|
|
||||||
template<std::size_t N>
|
namespace rng {
|
||||||
constexpr inline double dot(const std::array<double, N>& v, const std::array<double, N>& u)
|
using namespace std;
|
||||||
{
|
inline void test()
|
||||||
double res=0;
|
|
||||||
for(std::size_t i=0;i<N;i++)
|
|
||||||
{
|
{
|
||||||
res += v[i] * u[i];
|
frng rng(1.0, 2.0);
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline constexpr double fract(double x)
|
for(int i=0;i<10;i++) {
|
||||||
{
|
double d = rng.next_double();
|
||||||
return x - floor(x);
|
long l = rng.next_long(0, 100);
|
||||||
}
|
|
||||||
|
|
||||||
namespace rng {
|
cout << "Sampled: " << d << endl;
|
||||||
inline constexpr double sample_double(const std::array<double, 2>& state)
|
cout << "Long: " << l << endl;
|
||||||
{
|
}
|
||||||
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;
|
extern "C" void frng_test()
|
||||||
state[1] = sample_double(nvec);
|
|
||||||
}
|
|
||||||
double frng::sample()
|
|
||||||
{
|
{
|
||||||
double res = sample_double(state);
|
rng::test();
|
||||||
update_state(state, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue