From f12e61b1b592165db3abeb2c36831da18c67a050 Mon Sep 17 00:00:00 2001 From: sillysagiri Date: Wed, 6 Nov 2024 16:10:50 +0700 Subject: [PATCH] random using xoshiro256+ --- src/utils/Random.cpp | 83 +++++++++++++++++--------------------------- src/utils/Random.hpp | 31 ++++------------- 2 files changed, 38 insertions(+), 76 deletions(-) diff --git a/src/utils/Random.cpp b/src/utils/Random.cpp index 5279fba..652d649 100755 --- a/src/utils/Random.cpp +++ b/src/utils/Random.cpp @@ -1,66 +1,45 @@ -#include -#include - #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(); +} \ No newline at end of file diff --git a/src/utils/Random.hpp b/src/utils/Random.hpp index 501f06a..f01df0f 100755 --- a/src/utils/Random.hpp +++ b/src/utils/Random.hpp @@ -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]; }; } \ No newline at end of file