rand: add mwc64x generator
This commit is contained in:
parent
3b82757e5c
commit
2e700e6444
@ -210,6 +210,8 @@ UTIL_FILES = \
|
||||
rand/lcg.hpp \
|
||||
rand/xorshift.cpp \
|
||||
rand/xorshift.hpp \
|
||||
rand/mwc64x.cpp \
|
||||
rand/mwc64x.hpp \
|
||||
random.cpp \
|
||||
random.hpp \
|
||||
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/lcg.hpp"
|
||||
#include "rand/mwc64x.hpp"
|
||||
|
||||
#include "tap.hpp"
|
||||
#include "maths.hpp"
|
||||
@ -15,9 +16,9 @@ template <>
|
||||
std::string
|
||||
type_to_string<util::rand::xorshift<uint64_t>> (void) { return "xorshift<uint64_t>"; }
|
||||
|
||||
template <>
|
||||
std::string
|
||||
type_to_string<util::rand::lcg_t> (void) { return "lcg_t"; }
|
||||
template <> 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)
|
||||
++buckets[gen () & BUCKET_MASK];
|
||||
|
||||
tap.expect (std::find_if (std::cbegin (buckets),
|
||||
std::cend (buckets),
|
||||
[] (auto v) { return v < EXPECTED * 3 / 4; }) == std::cend (buckets),
|
||||
"bucket counts for %s", type_to_string<G> ());
|
||||
tap.expect (
|
||||
std::find_if (std::cbegin (buckets),
|
||||
std::cend (buckets),
|
||||
[] (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<uint64_t>> (tap, 0x1234u);
|
||||
test_buckets<util::rand::lcg_t> (tap, 0x1234u);
|
||||
test_buckets<util::rand::mwc64x> (tap, 0x1234u);
|
||||
|
||||
return tap.status ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user