random.hpp
1 
2 #pragma once
3 
4 #include <vector>
5 
6 #ifdef USE_BOOST
7 #include <boost/random/mersenne_twister.hpp>
8 #include <boost/random/seed_seq.hpp>
9 #include <boost/random/uniform_int_distribution.hpp>
10 #include <boost/random/uniform_real_distribution.hpp>
11 #endif
12 
13 #include <algorithm> // For std::generate
14 #include <random> // For std::random_device
15 
16 namespace wdm {
17 
18 namespace random {
19 
22 {
23 public:
24  // Constructor with optional seeds
25  explicit RandomGenerator(std::vector<int> seeds = std::vector<int>())
26 #ifdef USE_BOOST
27  : generator(initialize_boost_generator(seeds)){}
28 #else
29  : generator(initialize_std_generator(seeds))
30  {
31  }
32 #endif
33 
34  // Sample a size_t in [0, n-1]
35  size_t sample_int(size_t n)
36  {
37 #ifdef USE_BOOST
38  boost::random::uniform_int_distribution<size_t> distribution(0, n - 1);
39 #else
40  std::uniform_int_distribution<size_t> distribution(0, n - 1);
41 #endif
42  return distribution(generator);
43  }
44 
45  // Sample a double in [0.0, 1.0)
46  double sample_double()
47  {
48 #ifdef USE_BOOST
49  boost::random::uniform_real_distribution<double> distribution(0.0, 1.0);
50 #else
51  std::uniform_real_distribution<double> distribution(0.0, 1.0);
52 #endif
53  return distribution(generator);
54  }
55 
56 private:
57 #ifdef USE_BOOST
58  boost::random::mt19937 generator;
59 
60  // Initialize Boost generator with seeds
61  boost::random::mt19937 initialize_boost_generator(std::vector<int>& seeds)
62  {
63  if (seeds.empty()) {
64  seeds = generate_random_seeds();
65  }
66  boost::random::seed_seq seq(seeds.begin(), seeds.end());
67  return boost::random::mt19937(seq);
68  }
69 #else
70  std::default_random_engine generator;
71 
72  // Initialize std generator with seeds
73  std::default_random_engine initialize_std_generator(std::vector<int>& seeds)
74  {
75  if (seeds.empty()) {
76  seeds = generate_random_seeds();
77  }
78  std::seed_seq seq(seeds.begin(), seeds.end());
79  return std::default_random_engine(seq);
80  }
81 #endif
82 
83  // Generate random seeds using std::random_device
84  static std::vector<int> generate_random_seeds()
85  {
86  std::random_device rd{};
87  std::vector<int> seeds(5);
88  std::generate(
89  seeds.begin(), seeds.end(), [&]() { return static_cast<int>(rd()); });
90  return seeds;
91  }
92 };
93 
94 // Custom shuffle function
95 template<typename T>
96 void
97 shuffle(std::vector<T>& vec, RandomGenerator& rand_gen)
98 {
99  for (size_t i = vec.size() - 1; i > 0; --i) {
100  size_t j = rand_gen.sample_int(i + 1); // Generate a random index in [0, i]
101  std::swap(vec[i], vec[j]);
102  }
103 }
104 
105 }
106 }
Random-number generator used for reproducible randomized tie breaking.
Definition: random.hpp:22
Weighted dependence measures.
Definition: wdm.hpp:19