Added random numbers generation Parl-Miller and xorshift enhanced (xorwow). Added specific operator<< routines for std::vector and std::list that DO NOT conflict with other implementations of operator<<.

This commit is contained in:
Jérôme 2019-05-02 08:35:38 +02:00
parent 8ecc9a2518
commit 7ceb416bec

View file

@ -34,19 +34,35 @@ T clamp(const T & x, const T & a, const T & b)
return x;
}
/// VERY simple uniform random numbers generator (Park Miller)
///
/// http://www.cems.uwe.ac.uk/~irjohnso/coursenotes/ufeen8-15-m/p1192-parkmiller.pdf
/// http://www0.cs.ucl.ac.uk/staff/ucacbbl/ftp/papers/langdon_2009_CIGPU.pdf
template<int x=1>
int intrnd(int & seed) // 1 <= seed < m
#ifndef UTILS_NO_OSTREAM_OPERATOR
#include <vector>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T> & objs)
{
const int a = 16807; //ie 7**5
const int m = 2147483647; //ie 2**31-1
seed = (long(seed) * a) % m;
return seed;
for(auto const& obj : objs)
os << obj << ' ';
return os;
}
#include <list>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::list<T> & objs)
{
for(auto const& obj : objs)
os << obj << ' ';
return os;
}
/*
/// An implementation of operator<< for ostream, (to print std::vector, std::list, etc).
template<typename T, template<class> class C>
std::ostream& operator<<(std::ostream& os, const C<T> & objs)
{
for (auto const& obj : objs)
os << obj << ' ';
return os;
}//*/
/*
/// Generic operator<< for ostream, (to print std::vector, etd::list, std::map, etc). Can generate conflicts with specialized operator<< overloads.
template<typename T, template<class,class...> class C, class... Args>
@ -57,6 +73,48 @@ std::ostream& operator<<(std::ostream& os, const C<T,Args...>& objs)
return os;
}//*/
#endif
// Define UTILS_NO_RAND to deactivate the pseudo random number generation (and the inclusion of cstdint).
#ifndef UTILS_NO_RAND
#include <cstdint>
/// Pseudo-random number generator algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs".
///
/// The period is 2^160-2^32 ~= 10^48 numbers.
/// The first 4 elements of the state must be initialized to non-zero elements. The 5th element can also be zero.
/// Performs well but fails a few tests in BigCrush.
/// https://en.wikipedia.org/wiki/Xorshift#xorwow
template<int N=1>
uint32_t rand_xorwow(uint32_t state[5])
{
uint32_t s, t = state[3];
state[3] = state[2];
state[2] = state[1];
state[1] = s = state[0];
t ^= t >> 2;
t ^= t << 1;
state[0] = t ^= s ^ (s << 4);
return t + (state[4] += 362437);
}
/// VERY simple uniform random numbers generator (Park Miller).
///
/// The period is 2^31-1 = 2147483647 numbers.
/// http://www.cems.uwe.ac.uk/~irjohnso/coursenotes/ufeen8-15-m/p1192-parkmiller.pdf
/// http://www0.cs.ucl.ac.uk/staff/ucacbbl/ftp/papers/langdon_2009_CIGPU.pdf
template<int N=1>
int32_t rand_parkmiller(int32_t & seed) // 1 <= seed < m
{
const int32_t a = 16807; // ie 7**5
const int32_t m = 2147483647; // ie 2**31-1
seed = (int64_t(seed) * a) % m;
return seed;
}
#endif
// Define UTILS_NO_CHRONO to deactivate the chronometer.
#ifndef UTILS_NO_CHRONO
@ -310,7 +368,7 @@ class Profiler
// Display the list sorted by descending line time
{
// convert the map to a vector of pairs...
// convert the static array to a vector of pairs...
std::vector<std::pair<int,int64_t>> line_times_vec;
for (size_t i = 0; i < UTILS_PROFILER_NMAX; i++)
if(line_times[i] != 0)