rand: add xoshiro256plusplus generator
This commit is contained in:
parent
4bd9ec982b
commit
fde275feb2
@ -479,8 +479,6 @@ list (
|
||||
quaternion.hpp
|
||||
rand/lcg.cpp
|
||||
rand/lcg.hpp
|
||||
rand/xorshift.cpp
|
||||
rand/xorshift.hpp
|
||||
rand/mwc64x.cpp
|
||||
rand/mwc64x.hpp
|
||||
rand/pcg.cpp
|
||||
@ -489,6 +487,10 @@ list (
|
||||
rand/rdrand.hpp
|
||||
rand/splitmix64.hpp
|
||||
rand/system.hpp
|
||||
rand/xoshiro.cpp
|
||||
rand/xoshiro.hpp
|
||||
rand/xorshift.cpp
|
||||
rand/xorshift.hpp
|
||||
random.cpp
|
||||
random.hpp
|
||||
range.cpp
|
||||
|
128
rand/xoshiro.cpp
Normal file
128
rand/xoshiro.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||
*
|
||||
* To the extent possible under law, the author has dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2020, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "xoshiro.hpp"
|
||||
#include "splitmix64.hpp"
|
||||
|
||||
#include "../bitwise.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using cruft::rand::xoshiro256plusplus;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
xoshiro256plusplus::xoshiro256plusplus (u64 _seed)
|
||||
{
|
||||
splitmix64 gen (_seed);
|
||||
std::generate (
|
||||
std::begin (m_state),
|
||||
std::end (m_state),
|
||||
gen
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
u64
|
||||
xoshiro256plusplus::operator() (void)
|
||||
{
|
||||
u64 const result = rotatel (m_state[0] + m_state[3], 23) + m_state[0];
|
||||
|
||||
u64 const t = m_state[1] << 17;
|
||||
|
||||
m_state[2] ^= m_state[0];
|
||||
m_state[3] ^= m_state[1];
|
||||
m_state[1] ^= m_state[2];
|
||||
m_state[0] ^= m_state[3];
|
||||
|
||||
m_state[2] ^= t;
|
||||
|
||||
m_state[3] = rotatel (m_state[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
xoshiro256plusplus::jump (void)
|
||||
{
|
||||
static u64 constinit JUMP[] = {
|
||||
0x180ec6d33cfd0aba,
|
||||
0xd5a61266f0c9392c,
|
||||
0xa9582618e03fc9aa,
|
||||
0x39abdc4529b1661c
|
||||
};
|
||||
|
||||
u64 s0 = 0;
|
||||
u64 s1 = 0;
|
||||
u64 s2 = 0;
|
||||
u64 s3 = 0;
|
||||
|
||||
for (std::size_t i = 0; i < std::size (JUMP); ++i) {
|
||||
for (int b = 0; b < 64; b++) {
|
||||
if (JUMP[i] & u64 (1) << b) {
|
||||
s0 ^= m_state[0];
|
||||
s1 ^= m_state[1];
|
||||
s2 ^= m_state[2];
|
||||
s3 ^= m_state[3];
|
||||
}
|
||||
(*this) ();
|
||||
}
|
||||
}
|
||||
|
||||
m_state[0] = s0;
|
||||
m_state[1] = s1;
|
||||
m_state[2] = s2;
|
||||
m_state[3] = s3;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
xoshiro256plusplus::long_jump (void)
|
||||
{
|
||||
static constinit u64 LONG_JUMP[] = {
|
||||
0x76e15d3efefdcbbf,
|
||||
0xc5004e441c522fb3,
|
||||
0x77710069854ee241,
|
||||
0x39109bb02acbe635
|
||||
};
|
||||
|
||||
u64 s0 = 0;
|
||||
u64 s1 = 0;
|
||||
u64 s2 = 0;
|
||||
u64 s3 = 0;
|
||||
|
||||
for (std::size_t i = 0; i < std::size (LONG_JUMP); ++i) {
|
||||
for (int b = 0; b < 64; b++) {
|
||||
if (LONG_JUMP[i] & u64{1} << b) {
|
||||
s0 ^= m_state[0];
|
||||
s1 ^= m_state[1];
|
||||
s2 ^= m_state[2];
|
||||
s3 ^= m_state[3];
|
||||
}
|
||||
|
||||
(*this) ();
|
||||
}
|
||||
}
|
||||
|
||||
m_state[0] = s0;
|
||||
m_state[1] = s1;
|
||||
m_state[2] = s2;
|
||||
m_state[3] = s3;
|
||||
}
|
51
rand/xoshiro.hpp
Normal file
51
rand/xoshiro.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||
*
|
||||
* To the extent possible under law, the author has dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2020, Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../std.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::rand {
|
||||
class xoshiro256plusplus {
|
||||
public:
|
||||
using result_type = u64;
|
||||
|
||||
xoshiro256plusplus (u64 seed);
|
||||
|
||||
static constexpr result_type min (void)
|
||||
{
|
||||
return std::numeric_limits<result_type>::min ();
|
||||
}
|
||||
|
||||
static constexpr result_type max (void)
|
||||
{
|
||||
return std::numeric_limits<result_type>::max ();
|
||||
}
|
||||
|
||||
result_type operator() (void);
|
||||
|
||||
void jump (void);
|
||||
void long_jump (void);
|
||||
|
||||
private:
|
||||
u64 m_state[4];
|
||||
};
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include "rand/pcg.hpp"
|
||||
#include "rand/rdrand.hpp"
|
||||
#include "rand/system.hpp"
|
||||
#include "rand/xoshiro.hpp"
|
||||
#include "rand/splitmix64.hpp"
|
||||
|
||||
#include "tap.hpp"
|
||||
@ -51,6 +52,7 @@ main (int,char**)
|
||||
cruft::TAP::logger tap;
|
||||
|
||||
test_buckets<cruft::rand::splitmix64> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::xoshiro256plusplus> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::xorshift<uint32_t>> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::xorshift<uint64_t>> (tap, 0x1234u);
|
||||
test_buckets<cruft::rand::lcg_t> (tap, 0x1234u);
|
||||
|
Loading…
Reference in New Issue
Block a user