diff --git a/utils.hpp b/utils.hpp index c7366b9..0ac7b8a 100644 --- a/utils.hpp +++ b/utils.hpp @@ -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 intrnd(int & seed) // 1 <= seed < m +#ifndef UTILS_NO_OSTREAM_OPERATOR + +#include +template +std::ostream& operator<<(std::ostream& os, const std::vector & 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 +template +std::ostream& operator<<(std::ostream& os, const std::list & objs) +{ + for(auto const& obj : objs) + os << obj << ' '; + return os; +} + +/* +/// An implementation of operator<< for ostream, (to print std::vector, std::list, etc). +template class C> +std::ostream& operator<<(std::ostream& os, const C & 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 class C, class... Args> @@ -57,6 +73,48 @@ std::ostream& operator<<(std::ostream& os, const C& 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 + +/// 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 +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 +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> line_times_vec; for (size_t i = 0; i < UTILS_PROFILER_NMAX; i++) if(line_times[i] != 0)