random: remove typed randomisers without generators
This commit is contained in:
parent
9a6a406fa2
commit
246357e279
@ -216,7 +216,6 @@ UTIL_FILES = \
|
|||||||
rand/mwc64x.hpp \
|
rand/mwc64x.hpp \
|
||||||
random.cpp \
|
random.cpp \
|
||||||
random.hpp \
|
random.hpp \
|
||||||
random.ipp \
|
|
||||||
range.cpp \
|
range.cpp \
|
||||||
range.hpp \
|
range.hpp \
|
||||||
range.ipp \
|
range.ipp \
|
||||||
@ -435,7 +434,6 @@ TEST_BIN = \
|
|||||||
test/pool \
|
test/pool \
|
||||||
test/quaternion \
|
test/quaternion \
|
||||||
test/rand/buckets \
|
test/rand/buckets \
|
||||||
test/random \
|
|
||||||
test/range \
|
test/range \
|
||||||
test/rational \
|
test/rational \
|
||||||
test/region \
|
test/region \
|
||||||
|
19
colour.cpp
19
colour.cpp
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "./debug.hpp"
|
#include "./debug.hpp"
|
||||||
#include "./range.hpp"
|
#include "./range.hpp"
|
||||||
#include "./random.hpp"
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#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>
|
template <size_t S, typename T>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
|
@ -47,9 +47,9 @@ tmpname (std::string &str, size_t length)
|
|||||||
"0123456789";
|
"0123456789";
|
||||||
|
|
||||||
str.resize (length);
|
str.resize (length);
|
||||||
std::generate_n (str.begin (),
|
std::generate_n (str.begin (), length, [&] (void) {
|
||||||
length,
|
return util::rand::choose (alphanum);
|
||||||
[&] (void) { return util::choose (alphanum); });
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
43
random.cpp
43
random.cpp
@ -11,49 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "random.hpp"
|
#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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2016 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_RANDOM_HPP
|
#ifndef __UTIL_RANDOM_HPP
|
||||||
#define __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&
|
template <typename Generator = default_generator>
|
||||||
choose (T &container) {
|
Generator&
|
||||||
typename T::iterator cursor = container.begin ();
|
thread_engine (void)
|
||||||
typename T::size_type size = container.size ();
|
{
|
||||||
typename T::size_type offset = random<typename T::size_type> () % size;
|
std::random_device rd;
|
||||||
|
thread_local Generator gen (rd ());
|
||||||
std::advance (cursor, offset);
|
return gen;
|
||||||
return *cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename Generator = default_generator, typename T, size_t N>
|
||||||
T&
|
T&
|
||||||
choose (T (&v)[N]) {
|
choose (T (&t)[N], Generator gen = thread_engine<Generator> ())
|
||||||
return v[static_cast<size_t> (random<float> () * N)];
|
{
|
||||||
}
|
std::uniform_int_distribution<size_t> dist (0, N-1);
|
||||||
|
return t[dist (gen)];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "random.ipp"
|
|
||||||
|
|
||||||
#endif
|
#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 "vector.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "random.hpp"
|
|
||||||
|
|
||||||
#include "json/tree.hpp"
|
#include "json/tree.hpp"
|
||||||
|
|
||||||
@ -177,17 +176,5 @@ INSTANTIATE(double)
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
namespace util {
|
template vector<2,float> util::polar_to_cartesian (util::vector<2,float>);
|
||||||
template vector<2,float> polar_to_cartesian (util::vector<2,float>);
|
template vector<2,float> util::cartesian_to_polar (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; }
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user