Version: SMASH-3.4
smash::random Namespace Reference

Namespace random provides functions for random Number Generation. More...

Classes

class  uniform_dist
 Provides uniform random numbers on a fixed interval. More...
 
class  discrete_dist
 Discrete distribution with weight given by probability vector. More...
 
class  BesselSampler
 The intention of this class is to efficiently sample \( (N_1, N_2) \) from the Bessel distribution \( p(N_1,N_2) \sim \mathrm{Poi}(\nu_1) \mathrm{Poi}(\nu_2) \delta(N_1 - N_2 = N)\), where \(\mathrm{Poi}(\nu)\) denotes Poisson distribution with mean \(\nu\). More...
 

Typedefs

using Engine = std::mt19937_64
 The random number engine used is the Mersenne Twister. More...
 

Functions

int64_t generate_63bit_seed ()
 Generates a seed with a truly random 63-bit value, if possible. More...
 
template<typename T >
void set_seed (T &&seed)
 Sets the seed of the random number engine. More...
 
Engine::result_type advance ()
 Advance the engine's state and return the generated value. More...
 
template<typename T >
uniform (T min, T max)
 
template<typename T >
uniform_int (T min, T max)
 
template<typename T = double>
canonical ()
 
template<typename T = double>
canonical_nonzero ()
 
template<typename T >
uniform_dist< T > make_uniform_distribution (T min, T max)
 
template<typename T = double>
exponential (T lambda)
 Draws an exponentially distributed random number. More...
 
template<typename T = double>
expo (T A, T x1, T x2)
 Draws a random number x from an exponential distribution exp(A*x), where A is assumed to be positive, and x is typically negative. More...
 
template<typename T >
int sgn (T val)
 Signum function. More...
 
template<typename T = double>
power (T n, T xMin, T xMax)
 Sample from a power-law probability density proportional to |x|^n. More...
 
template<typename T >
int poisson (const T &lam)
 Returns a Poisson distributed random number. More...
 
template<typename T >
int binomial (const int N, const T &p)
 Returns a binomially distributed random number. More...
 
template<typename T >
double normal (const T &mean, const T &sigma)
 Returns a random number drawn from a normal distribution. More...
 
template<typename T = double>
cauchy (T pole, T width, T min, T max)
 Draws a random number from a Cauchy distribution (sometimes also called Lorentz or non-relativistic Breit-Wigner distribution) with the given parameters (constant width!) inside the range [min,max]. More...
 
template<typename T = double>
beta (T a, T b)
 Draws a random number from a beta-distribution, where probability density of \(x\) is \(p(x) = frac{\Gamma(a)\Gamma(b)}{Gamma(a+b)} x^{a-1} (1-x)^{b-1}\). More...
 
template<typename T = double>
beta_a0 (T xmin, T b)
 Draws a random number from a beta-distribution with a = 0. More...
 

Variables

Engine engine
 The engine that is used commonly by all distributions. More...
 

Detailed Description

Namespace random provides functions for random Number Generation.

Typedef Documentation

◆ Engine

using smash::random::Engine = typedef std::mt19937_64

The random number engine used is the Mersenne Twister.

Definition at line 30 of file random.h.

Function Documentation

◆ generate_63bit_seed()

int64_t smash::random::generate_63bit_seed ( )

Generates a seed with a truly random 63-bit value, if possible.

Definition at line 21 of file random.cc.

21  {
22  std::random_device rd;
23  static_assert(std::is_same<decltype(rd()), uint32_t>::value,
24  "random_device is assumed to generate uint32_t");
25  uint64_t unsigned_seed =
26  (static_cast<uint64_t>(rd()) << 32) | static_cast<uint64_t>(rd());
27  // Discard the highest bit to make sure it fits into a positive int64_t
28  const int64_t seed = static_cast<int64_t>(unsigned_seed >> 1);
29  return seed;
30 }
Here is the caller graph for this function:

◆ set_seed()

template<typename T >
void smash::random::set_seed ( T &&  seed)

