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; return x;
} }
/// VERY simple uniform random numbers generator (Park Miller) #ifndef UTILS_NO_OSTREAM_OPERATOR
///
/// http://www.cems.uwe.ac.uk/~irjohnso/coursenotes/ufeen8-15-m/p1192-parkmiller.pdf #include <vector>
/// http://www0.cs.ucl.ac.uk/staff/ucacbbl/ftp/papers/langdon_2009_CIGPU.pdf template<typename T>
template<int x=1> std::ostream& operator<<(std::ostream& os, const std::vector<T> & objs)
int intrnd(int & seed) // 1 <= seed < m
{ {
const int a = 16807; //ie 7**5 for(auto const& obj : objs)
const int m = 2147483647; //ie 2**31-1 os << obj << ' ';
seed = (long(seed) * a) % m; return os;
return seed;
} }
#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. /// 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> 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; 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. // Define UTILS_NO_CHRONO to deactivate the chronometer.
#ifndef UTILS_NO_CHRONO #ifndef UTILS_NO_CHRONO
@ -310,7 +368,7 @@ class Profiler
// Display the list sorted by descending line time // 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; std::vector<std::pair<int,int64_t>> line_times_vec;
for (size_t i = 0; i < UTILS_PROFILER_NMAX; i++) for (size_t i = 0; i < UTILS_PROFILER_NMAX; i++)
if(line_times[i] != 0) if(line_times[i] != 0)