summaryrefslogtreecommitdiff
path: root/core/rng.hpp
blob: a8d88f6f77e3db8a6655e919beb0c210c67b7c00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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