Sets the seed of the random number engine.

Definition at line 74 of file random.h.

74  {
75  static_assert(std::is_same<Engine::result_type, uint64_t>::value,
76  "experiment.cc needs the seed to be 64 bits");
77  engine.seed(std::forward<T>(seed));
78 }
Engine engine
The engine that is used commonly by all distributions.
Definition: random.cc:19
Here is the caller graph for this function:

◆ advance()

Engine::result_type smash::random::advance ( )
inline

Advance the engine's state and return the generated value.

Definition at line 81 of file random.h.

81 { return engine(); }
Here is the caller graph for this function:

◆ uniform()

template<typename T >
T smash::random::uniform ( min,
max 
)
Returns
A uniformly distributed random real number \(\chi \in [{\rm min}, {\rm max})\)
Parameters
minMinimal sampled value.
maxMaximal sampled value.

Definition at line 91 of file random.h.

91  {
92  /* Strictly speaking, a distribution could be created with min == max, but
93  * then it would be UB to use the call operator(), which we do here. */
94  assert(min < max);
95  return std::uniform_real_distribution<T>(min, max)(engine);
96 }
Here is the caller graph for this function:

◆ uniform_int()

template<typename T >
T smash::random::uniform_int ( min,
max 
)
Returns
A uniformly distributed random integer number \(\chi \in [{\rm min}, {\rm max})\)
Parameters
minMinimal sampled value.
maxMaximal sampled value.

Definition at line 106 of file random.h.

106  {
107  /* Strictly speaking, a distribution could be created with min == max, but
108  * then it would be UB to use the call operator(), which we do here. */
109  assert(min < max);
110  return std::uniform_int_distribution<T>(min, max)(engine);
111 }
Here is the caller graph for this function:

◆ canonical()

template<typename T = double>
T smash::random::canonical ( )
Returns
a uniformly distributed random number \(\chi \in [0,1)\).

Note that the popular implementations in GCC and clang may return 1:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64351 https://llvm.org/bugs/show_bug.cgi?id=18767

Definition at line 122 of file random.h.

122  {
123  return std::generate_canonical<T, std::numeric_limits<double>::digits>(
124  engine);
125 }
Here is the caller graph for this function:

◆ canonical_nonzero()

template<typename T = double>
T smash::random::canonical_nonzero ( )
Returns
A uniformly distributed random number \(\chi \in (0,1]\).

Definition at line 131 of file random.h.

131  {
132  // use 'nextafter' to generate a value that is guaranteed to be larger than 0
133  return std::nextafter(
134  std::generate_canonical<T, std::numeric_limits<double>::digits>(engine),
135  T(1));
136 }
Here is the caller graph for this function:

◆ make_uniform_distribution()

template<typename T >
uniform_dist<T> smash::random::make_uniform_distribution ( min,
max 
)
Returns
A uniform_dist object.
Parameters
minLower bound of interval.
maxUpper bound of interval.

Definition at line 144 of file random.h.

144  {
145  return uniform_dist<T>(min, max);
146 }
Here is the caller graph for this function:

◆ exponential()

template<typename T = double>
T smash::random::exponential ( lambda)

Draws an exponentially distributed random number.

Probability for a given return value \(\chi\) is \(p(\chi) = \Theta(\chi) \cdot \exp(-t)\).

Parameters
lambdaRate parameter.
Returns
Sampled random number.

Definition at line 158 of file random.h.

158  {
159  // We are not using std::exponential_distribution because of a bug in the
160  // implementations by clang and gcc.
161  return -std::log(canonical_nonzero()) / lambda;
162 }
T canonical_nonzero()
Definition: random.h:131
Here is the call graph for this function:

◆ expo()

template<typename T = double>
T smash::random::expo ( A,
x1,
x2 
)

Draws a random number x from an exponential distribution exp(A*x), where A is assumed to be positive, and x is typically negative.

The result x is restricted to lie between x1 and x2 (with x2 < x <= x1).

