random using xoshiro256+
This commit is contained in:
parent
28b4575bbc
commit
f12e61b1b5
@ -1,66 +1,45 @@
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
|
||||
#include "utils/Random.hpp"
|
||||
|
||||
panda::Random::Random(uint32_t _w, uint32_t _z) {
|
||||
m_w = _w;
|
||||
m_z = _z;
|
||||
static inline uint64_t splitmix64(uint64_t &x) {
|
||||
uint64_t z = (x += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
void panda::Random::setSeed(uint32_t w) {
|
||||
if (w != 0) m_w = w;
|
||||
static inline uint64_t rotl(const uint64_t x, int k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
void panda::Random::setSeed(uint32_t w, uint32_t z) {
|
||||
if (w != 0) m_w = w;
|
||||
if (z != 0) m_z = z;
|
||||
|
||||
panda::Random::Random(uint64_t seed) {
|
||||
for(int i=0; i<4; i++) s[i] = splitmix64(seed);
|
||||
}
|
||||
|
||||
void panda::Random::setSeedFromTime() {
|
||||
m_w = std::chrono::system_clock::now().time_since_epoch().count();
|
||||
void panda::Random::SetSeed(uint64_t seed) {
|
||||
for(int i=0; i<4; i++) s[i] = splitmix64(seed);
|
||||
}
|
||||
|
||||
uint32_t panda::Random::MWC() {
|
||||
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
|
||||
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
|
||||
return (m_z << 16) + m_w;
|
||||
uint64_t panda::Random::Next() {
|
||||
const uint64_t result = s[0] + s[3];
|
||||
|
||||
const uint64_t t = s[1] << 17;
|
||||
|
||||
s[2] ^= s[0];
|
||||
s[3] ^= s[1];
|
||||
s[1] ^= s[2];
|
||||
s[0] ^= s[3];
|
||||
|
||||
s[2] ^= t;
|
||||
|
||||
s[3] = rotl(s[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float panda::Random::UNI() {
|
||||
return MWC() * inv_uni;
|
||||
double panda::Random::Next_UNI() {
|
||||
return (Next() >> 11) * 0x1.0p-53;
|
||||
}
|
||||
|
||||
float panda::Random::range(float min, float max) {
|
||||
return min + (max-min) * UNI();
|
||||
}
|
||||
|
||||
float panda::Random::rangeEx(float min, float max, float lamda) {
|
||||
const float u = UNI();
|
||||
return min + (max-min) * std::pow(u, lamda);
|
||||
}
|
||||
|
||||
|
||||
|
||||
float panda::Random::xorshift_uni(uint32_t x) {
|
||||
return xorshift(x) * inv_uni;
|
||||
}
|
||||
|
||||
float panda::Random::xorshift64_uni(uint64_t x) {
|
||||
return xorshift64(x) * inv_uni64;
|
||||
}
|
||||
|
||||
uint32_t panda::Random::xorshift(uint32_t x) {
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t panda::Random::xorshift64(uint64_t x) {
|
||||
x ^= x << 13;
|
||||
x ^= x >> 7;
|
||||
x ^= x << 17;
|
||||
return x;
|
||||
}
|
||||
double panda::Random::Range(double min, double max) {
|
||||
return min + (max-min) * Next_UNI();
|
||||
}
|
@ -5,31 +5,14 @@ namespace panda
|
||||
{
|
||||
class Random {
|
||||
public:
|
||||
static Random& getInstance()
|
||||
{
|
||||
static Random instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Random(uint32_t _w = 521288629, uint32_t _z = 362436069);
|
||||
void setSeed(uint32_t w);
|
||||
void setSeed(uint32_t w, uint32_t z);
|
||||
void setSeedFromTime();
|
||||
|
||||
uint32_t MWC();
|
||||
float UNI();
|
||||
float range(float min, float max);
|
||||
float rangeEx(float min, float max, float lamda);
|
||||
|
||||
float xorshift_uni(uint32_t x);
|
||||
float xorshift64_uni(uint64_t x);
|
||||
uint32_t xorshift(uint32_t x);
|
||||
uint64_t xorshift64(uint64_t x);
|
||||
Random(uint64_t seed = 521288629);
|
||||
void SetSeed(uint64_t seed);
|
||||
|
||||
uint64_t Next();
|
||||
double Next_UNI();
|
||||
double Range(double min, double max);
|
||||
|
||||
private:
|
||||
uint32_t m_w;
|
||||
uint32_t m_z;
|
||||
float inv_uni = 2.3283064e-10;
|
||||
float inv_uni64 = 5.4210109e-20;
|
||||
uint64_t s[4];
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user