summaryrefslogtreecommitdiff
path: root/core/rng.hpp
diff options
context:
space:
mode:
authorJan Huwald <jh@sotun.de>2012-05-07 20:01:51 (GMT)
committerJan Huwald <jh@sotun.de>2012-05-07 20:01:51 (GMT)
commit420d2ef464d4a741028e132e662d5626806a41f5 (patch)
tree1aca6eb512e4ed0fb5f3c10c528cb998b6ffd695 /core/rng.hpp
Initial commitHEADmaster
Diffstat (limited to 'core/rng.hpp')
-rw-r--r--core/rng.hpp83
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
contact: Jan Huwald // Impressum