A wrapper for the splitmix64, xoroshiro128+, xorshift128+, and xorshift1024* PRNGs. Derived from their respective public-domain C implementations.
See LICENSE for details.
Please see http://xoroshiro.di.unimi.it for an overview of the PRNGs and their preferred use cases. For parallel simulations, xorshift1024* is recommended, otherwise xoroshiro128+. splitmix64 is convenient for seeding PRNG states.
auto now = [](){
return std::chrono::system_clock::now().time_since_epoch().count();
};
// splitmix64
xs::SplitMix64 sm64(now());
std::cout << "SplitMix64: " << sm64.Next() << std::endl;
// xorshift128
std::array<uint64_t, xs::Xorshift128::STATE_SIZE> state2;
std::generate(state2.begin(), state2.end(), now);
xs::Xorshift128 xs128(state2);
std::cout << "Xorshift128: " << xs128.Next() << std::endl;
// xoroshiro128
std::array<uint64_t, 2> state1;
state1[0] = now();
state1[1] = now();
xs::Xoroshiro128 xoro(state1);
std::vector<uint64_t> v(20);
std::cout << "Xoroshiro128: " << xoro.Next() << std::endl;
// seed splitmix64 with timestamp and then seed xorshift1024 with splitmix64
auto seed = now();
auto xs1024 = xs::SeedWithSm64<xs::Xorshift1024>(seed);
std::vector<uint64_t> vals(20);
std::generate(vals.begin(), vals.end(),
[xs1024]() mutable {return xs1024.Next();});
std::cout << "Xorshift1024: " << vals << std::endl;
// seed splitmix64 with same timestamp and then seed xorshift1024 and jump
auto xs1024_2 = xs::SeedWithSm64<xs::Xorshift1024>(seed);
xs1024_2.Jump();
std::generate(vals.begin(), vals.end(),
[xs1024_2]() mutable {return xs1024_2.Next();});
std::cout << "Xorshift1024_Jumped: " << vals << std::endl;