rand: add mwc64x generator
This commit is contained in:
parent
3b82757e5c
commit
2e700e6444
@ -210,6 +210,8 @@ UTIL_FILES = \
|
|||||||
rand/lcg.hpp \
|
rand/lcg.hpp \
|
||||||
rand/xorshift.cpp \
|
rand/xorshift.cpp \
|
||||||
rand/xorshift.hpp \
|
rand/xorshift.hpp \
|
||||||
|
rand/mwc64x.cpp \
|
||||||
|
rand/mwc64x.hpp \
|
||||||
random.cpp \
|
random.cpp \
|
||||||
random.hpp \
|
random.hpp \
|
||||||
random.ipp \
|
random.ipp \
|
||||||
|
45
rand/mwc64x.cpp
Normal file
45
rand/mwc64x.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "./mwc64x.hpp"
|
||||||
|
|
||||||
|
#include "../debug.hpp"
|
||||||
|
|
||||||
|
using util::rand::mwc64x;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
mwc64x::mwc64x (seed_type _seed):
|
||||||
|
m_state (_seed)
|
||||||
|
{
|
||||||
|
CHECK_NEZ (m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
mwc64x::value_type
|
||||||
|
mwc64x::operator() (void)
|
||||||
|
{
|
||||||
|
CHECK_NEZ (m_state);
|
||||||
|
|
||||||
|
uint32_t c = m_state >> 32u;
|
||||||
|
uint32_t x = m_state & 0xFFFFFFFFu;
|
||||||
|
|
||||||
|
m_state = x * 4294883355ULL + c;
|
||||||
|
|
||||||
|
return x ^ c;
|
||||||
|
}
|
43
rand/mwc64x.hpp
Normal file
43
rand/mwc64x.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UTIL_RAND_MWC64X_HPP
|
||||||
|
#define __UTIL_RAND_MWC64X_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace util { namespace rand {
|
||||||
|
// multiply-with-carry style generator suitable for rapid seeking and
|
||||||
|
// GPU generation.
|
||||||
|
//
|
||||||
|
// as with all such style generators, the seed value is very important.
|
||||||
|
// don't allow either half of the uint64_t to be zero.
|
||||||
|
struct mwc64x {
|
||||||
|
public:
|
||||||
|
using value_type = uint32_t;
|
||||||
|
using seed_type = uint64_t;
|
||||||
|
|
||||||
|
mwc64x (seed_type);
|
||||||
|
|
||||||
|
value_type operator() (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t m_state;
|
||||||
|
};
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,6 @@
|
|||||||
#include "rand/xorshift.hpp"
|
#include "rand/xorshift.hpp"
|
||||||
#include "rand/lcg.hpp"
|
#include "rand/lcg.hpp"
|
||||||
|
#include "rand/mwc64x.hpp"
|
||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
#include "maths.hpp"
|
#include "maths.hpp"
|
||||||
@ -15,9 +16,9 @@ template <>
|
|||||||
std::string
|
std::string
|
||||||
type_to_string<util::rand::xorshift<uint64_t>> (void) { return "xorshift<uint64_t>"; }
|
type_to_string<util::rand::xorshift<uint64_t>> (void) { return "xorshift<uint64_t>"; }
|
||||||
|
|
||||||
template <>
|
template <> std::string type_to_string<util::rand::lcg_t> (void) { return "lcg_t"; }
|
||||||
std::string
|
|
||||||
type_to_string<util::rand::lcg_t> (void) { return "lcg_t"; }
|
template <> std::string type_to_string<util::rand::mwc64x> (void) { return "mwc64x"; }
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -43,10 +44,11 @@ test_buckets (util::TAP::logger &tap, Args&& ...args)
|
|||||||
for (unsigned i = 0; i < ITERATIONS; ++i)
|
for (unsigned i = 0; i < ITERATIONS; ++i)
|
||||||
++buckets[gen () & BUCKET_MASK];
|
++buckets[gen () & BUCKET_MASK];
|
||||||
|
|
||||||
tap.expect (std::find_if (std::cbegin (buckets),
|
tap.expect (
|
||||||
std::cend (buckets),
|
std::find_if (std::cbegin (buckets),
|
||||||
[] (auto v) { return v < EXPECTED * 3 / 4; }) == std::cend (buckets),
|
std::cend (buckets),
|
||||||
"bucket counts for %s", type_to_string<G> ());
|
[] (auto v) { return v < EXPECTED * 7 / 8; }) == std::cend (buckets),
|
||||||
|
"bucket counts for %s", type_to_string<G> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ main (int,char**)
|
|||||||
test_buckets<util::rand::xorshift<uint32_t>> (tap, 0x1234u);
|
test_buckets<util::rand::xorshift<uint32_t>> (tap, 0x1234u);
|
||||||
test_buckets<util::rand::xorshift<uint64_t>> (tap, 0x1234u);
|
test_buckets<util::rand::xorshift<uint64_t>> (tap, 0x1234u);
|
||||||
test_buckets<util::rand::lcg_t> (tap, 0x1234u);
|
test_buckets<util::rand::lcg_t> (tap, 0x1234u);
|
||||||
|
test_buckets<util::rand::mwc64x> (tap, 0x1234u);
|
||||||
|
|
||||||
return tap.status ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user