2016-02-03 12:13:03 +11:00
|
|
|
#include "rand/xorshift.hpp"
|
|
|
|
#include "rand/lcg.hpp"
|
2016-06-30 18:15:05 +10:00
|
|
|
#include "rand/mwc64x.hpp"
|
2019-02-21 20:53:58 +11:00
|
|
|
#include "rand/pcg.hpp"
|
2019-06-19 12:02:20 +10:00
|
|
|
#include "rand/rdrand.hpp"
|
|
|
|
#include "rand/system.hpp"
|
2016-02-03 12:13:03 +11:00
|
|
|
|
|
|
|
#include "tap.hpp"
|
|
|
|
#include "maths.hpp"
|
|
|
|
#include "types/string.hpp"
|
2019-06-19 12:02:20 +10:00
|
|
|
#include "introspection.hpp"
|
2016-02-03 12:13:03 +11:00
|
|
|
|
|
|
|
|
2019-06-19 12:02:20 +10: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
|
|
|
///
|
2019-06-19 12:02:20 +10: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).
|
2019-06-19 12:02:20 +10:00
|
|
|
template <typename GeneratorT, typename ...Args>
|
|
|
|
static void
|
2018-08-05 14:42:02 +10:00
|
|
|
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;
|
|
|
|
|
2019-06-19 12:02:20 +10:00
|
|
|
GeneratorT gen (std::forward<Args> (args)...);
|
2019-02-21 20:53:07 +11:00
|
|
|
std::uniform_int_distribution<int> dist (0, BUCKET_COUNT - 1);
|
2016-02-03 12:13:03 +11:00
|
|
|
|
2019-02-21 20:53:07 +11:00
|
|
|
unsigned buckets[BUCKET_COUNT] = {};
|
2016-02-03 12:13:03 +11:00
|
|
|
for (unsigned i = 0; i < ITERATIONS; ++i)
|
2019-02-21 20:53:07 +11:00
|
|
|
++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),
|
2019-06-19 12:02:20 +10:00
|
|
|
"bucket counts for %s", cruft::type_name<GeneratorT> ()
|
|
|
|
);
|
2016-02-03 12:13:03 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
int
|
|
|
|
main (int,char**)
|
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::TAP::logger tap;
|
2016-02-03 12:13:03 +11:00
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
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);
|
2019-06-19 12:02:20 +10:00
|
|
|
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 ();
|
|
|
|
}
|