libcruft-util/test/rand/buckets.cpp

66 lines
2.3 KiB
C++
Raw Normal View History

#include <cruft/util/rand/xorshift.hpp>
#include <cruft/util/rand/lcg.hpp>
#include <cruft/util/rand/mwc64x.hpp>
#include <cruft/util/rand/pcg.hpp>
#include <cruft/util/rand/rdrand.hpp>
#include <cruft/util/rand/system.hpp>
#include <cruft/util/rand/xoshiro.hpp>
#include <cruft/util/rand/splitmix64.hpp>
2016-02-03 12:13:03 +11:00
#include <cruft/util/tap.hpp>
#include <cruft/util/maths.hpp>
#include <cruft/util/types/string.hpp>
#include <cruft/util/introspection/name.hpp>
2016-02-03 12:13:03 +11:00
/// //////////////////////////////////////////////////////////////////////////////
/// Check that outputs from a UniformRandomBitGenerator are roughly divisible
/// between a number of fixed width buckets.
2016-02-03 12:13:03 +11:00
///
/// This is not anything close to a strict statistical test. It is more aimed
2016-02-03 12:13:03 +11:00
/// at link testing and basic functionality verification within a small
/// resource footprint (ie, fast unit testing).
template <typename GeneratorT, typename ...Args>
static void
test_buckets (cruft::TAP::logger &tap, Args&& ...args)
2016-02-03 12:13:03 +11:00
{
constexpr unsigned BUCKET_BITS = 8u;
constexpr size_t BUCKET_COUNT = 1u << BUCKET_BITS;
constexpr unsigned EXPECTED = 1024u;
constexpr unsigned ITERATIONS = BUCKET_COUNT * EXPECTED;
GeneratorT gen (std::forward<Args> (args)...);
std::uniform_int_distribution<int> dist (0, BUCKET_COUNT - 1);
2016-02-03 12:13:03 +11:00
unsigned buckets[BUCKET_COUNT] = {};
2016-02-03 12:13:03 +11:00
for (unsigned i = 0; i < ITERATIONS; ++i)
++buckets[dist (gen)];
2016-02-03 12:13:03 +11:00
2016-06-30 18:15:05 +10:00
tap.expect (
std::find_if (std::cbegin (buckets),
std::cend (buckets),
[] (auto v) { return v < EXPECTED * 7 / 8; }) == std::cend (buckets),
2021-04-13 16:05:08 +10:00
"bucket counts for {:s}", cruft::introspection::name::full<GeneratorT> ()
);
2016-02-03 12:13:03 +11:00
}
///////////////////////////////////////////////////////////////////////////////
int
main (int,char**)
{
cruft::TAP::logger tap;
2016-02-03 12:13:03 +11:00
test_buckets<cruft::rand::splitmix64> (tap, 0x1234u);
2020-08-17 14:30:55 +10:00
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);
test_buckets<cruft::rand::mwc64x> (tap, 0x1234u);
2019-02-21 20:53:58 +11:00
test_buckets<cruft::rand::pcg_xsh_rr<>> (tap, 0x1234u);
test_buckets<cruft::rand::system> (tap);
2019-06-19 12:02:50 +10:00
test_buckets<cruft::rand::rdrand> (tap);
2016-02-03 12:13:03 +11:00
return tap.status ();
}