Parameters
APositive shape parameter.
x1Maximal sampled value.
x2Minimal sampled value.
Returns
Sampled random number.
Exceptions
std::logic_errorif the computed sampling interval is degenerate, reversed, or otherwise invalid.

Definition at line 178 of file random.h.

178  {
179  const T a1 = A * x1, a2 = A * x2;
180  const T a_min = std::log(std::numeric_limits<T>::min());
181  assert(A > T(0.) && x1 > x2 && a1 > a_min);
182  const T high = std::exp(a1);
183  const T low = a2 > a_min ? std::exp(a2) : T(0.); // prevent underflow
184  if (unlikely(!(low < high))) { // catches NANs, too
185  std::ostringstream error_message{};
186  error_message << "Function " << __func__
187  << ": internal invariant 'low < high' violated (low = " << low
188  << ", high = " << high << ")";
189  throw std::logic_error(error_message.str());
190  }
191  T x{};
192  do {
193  /* sample repeatedly until x is in the requested range
194  * (it can get outside due to numerical errors). */
195  x = std::log(uniform(low, high)) / A;
196  } while (!(x <= x1 && x > x2));
197  return x;
198 }
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
Definition: macros.h:16
T uniform(T min, T max)
Definition: random.h:91
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sgn()

template<typename T >
int smash::random::sgn ( val)

Signum function.

Parameters
valThe input value.
Returns
The sign of the input value.

Definition at line 207 of file random.h.

207  {
208  return (T(0) < val) - (val < T(0));
209 }
Here is the caller graph for this function:

◆ power()

template<typename T = double>
T smash::random::power ( n,
xMin,
xMax 
)

Sample from a power-law probability density proportional to |x|^n.

The sample is drawn on the interval [xMin, xMax]. The interval must lie entirely on one side of zero; intervals crossing zero are not supported. Negative intervals are handled by sampling the absolute values and restoring the negative sign. For n ≈ -1, the distribution is sampled using the logarithmic limit.

Template Parameters
TFloating-point type.
Parameters
nPower-law exponent.
xMinLower interval bound.
xMaxUpper interval bound.
Returns
Random value distributed as p(x) ∝ |x|^n on the given interval.
Exceptions
std::invalid_argumentif the interval crosses zero.
std::invalid_argumentif the interval touches zero and n <= -1, where the distribution is not normalizable.

Definition at line 229 of file random.h.

229  {
230  const T n1 = n + T(1);
231 
232  if ((xMin < 0 && xMax > 0) || (xMax < 0 && xMin > 0)) {
233  throw std::invalid_argument(
234  "power: interval crossing zero is not supported");
235  } else if ((xMin == 0 || xMax == 0) && n <= -1) {
236  throw std::invalid_argument("power: distribution not normalizable at x=0");
237  }
238 
239  if (xMin > xMax) {
240  std::swap(xMin, xMax);
241  }
242  const T sign = xMax < T(0) ? T(-1) : T(1);
243 
244  const T lo = std::abs(xMin);
245  const T hi = std::abs(xMax);
246 
247  if (std::abs(n1) < T(1e-3)) {
248  return sign * lo * std::pow(hi / lo, canonical());
249  }
250 
251  T a = std::pow(lo, n1);
252  T b = std::pow(hi, n1);
253 
254  if (a > b) {
255  std::swap(a, b);
256  }
257 
258  return sign * std::pow(uniform(a, b), T(1) / n1);
259 }
constexpr int n
Neutron.
T canonical()
Definition: random.h:122
Here is the call graph for this function:
Here is the caller graph for this function:

◆ poisson()

template<typename T >
int smash::random::poisson ( const T &  lam)

Returns a Poisson distributed random number.

Probability for a given return value \(\chi\) is \(p(\chi) = \chi^i/i! \cdot \exp(-\chi)\)

Parameters
lamMean value of the distribution.
Returns
Sampled random number.

Definition at line 270 of file random.h.

