126 lines
3.3 KiB
C++
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;
|
|
// }
|
|
// };
|
|
// }
|