rng/generators/mt19937.cpp
2025-07-06 17:13:58 +01:00

126 lines
3.3 KiB
C++

#include "../rng.h"
#include "mt19937.h"
// more specifically this will be mt19937 - 32 bit
namespace splat {
std::array<uint32_t,624> mt19937_init(uint32_t seed){
std::array<uint32_t,624> state;
state[0] = seed;
for(int i=1; i<624; i++){
state[i]= 1812433253*(state[i-1] ^ (state[i-1] >> 30)) + i;
}
return state;
}
std::array<uint32_t, 624> mt19937_twist(const std::array<uint32_t, 624>& state){
std::array<uint32_t,624> newstate;
for(int i=0; i<624; i++){
uint32_t x;
// concating the MSB and LSB from next
if(i+1<624){
x = (state[i] & 0x80000000) | (state[(i+1)] & 0x7FFFFFFF);
}else{
x = (state[i] & 0x80000000) | (newstate[(i+1)%624] & 0x7FFFFFFF);
}
// does the *A part
if(x&1){
x = (x>>1) ^ 0x9908B0DFUL;
}else{
x=x>>1;
}
uint32_t y;
if(i+397<624){
y = state[i+397] ^ x;
}else{
y = newstate[(i+397) % 624] ^ x;
}
newstate[i] = y;
}
return newstate;
}
std::array<uint32_t, 624> mt19937_temper(const std::array<uint32_t, 624>& state){
std::array<uint32_t, 624> tempered;
for(int i=0; i<624; i++){
uint32_t y = state[i];
y = y ^ (y >> 11);
y = y ^ ((y << 7) & 0x9D2C5680UL);
y = y ^ ((y << 15) & 0xEFC60000UL);
tempered[i] = y ^ (y >> 18);
}
return tempered;
}
mt19937_generator::mt19937_generator(uint32_t genSeed) : PRNG(genSeed) {
state = mt19937_init(seed);
nextblock();
}
void mt19937_generator::nextblock() {
state = mt19937_twist(state);
random_values = mt19937_temper(state);
position = 0;
}
uint32_t mt19937_generator::generate() {
uint32_t generated = random_values[position];
position++;
if(position>=624){
nextblock();
}
return generated;
}
std::string mt19937_generator::getName() {
return "mt19937-32 test";
}
}
// namespace splat {
// class mt19937_generator : public PRNG {
// public:
// mt19937_generator(uint32_t genSeed) : PRNG(genSeed) {
// state = mt19937_init(seed);
// nextblock();
// }
// uint32_t generate() override {
// uint32_t generated = random_values[position];
// position++;
// if(position>=624){
// nextblock();
// }
// return generated;
// }
// std::string getName() override {
// return "mt19937-32";
// }
// private:
// std::array<uint32_t,624> state;
// std::array<uint32_t,624> random_values;
// int position;
// // goes to next block of 624 values
// void nextblock() {
// state = mt19937_twist(state);
// random_values = mt19937_temper(state);
// position = 0;
// }
// };
// }