270  {
271  return std::poisson_distribution<int>(lam)(engine);
272 }
Here is the caller graph for this function:

◆ binomial()

template<typename T >
int smash::random::binomial ( const int  N,
const T &  p 
)

Returns a binomially distributed random number.

Parameters
NNumber of trials.
pProbability of a trial generating true.
Returns
Sampled random number.

Definition at line 282 of file random.h.

282  {
283  return std::binomial_distribution<int>(N, p)(engine);
284 }
constexpr int p
Proton.
Here is the caller graph for this function:

◆ normal()

template<typename T >
double smash::random::normal ( const T &  mean,
const T &  sigma 
)

Returns a random number drawn from a normal distribution.

Parameters
meanMean value of the distribution.
sigmaStandard deviation of the distribution.
Returns
Sampled random number.

Definition at line 294 of file random.h.

294  {
295  return std::normal_distribution<double>(mean, sigma)(engine);
296 }
Here is the caller graph for this function:

◆ cauchy()

template<typename T = double>
T smash::random::cauchy ( pole,
width,
min,
max 
)

Draws a random number from a Cauchy distribution (sometimes also called Lorentz or non-relativistic Breit-Wigner distribution) with the given parameters (constant width!) inside the range [min,max].

This function is similar to std::cauchy_distribution, but can return values inside a limited interval.

Parameters
polePole parameter of the Cauchy function, i.e. location of the peak.
widthWidth parameter of the Cauchy function, determining the sharpness of the peak.
minMinimum value to be returned.
maxMaximum value to be returned.
Returns
Sampled random number.

Definition at line 351 of file random.h.

351  {
352  /* Use double-precision variables, in order to work around a glibc bug in
353  * tanf:
354  * https://sourceware.org/bugzilla/show_bug.cgi?id=18221 */
355  const double u_min = std::atan((min - pole) / width);
356  const double u_max = std::atan((max - pole) / width);
357  const double u = uniform(u_min, u_max);
358  return pole + width * std::tan(u);
359 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ beta()

template<typename T = double>
T smash::random::beta ( a,
b 
)

Draws a random number from a beta-distribution, where probability density of \(x\) is \(p(x) = frac{\Gamma(a)\Gamma(b)}{Gamma(a+b)} x^{a-1} (1-x)^{b-1}\).

This distribution is necessary for string formation. The implementation uses a property connecting beta distribution to gamma-distribution. Interchanging a and b will not change results.

Parameters
aShape parameter.
bScale parameter.
Returns
Sampled random number.

Definition at line 373 of file random.h.

373  {
374  // Otherwise the integral over probability density diverges
375  assert(a > T(0.0) && b > T(0.0));
376  const T x1 = std::gamma_distribution<T>(a)(engine);
377  const T x2 = std::gamma_distribution<T>(b)(engine);
378  return x1 / (x1 + x2);
379 }
Here is the caller graph for this function:

◆ beta_a0()

template<typename T = double>
T smash::random::beta_a0 ( xmin,
b 
)

Draws a random number from a beta-distribution with a = 0.

In this case the probability density is \(p(x) = 1/x (1-x)^b\). The integral from 0 to 1 over this distribution diverges, so the sampling is performed in the interval (xmin, 1). This distribution is necessary for string formation. The implementation uses the following property: \(p(x)dx = dx/x (1-x)^b = (1-x)^b d ln(x) = (1 - e^{-y})^b dy\), where \( y = - ln(x) \).

Parameters
xminMinimal sampled value.
bSecond shape parameter.
Returns
Sampled random number.

Definition at line 395 of file random.h.

395  {
396  assert(xmin > T(0.0) && xmin < T(1.0));
397  T y;
398  do {
399  y = uniform(0.0, -std::log(xmin));
400  } while (std::pow((1.0 - std::exp(-y)), b) < canonical());
401  return std::exp(-y);
402 }
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ engine

random::Engine smash::random::engine
extern

The engine that is used commonly by all distributions.

Definition at line 19 of file random.cc.