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