#ifndef eyNJdhz0jqVQc4zddlEi67woThg #define eyNJdhz0jqVQc4zddlEi67woThg // TODO: use proper PRNG #include #include #include #include #include #include #include #include #include "template_helpers.hpp" #include #include namespace RNG { typedef boost::ecuyer1988 generator; struct seed_t { generator rng; seed_t() : rng(0) {} template explicit seed_t(T x) : rng(x + 17 * x + 257 * x) {} seed_t & operator= (seed_t x) { rng = x.rng; return *this; } template seed_t & operator= (T x) { rng.seed(x); return *this; } }; seed_t next(seed_t last, int amount=1) { boost::uniform_int dist; for (int i=0; i dist(0, -1); uint64_t s = 0; for (int i=0; i<37; i++) { s ^= dist(old.rng); s ^= ~(s << 1); } // std::cout << "new seed: " << s << std::endl; return seed_t(s); } uint32_t integer(seed_t s, uint32_t num) { boost::uniform_int gen(0, num-1); return gen(s.rng); } // returns val \in [0,1) double equi(seed_t s) { boost::uniform_01 dist; return dist(s.rng); } double expo(seed_t s, double mean) { typedef boost::exponential_distribution dist; boost::variate_generator gen(s.rng, dist(1.0 / mean)); double res = gen(); return res; } } namespace std { std::ostream& operator<< (std::ostream &os, RNG::seed_t s) { return os << "rand48(" << s.rng << ")"; } } #endif // eyNJdhz0jqVQc4zddlEi67woThg