SPH
Rng.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 #include "objects/geometry/Box.h"
11 #include <random>
12 
14 
16 class UniformRng : public Noncopyable {
17 private:
18  std::mt19937_64 mt;
19 
23  std::uniform_real_distribution<Float> dist;
24 
25 public:
26  explicit UniformRng(const int seed = 1234) {
27  mt = std::mt19937_64(seed);
28  }
29 
31  : mt(other.mt)
32  , dist(other.dist) {}
33 
34  Float operator()(const int UNUSED(s) = 0) {
35  return dist(mt);
36  }
37 };
38 
39 
43 class BenzAsphaugRng : public Noncopyable {
44 private:
45  const int seed;
46  const int im1 = 2147483563;
47  const int im2 = 2147483399;
48  const Float am = 1._f / im1;
49  const int imm1 = im1 - 1;
50  const int ia1 = 40014;
51  const int ia2 = 40692;
52  const int iq1 = 53668;
53  const int iq2 = 52774;
54  const int ir1 = 12211;
55  const int ir2 = 3791;
56  const Float eps = 1.2e-7_f;
57  const Float rnmx = 1._f - eps;
58 
59  static constexpr int ntab = 32;
61  int iy = 0;
62  int idum2 = 123456789;
63  int idum;
64 
65 public:
66  explicit BenzAsphaugRng(const int seed);
67 
69 
70  Float operator()(const int s = 0);
71 };
72 
74 class HaltonQrng : public Noncopyable {
75 private:
76  static const int dimension = 6;
79 
80 public:
81  HaltonQrng();
82 
83  HaltonQrng(HaltonQrng&& other);
84 
85  Float operator()(const int s);
86 };
87 
88 
90 class IRng : public Polymorphic {
91 public:
93  virtual Float operator()(const int s = 0) = 0;
94 };
95 
96 template <typename TRng>
97 class RngWrapper : public IRng {
98 private:
99  TRng rng;
100 
101 public:
102  template <typename... TArgs>
103  explicit RngWrapper(TArgs&&... args)
104  : rng(std::forward<TArgs>(args)...) {}
105 
106  virtual Float operator()(const int s) override {
107  return rng(s);
108  }
109 };
110 
111 template <typename TRng, typename... TArgs>
113  return makeAuto<RngWrapper<TRng>>(std::forward<TArgs>(args)...);
114 }
115 
119 template <typename TRng>
120 INLINE Float sampleNormalDistribution(TRng& rng, const Float mu, const Float sigma) {
121  static const Float epsilon = std::numeric_limits<Float>::min();
122 
123  Float u1, u2;
124  do {
125  u1 = rng();
126  u2 = rng();
127  } while (u1 <= epsilon);
128 
129  const Float z1 = sqrt(-2._f * log(u1)) * cos(2._f * PI * u2);
130  SPH_ASSERT(isReal(z1));
131  return z1 * sigma + mu;
132 }
133 
137 template <typename TRng>
139  static const Float epsilon = std::numeric_limits<Float>::min();
140 
141  Float u;
142  do {
143  u = rng();
144  } while (u <= epsilon);
145  return -log(rng()) / lambda;
146 }
147 
151 template <typename TRng>
152 INLINE Size samplePoissonDistribution(TRng& rng, const Float lambda) {
153  const Float l = exp(-lambda);
154  Size k = 0;
155  Float p = 1;
156  do {
157  k = k + 1;
158  const Float u = rng();
159  p = p * u;
160  } while (p > l);
161  return k - 1;
162 }
163 
165 template <typename TRng>
167  const Float phi = rng() * 2._f * PI;
168  const Float z = rng() * 2._f - 1._f;
169  const Float u = sqrt(1._f - sqr(z));
170 
171  return Vector(u * cos(phi), u * sin(phi), z);
172 }
173 
174 
183 template <typename TRng, typename TFunc>
184 INLINE Float sampleDistribution(TRng& rng, const Interval& range, const Float upperBound, const TFunc& func) {
185  while (true) {
186  const Float x = range.lower() + rng() * range.size();
187  const Float y = rng() * upperBound;
188  const Float pdf = func(x);
189  SPH_ASSERT(pdf >= 0._f && pdf < upperBound, pdf);
190  if (y < pdf) {
191  return x;
192  }
193  }
194 }
195 
202 template <typename TRng, typename TFunc>
203 INLINE Vector sampleDistribution(TRng& rng, const Box& box, const Float upperBound, const TFunc& func) {
204  while (true) {
205  const Vector r = box.lower() + Vector(rng(), rng(), rng()) * box.size();
206  const Float y = rng() * upperBound;
207  const Float pdf = func(r);
208  SPH_ASSERT(pdf >= 0._f && pdf < upperBound, pdf);
209  if (y < pdf) {
210  return r;
211  }
212  }
213 }
214 
INLINE bool isReal(const AntisymmetricTensor &t)
Generic dynamically allocated resizable storage.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
Simplified implementation of std::unique_ptr, using only default deleter.
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Object representing a three-dimensional axis-aligned box.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
Definition: MathBasic.h:15
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sin(const T f)
Definition: MathUtils.h:296
INLINE T cos(const T f)
Definition: MathUtils.h:291
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
INLINE T exp(const T f)
Definition: MathUtils.h:269
constexpr Float PI
Mathematical constants.
Definition: MathUtils.h:361
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
INLINE Vector sampleUnitSphere(TRng &rng)
Generates a random position on a unit sphere.
Definition: Rng.h:166
AutoPtr< RngWrapper< TRng > > makeRng(TArgs &&... args)
Definition: Rng.h:112
INLINE Size samplePoissonDistribution(TRng &rng, const Float lambda)
Generates a random integer from Poisson distribution.
Definition: Rng.h:152
INLINE Float sampleExponentialDistribution(TRng &rng, const Float lambda)
Generates a random number from exponential distribution.
Definition: Rng.h:138
INLINE Float sampleNormalDistribution(TRng &rng, const Float mu, const Float sigma)
Generates a random number from normal distribution, using Box-Muller algorithm.
Definition: Rng.h:120
INLINE Float sampleDistribution(TRng &rng, const Interval &range, const Float upperBound, const TFunc &func)
Generates a random number from a generic distribution, using rejection sampling.
Definition: Rng.h:184
BasicVector< Float > Vector
Definition: Vector.h:539
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
Random number generator used in code SPH5 of Benz & Asphaug (1994).
Definition: Rng.h:43
BenzAsphaugRng(const int seed)
Definition: Rng.cpp:5
Float operator()(const int s=0)
Definition: Rng.cpp:18
Helper object defining three-dimensional interval (box).
Definition: Box.h:17
INLINE const Vector & lower() const
Returns lower bounds of the box.
Definition: Box.h:82
INLINE Vector size() const
Returns box dimensions.
Definition: Box.h:106
Quasi-random number generator.
Definition: Rng.h:74
Float operator()(const int s)
Definition: Rng.cpp:79
HaltonQrng()
Definition: Rng.cpp:70
Polymorphic holder allowing to store any RNG (type erasure).
Definition: Rng.h:90
virtual Float operator()(const int s=0)=0
Generates a random number.
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE Float lower() const
Returns lower bound of the interval.
Definition: Interval.h:74
INLINE Float size() const
Returns the size of the interval.
Definition: Interval.h:89
Definition: Rng.h:97
RngWrapper(TArgs &&... args)
Definition: Rng.h:103
virtual Float operator()(const int s) override
Generates a random number.
Definition: Rng.h:106
Random number generator with uniform distribution.
Definition: Rng.h:16
UniformRng(const int seed=1234)
Definition: Rng.h:26
UniformRng(UniformRng &&other)
Definition: Rng.h:30
Float operator()(const int UNUSED(s)=0)
Definition: Rng.h:34
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Object with deleted copy constructor and copy operator.
Definition: Object.h:54
Base class for all polymorphic objects.
Definition: Object.h:88