13 #ifndef VMCMC_RANDOM_H_ 14 #define VMCMC_RANDOM_H_ 19 #include <type_traits> 24 #include <boost/numeric/ublas/vector.hpp> 25 #include <boost/numeric/ublas/matrix.hpp> 26 #include <boost/numeric/ublas/triangular.hpp> 42 template <
typename EngineT>
46 typedef EngineT engine_type;
47 typedef typename engine_type::result_type result_type;
54 static void Seed(result_type seed);
63 static std::atomic<result_type> sSeed;
89 template <
typename FloatT>
90 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
91 Uniform(FloatT min, FloatT max,
bool minIncluded,
bool maxIncluded);
99 template <
typename FloatT =
double>
100 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
101 Uniform(FloatT min = 0.0, FloatT max = 1.0);
109 template <
typename IntegerT>
110 typename std::enable_if<std::is_integral<IntegerT>::value, IntegerT>::type
111 Uniform(IntegerT inclMin, IntegerT inclMax);
118 template <
typename FloatT =
double>
119 bool Bool(FloatT probability = 0.5);
127 template <
typename FloatT =
double>
128 FloatT
Normal(FloatT mean = 0.0, FloatT sigma = 1.0);
130 template <
typename FloatT =
double>
131 FloatT StudentT(FloatT n = 1.0, FloatT mean = 0.0, FloatT sigma = 1.0);
138 template <
typename FloatT>
146 template <
typename IntegerT = u
int32_t>
147 typename std::enable_if<std::is_integral<IntegerT>::value, IntegerT>::type
155 template <
typename FloatT>
156 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
163 template <
typename ProbRangeT,
typename IndexType = u
int32_t>
164 IndexType
Discrete(
const ProbRangeT& probabilities);
173 template <
typename DistributionT>
174 typename DistributionT::result_type
FromDistribution(DistributionT& dist = DistributionT());
186 template <
typename DistributionT,
typename VectorT,
typename MatrixT>
196 template <
typename DistributionT,
typename VectorT>
200 static constexpr result_type min() {
return engine_type::min(); }
201 static constexpr result_type max() {
return engine_type::max(); }
213 template <
typename EngineT>
216 sSeed = (seed == 0) ? std::random_device()() : seed;
219 template <
typename EngineT>
233 template <
typename EngineT>
240 template <
typename EngineT>
243 static std::mutex sMtx;
244 std::lock_guard<std::mutex> lock(sMtx);
251 template <
typename EngineT>
258 template <
typename EngineT>
267 template <
typename EngineT>
271 fEngine.seed( sSeed++ );
274 template <
typename EngineT>
278 template <
typename EngineT>
279 template <
typename FloatT>
280 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
288 max = std::nextafter(max, (max > min) ? std::numeric_limits<FloatT>::max() : -std::numeric_limits<FloatT>::max());
293 min = std::nextafter(min, (max > min) ? std::numeric_limits<FloatT>::max() : -std::numeric_limits<FloatT>::max());
299 return std::uniform_real_distribution<FloatT>(min, max)(*
this);
302 template <
typename EngineT>
303 template <
typename FloatT>
304 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
307 return std::uniform_real_distribution<FloatT>(min, max)(*
this);
310 template <
typename EngineT>
311 template <
typename IntegerT>
312 typename std::enable_if<std::is_integral<IntegerT>::value, IntegerT>::type
315 return std::uniform_int_distribution<IntegerT>(inclMin, inclMax)(*
this);
318 template <
typename EngineT>
319 template <
typename FloatT>
322 return std::uniform_real_distribution<FloatT>(0.0, 1.0)(*this) < probability;
325 template <
typename EngineT>
326 template <
typename FloatT>
329 return std::normal_distribution<FloatT>(mean, sigma)(*
this);
332 template <
typename EngineT>
333 template <
typename DistributionT>
339 template <
typename EngineT>
340 template <
typename DistributionT,
typename VectorT,
typename MatrixT>
343 LOG_DEFINE(
"vmcmc.random");
344 LOG_ASSERT( mean.size() == cholesky.size1() );
346 VectorT noise( mean.size() );
348 for (
size_t i = 0; i < noise.size(); ++i)
349 noise[i] = dist(*
this);
351 return mean + ublas::prod(noise, cholesky);
354 template <
typename EngineT>
355 template <
typename DistributionT,
typename VectorT>
358 LOG_DEFINE(
"vmcmc.random");
359 LOG_ASSERT( mean.size() == sigma.size1() );
361 VectorT noise( mean.size() );
363 for (
size_t i = 0; i < noise.size(); ++i)
364 noise[i] = dist(*
this);
366 return mean + ublas::element_prod(noise, sigma);
370 template <
typename EngineT>
371 template <
typename IntegerT>
372 typename std::enable_if<std::is_integral<IntegerT>::value, IntegerT>::type
375 return std::poisson_distribution<IntegerT>(mean)(*
this);
378 template <
typename EngineT>
379 template <
typename FloatT>
380 typename std::enable_if<std::is_floating_point<FloatT>::value, FloatT>::type
383 if (mean > std::numeric_limits<uint64_t>::max() / 2.0)
384 return Normal<FloatT>(mean, sqrt(mean));
386 return (FloatT) std::poisson_distribution<uint64_t>(mean)(*
this);
389 template <
typename EngineT>
390 template <
typename FloatT>
393 return std::exponential_distribution<FloatT>(1.0/tau)(*
this);
396 template <
typename EngineT>
397 template <
typename ProbRangeT,
typename IndexType>
400 return std::discrete_distribution<IndexType>(probabilities.begin(), probabilities.end())(*
this);
std::enable_if< std::is_floating_point< FloatT >::value, FloatT >::type Uniform(FloatT min, FloatT max, bool minIncluded, bool maxIncluded)
Get a random uniform number in the specified range.
Definition: random.hpp:281
Definition: algorithm.cpp:28
std::enable_if< std::is_integral< IntegerT >::value, IntegerT >::type Poisson(double mean)
Draw an integer value from a poisson distribution.
Definition: random.hpp:373
result_type operator()()
Invokes the underlying random number generator.
Definition: random.hpp:259
Class definitions and MACROs for logging purposes.
engine_type & GetEngine()
Get a reference to the underlying random number engine (mersenne twister).
Definition: random.hpp:78
bool Bool(FloatT probability=0.5)
Return a boolean.
Definition: random.hpp:320
A thread-safe interface for STL style pesudo random number generators (PRNG).
Definition: random.hpp:43
FloatT Normal(FloatT mean=0.0, FloatT sigma=1.0)
Draw from a gaussian / normal distribution.
Definition: random.hpp:327
VectorT FromMultiVariateDistribution(DistributionT &dist, const VectorT &mean, const MatrixT &cholesky)
Draw from a custom multivariate distribution.
Definition: random.hpp:341
static RandomPrototype & Instance()
Get a reference to a static instance for the current thread.
Definition: random.hpp:252
FloatT Exponential(FloatT tau)
Draw from an exponential distribution according to exp(-t/tau).
Definition: random.hpp:391
IndexType Discrete(const ProbRangeT &probabilities)
Produces integers in the range [0, n) with the probability of producing each value is specified by th...
Definition: random.hpp:398
static void Seed(result_type seed)
Set the initial value for the global seed variable.
Definition: random.hpp:214
DistributionT::result_type FromDistribution(DistributionT &dist=DistributionT())
Draw from a custom distribution.
Definition: random.hpp:334