10 #ifndef SRC_INCLUDE_SMASH_RANDOM_H_
11 #define SRC_INCLUDE_SMASH_RANDOM_H_
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));
95 return std::uniform_real_distribution<T>(min, max)(
engine);
105 template <
typename T>
110 return std::uniform_int_distribution<T>(min, max)(
engine);
121 template <
typename T =
double>
123 return std::generate_canonical<T, std::numeric_limits<double>::digits>(
130 template <
typename T =
double>
133 return std::nextafter(
134 std::generate_canonical<T, std::numeric_limits<double>::digits>(
engine),
143 template <
typename T>
157 template <
typename T =
double>
177 template <
typename T =
double>
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.);
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());
195 x = std::log(
uniform(low, high)) / A;
196 }
while (!(x <= x1 && x > x2));
206 template <
typename T>
208 return (T(0) < val) - (val < T(0));
228 template <
typename T =
double>
230 const T n1 =
n + T(1);
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");
240 std::swap(xMin, xMax);
242 const T sign = xMax < T(0) ? T(-1) : T(1);
244 const T lo = std::abs(xMin);
245 const T hi = std::abs(xMax);
247 if (std::abs(n1) < T(1e-3)) {
248 return sign * lo * std::pow(hi / lo,
canonical());
251 T a = std::pow(lo, n1);
252 T b = std::pow(hi, n1);
258 return sign * std::pow(
uniform(a, b), T(1) / n1);
269 template <
typename T>
271 return std::poisson_distribution<int>(lam)(
engine);
281 template <
typename T>
283 return std::binomial_distribution<int>(N,
p)(
engine);
293 template <
typename T>
294 double normal(
const T &mean,
const T &sigma) {
295 return std::normal_distribution<double>(mean, sigma)(
engine);
301 template <
typename T>
325 distribution = std::discrete_distribution<>(plist.begin(), plist.end());
350 template <
typename T =
double>
351 T
cauchy(T pole, T width, T min, T max) {
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);
372 template <
typename T =
double>
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);
394 template <
typename T =
double>
396 assert(xmin > T(0.0) && xmin < T(1.0));
399 y =
uniform(0.0, -std::log(xmin));
400 }
while (std::pow((1.0 - std::exp(-y)), b) <
canonical());
431 BesselSampler(
const double poisson_mean1,
const double poisson_mean2,
432 const int fixed_difference);
439 std::pair<int, int>
sample();
451 static double r_(
int n,
double a);
The intention of this class is to efficiently sample from the Bessel distribution ,...
double mu_
Mean of the Bessel distribution.
double sigma_
Standard deviation of the Bessel distribution.
std::pair< int, int > sample()
Sample two numbers from given Poissonians with a fixed difference.
const bool N_is_positive_
Boolean variable to verify that N > 0.
static double r_(int n, double a)
Compute the ratio of two Bessel functions r(n,a) = bessel_I(n+1,a)/bessel_I(n,a) using the continued ...
static constexpr double negligible_probability_
Probabilities smaller than negligibly_probability are neglected.
double m_
Mode of the Bessel function, see for details.
static constexpr double m_switch_method_
Switching mode to normal approximation.
random::discrete_dist< double > dist_
Vector to store tabulated values of probabilities for small m case (m <6).
BesselSampler(const double poisson_mean1, const double poisson_mean2, const int fixed_difference)
Construct a BesselSampler.
const int N_
First parameter of Bessel distribution (= in ).
const double a_
Second parameter of Bessel distribution, see for details.
Discrete distribution with weight given by probability vector.
discrete_dist()
Default discrete distribution.
std::discrete_distribution distribution
The distribution object that is being used.
int operator()()
Draw a random number from the discrete distribution.
discrete_dist(const std::vector< T > &plist)
Construct from probability vector.
discrete_dist(std::initializer_list< T > l)
Construct from probability list.
void reset_weights(const std::vector< T > &plist)
Reset the discrete distribution from a new probability list.
#define unlikely(x)
Tell the branch predictor that this expression is likely false.
int poisson(const T &lam)
Returns a Poisson distributed random number.
T power(T n, T xMin, T xMax)
Sample from a power-law probability density proportional to |x|^n.
T exponential(T lambda)
Draws an exponentially distributed random number.
T beta_a0(T xmin, T b)
Draws a random number from a beta-distribution with a = 0.
T beta(T a, T b)
Draws a random number from a beta-distribution, where probability density of is .
uniform_dist< T > make_uniform_distribution(T min, T max)
Engine::result_type advance()
Advance the engine's state and return the generated value.
T 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,...
Engine engine
The engine that is used commonly by all distributions.
int64_t generate_63bit_seed()
Generates a seed with a truly random 63-bit value, if possible.
std::mt19937_64 Engine
The random number engine used is the Mersenne Twister.
double normal(const T &mean, const T &sigma)
Returns a random number drawn from a normal distribution.
T uniform_int(T min, T max)
int binomial(const int N, const T &p)
Returns a binomially distributed random number.
T cauchy(T pole, T width, T min, T max)
Draws a random number from a Cauchy distribution (sometimes also called Lorentz or non-relativistic B...
int sgn(T val)
Signum function.
void set_seed(T &&seed)
Sets the seed of the random number engine.