#include "../rng.h" #include "mt19937.h" // more specifically this will be mt19937 - 32 bit namespace splat { std::array mt19937_init(uint32_t seed){ std::array 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 mt19937_twist(const std::array& state){ std::array 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 mt19937_temper(const std::array& state){ std::array 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"; } }