6 #ifndef TURI_RANDOM_HPP 7 #define TURI_RANDOM_HPP 17 #include <boost/random.hpp> 18 #include <timer/timer.hpp> 19 #include <core/parallel/pthread_tools.hpp> 44 namespace distributions {
52 template<
typename IntType>
54 typedef boost::uniform_int<IntType> distribution_type;
55 template<
typename RealRNG,
typename DiscreteRNG>
56 static inline IntType sample(RealRNG& real_rng,
57 DiscreteRNG& discrete_rng,
58 const IntType& min,
const IntType& max) {
59 return distribution_type(min, max)(discrete_rng);
64 typedef boost::uniform_real<double> distribution_type;
65 template<
typename RealRNG,
typename DiscreteRNG>
66 static inline double sample(RealRNG& real_rng,
67 DiscreteRNG& discrete_rng,
68 const double& min,
const double& max) {
69 return distribution_type(min, max)(real_rng);
74 typedef boost::uniform_real<float> distribution_type;
75 template<
typename RealRNG,
typename DiscreteRNG>
76 static inline float sample(RealRNG& real_rng,
77 DiscreteRNG& discrete_rng,
78 const float& min,
const float& max) {
79 return distribution_type(min, max)(real_rng);
92 typedef boost::lagged_fibonacci607 real_rng_type;
93 typedef boost::mt11213b discrete_rng_type;
94 typedef boost::rand48 fast_discrete_rng_type;
105 fast_discrete_rng.seed();
120 uint32_t _seed =
static_cast<uint32_t
>(number);
121 if(
size_t(_seed) != number) {
122 _seed =
static_cast<uint32_t
>(std::hash<size_t>{}(number));
126 fast_discrete_rng.seed(_seed);
127 real_rng.seed(fast_discrete_rng);
128 discrete_rng.seed(fast_discrete_rng);
135 real_rng.seed(other.real_rng);
136 discrete_rng.seed(other.discrete_rng);
137 fast_discrete_rng.seed(other.fast_discrete_rng());
145 template<
typename NumType>
146 inline NumType
uniform(
const NumType min,
const NumType max) {
149 sample(real_rng, discrete_rng, min, max);
158 template<
typename NumType>
162 sample(real_rng, fast_discrete_rng, min, max);
172 inline double gamma(
const double alpha =
double(1)) {
173 boost::gamma_distribution<double> gamma_dist(alpha);
175 const double result = gamma_dist(real_rng);
185 inline double gaussian(
const double mean =
double(0),
186 const double stdev =
double(1)) {
187 boost::normal_distribution<double> normal_dist(mean, stdev);
189 const double result = normal_dist(real_rng);
198 inline double normal(
const double mean =
double(0),
199 const double stdev =
double(1)) {
207 inline double cauchy(
const double location =
double(0),
208 const double scale =
double(1)) {
209 boost::cauchy_distribution<double> cauchy_dist(location, scale);
211 const double result = cauchy_dist(real_rng);
216 inline bool bernoulli(
const double p =
double(0.5)) {
217 boost::bernoulli_distribution<double> dist(p);
219 const double result(dist(discrete_rng));
225 boost::bernoulli_distribution<double> dist(p);
227 const double result(dist(fast_discrete_rng));
236 template<
typename Double>
238 ASSERT_GT(prb.size(),0);
239 if (prb.size() == 1) {
return 0; }
241 for(
size_t i = 0; i < prb.size(); ++i) {
242 ASSERT_GE(prb[i], 0);
247 const Double rnd(uniform<Double>(0,1));
249 for(Double cumsum(prb[ind]/sum);
250 rnd > cumsum && (ind+1) < prb.size();
251 cumsum += (prb[++ind]/sum));
259 template <
typename VecType,
typename VType>
263 return fast_uniform<VType>(0, prb.size() - 1);
269 for(
size_t i = 0; i < size_t(prb.size()); ++i) {
270 total += VType(prb[i]);
273 ASSERT_LT(
double(std::abs(norm - total)), std::max(1e-20, 1e-6 * norm));
276 VType rnd = fast_uniform<VType>(0,norm - (std::is_integral<VType>::value ? 1 : 0));
278 for(
size_t i = 0; i < size_t(prb.size()); ++i) {
295 template<
typename Double>
297 return std::upper_bound(cdf.begin(), cdf.end(),
298 uniform<Double>(0,1)) - cdf.begin();
308 std::vector<T> perm(nelems);
309 for(T i = 0; i < nelems; ++i) perm[i] = i;
323 template<
typename Iterator>
326 shuffle_functor functor(*
this);
327 std::random_shuffle(begin, end, functor);
334 struct shuffle_functor {
336 inline shuffle_functor(
generator& gen) : gen(gen) { }
337 inline std::ptrdiff_t operator()(std::ptrdiff_t end) {
339 sample(gen.real_rng, gen.fast_discrete_rng, 0, end-1);
345 real_rng_type real_rng;
347 discrete_rng_type discrete_rng;
349 fast_discrete_rng_type fast_discrete_rng;
378 void seed(
size_t seed_value);
404 template<
typename NumType>
405 inline NumType
uniform(
const NumType min,
const NumType max) {
406 if (min == max)
return min;
415 template<
typename NumType>
417 if (min == max)
return min;
425 inline double rand01() {
return uniform<double>(0, 1); }
438 inline double gamma(
const double alpha =
double(1)) {
449 inline double gaussian(
const double mean =
double(0),
450 const double stdev =
double(1)) {
459 inline double normal(
const double mean =
double(0),
460 const double stdev =
double(1)) {
469 inline double cauchy(
const double location =
double(0),
470 const double scale =
double(1)) {
495 template<
typename Double>
505 template<
typename VecLike,
typename Double>
514 template<
typename Double>
544 template<
typename Iterator>
545 inline void shuffle(Iterator begin, Iterator end) {
552 void pdf2cdf(std::vector<double>& pdf);
std::vector< T > permutation(const size_t nelems)
void seed(generator &other)
Seed the generator using another generator.
size_t multinomial_cdf(const std::vector< Double > &cdf)
NumType uniform(const NumType min, const NumType max)
bool fast_bernoulli(const double p=double(0.5))
NumType fast_uniform(const NumType min, const NumType max)
double gaussian(const double mean=double(0), const double stdev=double(1))
size_t multinomial(const std::vector< Double > &prb)
size_t multinomial_cdf(const std::vector< Double > &cdf)
NumType uniform(const NumType min, const NumType max)
size_t multinomial(const VecType &prb, VType norm)
void seed()
Seed the generator using the default seed.
size_t multinomial(const std::vector< Double > &prb)
static size_t usec_of_day()
Returns only the micro-second component of the time since the Unix Epoch.
void time_seed()
Seed the generator using the current time in microseconds.
void shuffle(std::vector< T > &vec)
double cauchy(const double location=double(0), const double scale=double(1))
void pdf2cdf(std::vector< double > &pdf)
std::vector< T > permutation(const size_t nelems)
double gamma(const double alpha=double(1))
double gamma(const double alpha=double(1))
bool bernoulli(const double p=double(0.5))
uint64_t pure_random_seed()
double gaussian(const double mean=double(0), const double stdev=double(1))
double normal(const double mean=double(0), const double stdev=double(1))
void seed(size_t number)
Seed the random number generator based on a number.
double cauchy(const double location=double(0), const double scale=double(1))
void shuffle(Iterator begin, Iterator end)
NumType fast_uniform(const NumType min, const NumType max)
void shuffle(std::vector< T > &vec)
double normal(const double mean=double(0), const double stdev=double(1))