parent
48301abe6b
commit
eec7fa4167
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#include "impl.hpp"
|
||||||
|
|
||||||
|
namespace rng
|
||||||
|
{
|
||||||
|
struct drng : public RNG
|
||||||
|
{
|
||||||
|
inline drng(std::uint32_t seed) : state(seed){sample();}
|
||||||
|
inline drng() : drng(1){}
|
||||||
|
|
||||||
|
static drng from_time();
|
||||||
|
|
||||||
|
int rand();
|
||||||
|
protected:
|
||||||
|
double sample() override;
|
||||||
|
private:
|
||||||
|
std::uint32_t state;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "impl.hpp"
|
||||||
|
|
||||||
|
namespace rng
|
||||||
|
{
|
||||||
|
struct xoroshiro128plus : public RNG
|
||||||
|
{
|
||||||
|
using State = std::array<std::uint64_t, 2>;
|
||||||
|
inline constexpr xoroshiro128plus(std::uint64_t s0, std::uint64_t s1) : state({s0, s1}){}
|
||||||
|
inline constexpr xoroshiro128plus(std::array<std::uint64_t, 2>&& ar) : state(ar){}
|
||||||
|
inline constexpr xoroshiro128plus(const std::array<std::uint64_t, 2>& ar) : state(ar){}
|
||||||
|
inline constexpr xoroshiro128plus(const std::uint64_t (&ar)[2]) : state({ar[0], ar[1]}){}
|
||||||
|
|
||||||
|
std::uint64_t next_ulong();
|
||||||
|
using RNG::next_long;
|
||||||
|
std::int64_t next_long() override;
|
||||||
|
|
||||||
|
void jump();
|
||||||
|
void long_jump();
|
||||||
|
protected:
|
||||||
|
double sample() override;
|
||||||
|
private:
|
||||||
|
State state;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <rng/drng.h>
|
||||||
|
|
||||||
|
namespace rng
|
||||||
|
{
|
||||||
|
static inline void d_test()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
drng rng(100);
|
||||||
|
|
||||||
|
for(int i=0;i<10;i++) {
|
||||||
|
double d = rng.next_double();
|
||||||
|
long l = rng.next_long(-10, 10);
|
||||||
|
|
||||||
|
std::array<bool, 10> ar;
|
||||||
|
for(auto& i : ar) i = rng.chance();
|
||||||
|
|
||||||
|
cout << "D Sampled: " << d << endl;
|
||||||
|
cout << "D Long: " << l << endl;
|
||||||
|
cout << "D Bools: [ ";
|
||||||
|
for(const auto& i : ar) cout << i << " ";
|
||||||
|
cout << "]" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drng drng::from_time() { return drng(time(NULL)); }
|
||||||
|
|
||||||
|
int drng::rand()
|
||||||
|
{
|
||||||
|
return rand_r(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
double drng::sample()
|
||||||
|
{
|
||||||
|
int val = rand_r(&state);
|
||||||
|
return (double)val / (double)RAND_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void drng_test()
|
||||||
|
{
|
||||||
|
return rng::d_test();
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
#include <rng/xoroshiro128plus.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using u64 = std::uint64_t;
|
||||||
|
|
||||||
|
#define XO xoroshiro128plus
|
||||||
|
|
||||||
|
static inline constexpr u64 rotl(u64 x, int k)
|
||||||
|
{
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace rng
|
||||||
|
{
|
||||||
|
static inline void xo_test()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
XO rng(100ul, 123123123ul);
|
||||||
|
|
||||||
|
for(int i=0;i<10;i++) {
|
||||||
|
double d = rng.next_double();
|
||||||
|
long l = rng.next_long(-10, 10);
|
||||||
|
|
||||||
|
std::array<bool, 10> ar;
|
||||||
|
for(auto& i : ar) i = rng.chance();
|
||||||
|
|
||||||
|
cout << "XO Sampled: " << d << endl;
|
||||||
|
cout << "XO Long: " << l << endl;
|
||||||
|
cout << "XO Bools: [ ";
|
||||||
|
for(const auto& i : ar) cout << i << " ";
|
||||||
|
cout << "]" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr u64 next(XO::State& s)
|
||||||
|
{
|
||||||
|
u64 s0 = s[0];
|
||||||
|
u64 s1 = s[1];
|
||||||
|
u64 result = s0 + s1;
|
||||||
|
|
||||||
|
s1 ^= s0;
|
||||||
|
s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16);
|
||||||
|
s[1] = rotl(s1, 37);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
inline constexpr void xo_jump(XO::State& s)
|
||||||
|
{
|
||||||
|
constexpr const std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
|
||||||
|
|
||||||
|
std::uint64_t s0 = 0;
|
||||||
|
std::uint64_t s1 = 0;
|
||||||
|
for(u64 i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
|
||||||
|
for(int b = 0; b < 64; b++) {
|
||||||
|
if (JUMP[i] & UINT64_C(1) << b) {
|
||||||
|
s0 ^= s[0];
|
||||||
|
s1 ^= s[1];
|
||||||
|
}
|
||||||
|
next(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
s[0] = s0;
|
||||||
|
s[1] = s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr void xo_long_jump(XO::State& s)
|
||||||
|
{
|
||||||
|
constexpr const uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
|
||||||
|
|
||||||
|
std::uint64_t s0 = 0;
|
||||||
|
std::uint64_t s1 = 0;
|
||||||
|
for(u64 i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
|
||||||
|
for(int b = 0; b < 64; b++) {
|
||||||
|
if (LONG_JUMP[i] & UINT64_C(1) << b) {
|
||||||
|
s0 ^= s[0];
|
||||||
|
s1 ^= s[1];
|
||||||
|
}
|
||||||
|
next(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
s[0] = s0;
|
||||||
|
s[1] = s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XO::jump() { xo_jump(state); }
|
||||||
|
void XO::long_jump() { xo_long_jump(state); }
|
||||||
|
|
||||||
|
std::uint64_t XO::next_ulong()
|
||||||
|
{
|
||||||
|
return next(state);
|
||||||
|
}
|
||||||
|
std:: int64_t XO::next_long()
|
||||||
|
{
|
||||||
|
const u64 v = next_ulong();
|
||||||
|
static_assert(sizeof(v) == sizeof(decltype(next_long())));
|
||||||
|
|
||||||
|
return *(const std::int64_t*)&v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double XO::sample()
|
||||||
|
{
|
||||||
|
return (next(state) & ((INT64_C(1) << 53) - 1)) * (1.00 / (INT64_C(1) << 53));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void xorng_test()
|
||||||
|
{
|
||||||
|
return rng::xo_test();
|
||||||
|
}
|
Loading…
Reference in new issue