diff options
author | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
---|---|---|
committer | Jan Huwald <jh@sotun.de> | 2012-05-07 20:01:51 (GMT) |
commit | 420d2ef464d4a741028e132e662d5626806a41f5 (patch) | |
tree | 1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/rng.hpp |
Diffstat (limited to 'core/rng.hpp')
-rw-r--r-- | core/rng.hpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/core/rng.hpp b/core/rng.hpp new file mode 100644 index 0000000..a8d88f6 --- /dev/null +++ b/core/rng.hpp @@ -0,0 +1,83 @@ +#ifndef eyNJdhz0jqVQc4zddlEi67woThg +#define eyNJdhz0jqVQc4zddlEi67woThg + +// TODO: use proper PRNG + +#include <stdlib.h> +#include <inttypes.h> +#include <math.h> +#include <boost/random.hpp> +#include <boost/random/uniform_int.hpp> +#include <boost/random/exponential_distribution.hpp> +#include <boost/random/variate_generator.hpp> +#include <boost/static_assert.hpp> + +#include "template_helpers.hpp" + +#include <boost/random/ranlux.hpp> +#include <boost/random/additive_combine.hpp> + +namespace RNG { + typedef boost::ecuyer1988 generator; + struct seed_t { + generator rng; + + seed_t() : rng(0) {} + template<typename T> + explicit seed_t(T x) : rng(x + 17 * x + 257 * x) {} + + seed_t & operator= (seed_t x) { + rng = x.rng; + return *this; + } + template<typename T> + seed_t & operator= (T x) { + rng.seed(x); + return *this; + } + }; + + seed_t next(seed_t last, int amount=1) { + boost::uniform_int<uint64_t> dist; + for (int i=0; i<amount; i++) + dist(last.rng); + return last; + } + + seed_t split(seed_t old) { + boost::uniform_int<uint64_t> 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<uint32_t> gen(0, num-1); + return gen(s.rng); + } + + // returns val \in [0,1) + double equi(seed_t s) { + boost::uniform_01<double> dist; + return dist(s.rng); + } + + double expo(seed_t s, double mean) { + typedef boost::exponential_distribution<double> dist; + boost::variate_generator<generator &, dist> 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 |