faunus
random.h
1 #pragma once
2 #include <random>
3 #include <vector>
4 #include <cassert>
5 #include <stdexcept>
6 #include <Eigen/Core>
7 #include <nlohmann/json.hpp>
8 
9 #ifdef ENABLE_PCG
10 #include <pcg_random.hpp>
11 #endif
12 
13 namespace Faunus {
14 
15 using Point = Eigen::Vector3d;
16 
17 #ifdef ENABLE_PCG
18 using RandomNumberEngine = pcg32;
19 #else
20 using RandomNumberEngine = std::mt19937;
21 #endif
22 
34 class Random
35 {
36  private:
37  std::uniform_real_distribution<double> dist01;
38  public:
39  RandomNumberEngine engine;
40  Random();
41  void seed();
42  double operator()();
43 
50  auto range(std::integral auto min, std::integral auto max)
51  {
52  return std::uniform_int_distribution<>(min, max)(engine);
53  }
54 
61  template <typename Iterator> Iterator sample(Iterator begin, Iterator end)
62  {
63  std::advance(begin, range<>(0, std::distance(begin, end) - 1));
64  return begin;
65  }
66 };
67 
68 void to_json(nlohmann::json&, const Random&);
69 void from_json(const nlohmann::json&, Random&);
70 
71 extern Random random;
72 
83 template <typename T> class WeightedDistribution
84 {
85  private:
86  std::discrete_distribution<> distribution;
87  std::vector<double> weights;
88  size_t latest_index;
89  public:
90  std::vector<T> data;
91 
92  auto size() const { return data.size(); }
93 
94  [[nodiscard]] bool empty() const { return data.empty(); }
95 
96  [[nodiscard]] size_t getLastIndex() const
97  {
98  assert(!data.empty());
99  return latest_index;
100  }
101 
102  void clear()
103  {
104  data.clear();
105  weights.clear();
106  }
107 
116  template <typename Iterator> void setWeight(Iterator begin, Iterator end)
117  {
118  // Disable assert fow now
119  // see
120  // https://stackoverflow.com/questions/74496713/how-to-get-the-type-of-the-values-in-a-c20-stdranges-range
121  // static_assert(std::is_convertible_v<std::ranges::range_value_t<Iterator>, double>);
122  if (auto size = std::distance(begin, end); size == data.size()) {
123  weights.resize(size);
124  std::copy(begin, end, weights.begin());
125  distribution = std::discrete_distribution(weights.begin(), weights.end());
126  assert(size_t(distribution.max()) == data.size() - 1);
127  }
128  else {
129  throw std::runtime_error("number of weights must match data");
130  }
131  }
132 
138  void push_back(const T& value, double weight = 1.0)
139  {
140  data.push_back(value);
141  weights.push_back(weight);
142  setWeight(weights.begin(), weights.end());
143  latest_index = data.size() - 1;
144  }
145 
151  template <typename RandomGenerator> const T& sample(RandomGenerator& engine)
152  {
153  assert(not empty());
154  latest_index = distribution(engine);
155  return data.at(latest_index);
156  }
157 };
158 
160  Random& rand,
161  const Point& directions =
162  Point::Ones());
163 
165  Random& rand);
166 
167 } // namespace Faunus
Point randomUnitVector(Random &rand, const Point &directions=Point::Ones())
Random unit vector using Neuman&#39;s method ("sphere picking")
void push_back(const T &value, double weight=1.0)
Add data and it&#39;s weight.
Definition: random.h:138
Eigen::Vector3d Point
3D vector used for positions, velocities, forces etc.
Definition: coordinates.h:7
void setWeight(Iterator begin, Iterator end)
Set weights for all data points in vec
Definition: random.h:116
auto range(std::integral auto min, std::integral auto max)
Integer in closed interval [min:max].
Definition: random.h:50
Random random
global instance of Random
Definition: random.cpp:62
Random number generator.
Definition: random.h:34
double operator()()
Random double in uniform range [0,1)
Definition: random.cpp:57
double T
floating point size
Definition: units.h:73
bool empty() const
True if no data points.
Definition: random.h:94
const T & sample(RandomGenerator &engine)
Get random data point respecting the weighted distribution.
Definition: random.h:151
Iterator sample(Iterator begin, Iterator end)
Pick random element in iterable range.
Definition: random.h:61
Point randomUnitVectorPolar(Random &rand)
Random unit vector using polar coordinates ("sphere picking")
void seed()
Set a non-deterministic ("hardware") seed.
Definition: random.cpp:47
auto size() const
Number of data points.
Definition: random.h:92
void clear()
Clear all data.
Definition: random.h:102
Random()
Constructor with deterministic seed.
Definition: random.cpp:52
Cell list class templates.
Definition: actions.cpp:11
Stores a series of elements with given weight.
Definition: random.h:83
std::vector< T > data
raw vector of T
Definition: random.h:90
RandomNumberEngine engine
Random number engine used for all operations.
Definition: random.h:39
size_t getLastIndex() const
index of last get() or addGroup() element
Definition: random.h:96