random: remove typed randomisers without generators
This commit is contained in:
parent
9a6a406fa2
commit
246357e279
@ -216,7 +216,6 @@ UTIL_FILES = \
|
||||
rand/mwc64x.hpp \
|
||||
random.cpp \
|
||||
random.hpp \
|
||||
random.ipp \
|
||||
range.cpp \
|
||||
range.hpp \
|
||||
range.ipp \
|
||||
@ -435,7 +434,6 @@ TEST_BIN = \
|
||||
test/pool \
|
||||
test/quaternion \
|
||||
test/rand/buckets \
|
||||
test/random \
|
||||
test/range \
|
||||
test/rational \
|
||||
test/region \
|
||||
|
19
colour.cpp
19
colour.cpp
@ -18,7 +18,6 @@
|
||||
|
||||
#include "./debug.hpp"
|
||||
#include "./range.hpp"
|
||||
#include "./random.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
@ -361,24 +360,6 @@ namespace json { namespace tree {
|
||||
} }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template<>
|
||||
colour4f
|
||||
random (void) {
|
||||
return colour4f ({ range<float>::UNIT.random (),
|
||||
range<float>::UNIT.random (),
|
||||
range<float>::UNIT.random (),
|
||||
range<float>::UNIT.random () });
|
||||
}
|
||||
|
||||
template <>
|
||||
colour4f&
|
||||
randomise (colour4f &c)
|
||||
{ return c = random<colour4f> (); }
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <size_t S, typename T>
|
||||
std::ostream&
|
||||
|
@ -47,9 +47,9 @@ tmpname (std::string &str, size_t length)
|
||||
"0123456789";
|
||||
|
||||
str.resize (length);
|
||||
std::generate_n (str.begin (),
|
||||
length,
|
||||
[&] (void) { return util::choose (alphanum); });
|
||||
std::generate_n (str.begin (), length, [&] (void) {
|
||||
return util::rand::choose (alphanum);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
43
random.cpp
43
random.cpp
@ -11,49 +11,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "random.hpp"
|
||||
|
||||
#include "range.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
using namespace util;
|
||||
|
||||
namespace util {
|
||||
template <typename T>
|
||||
T
|
||||
random (void) {
|
||||
static_assert (std::is_integral<T>::value, "random should only operate on integral types");
|
||||
return range<T>::UNLIMITED.random ();
|
||||
}
|
||||
|
||||
template <>
|
||||
double
|
||||
random (void)
|
||||
{ return range<double>::UNIT.random (); }
|
||||
|
||||
template <>
|
||||
float
|
||||
random (void)
|
||||
{ return range<float>::UNIT.random (); }
|
||||
|
||||
template <>
|
||||
bool
|
||||
random (void)
|
||||
{ return rand () & 0x01; }
|
||||
|
||||
template <typename T>
|
||||
T&
|
||||
randomise (T &val)
|
||||
{ return val = util::random<T> (); }
|
||||
}
|
||||
|
||||
template double util::random (void);
|
||||
template float util::random (void);
|
||||
template uint64_t util::random (void);
|
||||
template uint32_t util::random (void);
|
||||
template uint16_t util::random (void);
|
||||
|
52
random.hpp
52
random.hpp
@ -11,50 +11,40 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_RANDOM_HPP
|
||||
#define __UTIL_RANDOM_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
|
||||
namespace util {
|
||||
template <typename T>
|
||||
T& randomise (T &);
|
||||
|
||||
template <typename T, size_t N>
|
||||
T* randomise (T(&)[N]);
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace util::rand {
|
||||
//-------------------------------------------------------------------------
|
||||
using default_generator = std::minstd_rand;
|
||||
|
||||
template <typename T>
|
||||
T random (void);
|
||||
|
||||
template <typename T>
|
||||
typename T::value_type&
|
||||
choose (T &container) {
|
||||
typename T::iterator cursor = container.begin ();
|
||||
typename T::size_type size = container.size ();
|
||||
typename T::size_type offset = random<typename T::size_type> () % size;
|
||||
|
||||
std::advance (cursor, offset);
|
||||
return *cursor;
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename Generator = default_generator>
|
||||
Generator&
|
||||
thread_engine (void)
|
||||
{
|
||||
std::random_device rd;
|
||||
thread_local Generator gen (rd ());
|
||||
return gen;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename Generator = default_generator, typename T, size_t N>
|
||||
T&
|
||||
choose (T (&v)[N]) {
|
||||
return v[static_cast<size_t> (random<float> () * N)];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename T::value_type&
|
||||
choose (T begin, T end) {
|
||||
typename T::difference_type size = std::distance (begin, end);
|
||||
std::advance (begin, random<T::size_type> () % size);
|
||||
return *begin;
|
||||
choose (T (&t)[N], Generator gen = thread_engine<Generator> ())
|
||||
{
|
||||
std::uniform_int_distribution<size_t> dist (0, N-1);
|
||||
return t[dist (gen)];
|
||||
}
|
||||
}
|
||||
|
||||
#include "random.ipp"
|
||||
|
||||
#endif
|
||||
|
33
random.ipp
33
random.ipp
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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 2010 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifdef __UTIL_RANDOM_IPP
|
||||
#error Double inclusion of util/random.ipp
|
||||
#endif
|
||||
|
||||
#define __UTIL_RANDOM_IPP
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template <typename T, size_t N>
|
||||
T* randomise (T (&array)[N]) {
|
||||
for (auto &i: array)
|
||||
i = random<T> ();
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
#include "random.hpp"
|
||||
#include "debug.hpp"
|
||||
#include "tap.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TODO: Use a more robust test like Chi-Square
|
||||
void
|
||||
test_bool (util::TAP::logger &tap)
|
||||
{
|
||||
static const unsigned ITERATIONS = 8192;
|
||||
static const unsigned THRESHOLD = ITERATIONS / 10;
|
||||
|
||||
unsigned counts[2] = { 0, 0 };
|
||||
for (unsigned i = 0; i < ITERATIONS; ++i)
|
||||
++counts[util::random<bool> () ? 0 : 1];
|
||||
|
||||
unsigned diff = counts[0] > counts[1] ?
|
||||
counts[0] - counts[1] :
|
||||
counts[1] - counts[0];
|
||||
|
||||
tap.expect_lt (diff, THRESHOLD, "approximately even bool distribution");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TODO: Use a more robust test like Kolmogorov-Smirnov
|
||||
void
|
||||
test_float (util::TAP::logger &tap)
|
||||
{
|
||||
static const unsigned BUCKETS = 8;
|
||||
static const unsigned ITERATIONS = 8912;
|
||||
static const unsigned EXPECTED = ITERATIONS / BUCKETS;
|
||||
static const float THRESHOLD = EXPECTED / 10;
|
||||
|
||||
unsigned counts[BUCKETS] = { 0 };
|
||||
for (unsigned i = 0; i < ITERATIONS; ++i)
|
||||
++counts[unsigned (util::random<float> () * BUCKETS)];
|
||||
|
||||
bool success = true;
|
||||
for (unsigned c: counts) {
|
||||
unsigned diff = EXPECTED > c ?
|
||||
EXPECTED - c :
|
||||
c - EXPECTED;
|
||||
|
||||
success = success && diff < THRESHOLD;
|
||||
}
|
||||
|
||||
tap.expect (success, "approximately equal float buckets");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
main (int, char **) {
|
||||
util::TAP::logger tap;
|
||||
|
||||
srand (0u);
|
||||
|
||||
test_bool (tap);
|
||||
test_float (tap);
|
||||
|
||||
return tap.status ();
|
||||
}
|
17
vector.cpp
17
vector.cpp
@ -17,7 +17,6 @@
|
||||
#include "vector.hpp"
|
||||
|
||||
#include "debug.hpp"
|
||||
#include "random.hpp"
|
||||
|
||||
#include "json/tree.hpp"
|
||||
|
||||
@ -177,17 +176,5 @@ INSTANTIATE(double)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace util {
|
||||
template vector<2,float> polar_to_cartesian (util::vector<2,float>);
|
||||
template vector<2,float> cartesian_to_polar (util::vector<2,float>);
|
||||
|
||||
template <> vector<1,float> random (void) { util::vector<1,float> out; randomise (out.data); return out; }
|
||||
template <> vector<2,float> random (void) { util::vector<2,float> out; randomise (out.data); return out; }
|
||||
template <> vector<3,float> random (void) { util::vector<3,float> out; randomise (out.data); return out; }
|
||||
template <> vector<4,float> random (void) { util::vector<4,float> out; randomise (out.data); return out; }
|
||||
|
||||
template <> vector<1,double> random (void) { util::vector<1,double> out; randomise (out.data); return out; }
|
||||
template <> vector<2,double> random (void) { util::vector<2,double> out; randomise (out.data); return out; }
|
||||
template <> vector<3,double> random (void) { util::vector<3,double> out; randomise (out.data); return out; }
|
||||
template <> vector<4,double> random (void) { util::vector<4,double> out; randomise (out.data); return out; }
|
||||
}
|
||||
template vector<2,float> util::polar_to_cartesian (util::vector<2,float>);
|
||||
template vector<2,float> util::cartesian_to_polar (util::vector<2,float>);
|
||||
|
Loading…
Reference in New Issue
Block a user