24 #ifndef GRAPHLAB_RANDOM_HPP
25 #define GRAPHLAB_RANDOM_HPP
35 #include <boost/random.hpp>
36 #include <graphlab/util/timer.hpp>
37 #include <graphlab/parallel/pthread_tools.hpp>
55 namespace distributions {
63 template<
typename IntType>
65 typedef boost::uniform_int<IntType> distribution_type;
66 template<
typename RealRNG,
typename DiscreteRNG>
67 static inline IntType sample(RealRNG& real_rng,
68 DiscreteRNG& discrete_rng,
69 const IntType& min,
const IntType& max) {
70 return distribution_type(min, max)(discrete_rng);
75 typedef boost::uniform_real<double> distribution_type;
76 template<
typename RealRNG,
typename DiscreteRNG>
77 static inline double sample(RealRNG& real_rng,
78 DiscreteRNG& discrete_rng,
79 const double& min,
const double& max) {
80 return distribution_type(min, max)(real_rng);
85 typedef boost::uniform_real<float> distribution_type;
86 template<
typename RealRNG,
typename DiscreteRNG>
87 static inline float sample(RealRNG& real_rng,
88 DiscreteRNG& discrete_rng,
89 const float& min,
const float& max) {
90 return distribution_type(min, max)(real_rng);
103 typedef boost::lagged_fibonacci607 real_rng_type;
104 typedef boost::mt11213b discrete_rng_type;
105 typedef boost::rand48 fast_discrete_rng_type;
116 fast_discrete_rng.seed();
132 fast_discrete_rng.seed(number);
133 real_rng.seed(fast_discrete_rng);
134 discrete_rng.seed(fast_discrete_rng);
141 real_rng.seed(other.real_rng);
142 discrete_rng.seed(other.discrete_rng);
143 fast_discrete_rng.seed(other.fast_discrete_rng());
151 template<
typename NumType>
152 inline NumType
uniform(
const NumType min,
const NumType max) {
155 sample(real_rng, discrete_rng, min, max);
164 template<
typename NumType>
168 sample(real_rng, fast_discrete_rng, min, max);
178 inline double gamma(
const double alpha =
double(1)) {
179 boost::gamma_distribution<double> gamma_dist(alpha);
181 const double result = gamma_dist(real_rng);
191 inline double gaussian(
const double mean =
double(0),
192 const double stdev =
double(1)) {
193 boost::normal_distribution<double> normal_dist(mean,stdev);
195 const double result = normal_dist(real_rng);
204 inline double normal(
const double mean =
double(0),
205 const double stdev =
double(1)) {
210 inline bool bernoulli(
const double p =
double(0.5)) {
211 boost::bernoulli_distribution<double> dist(p);
213 const double result(dist(discrete_rng));
218 inline bool fast_bernoulli(
const double p =
double(0.5)) {
219 boost::bernoulli_distribution<double> dist(p);
221 const double result(dist(fast_discrete_rng));
230 template<
typename Double>
232 ASSERT_GT(prb.size(),0);
233 if (prb.size() == 1) {
return 0; }
235 for(
size_t i = 0; i < prb.size(); ++i) {
236 ASSERT_GE(prb[i], 0);
241 const Double rnd(uniform<Double>(0,1));
243 for(Double cumsum(prb[ind]/sum);
244 rnd > cumsum && (ind+1) < prb.size();
245 cumsum += (prb[++ind]/sum));
255 template<
typename Double>
257 return std::upper_bound(cdf.begin(), cdf.end(),
258 uniform<Double>(0,1)) - cdf.begin();
268 std::vector<T> perm(nelems);
269 for(T i = 0; i < nelems; ++i) perm[i] = i;
283 template<
typename Iterator>
286 shuffle_functor functor(*
this);
287 std::random_shuffle(begin, end, functor);
294 struct shuffle_functor {
296 inline shuffle_functor(
generator& gen) : gen(gen) { }
297 inline std::ptrdiff_t operator()(std::ptrdiff_t end) {
298 return distributions::uniform<ptrdiff_t>::
299 sample(gen.real_rng, gen.fast_discrete_rng, 0, end-1);
305 real_rng_type real_rng;
307 discrete_rng_type discrete_rng;
309 fast_discrete_rng_type fast_discrete_rng;
338 void seed(
size_t seed_value);
364 template<
typename NumType>
365 inline NumType
uniform(
const NumType min,
const NumType max) {
366 if (min == max)
return min;
375 template<
typename NumType>
377 if (min == max)
return min;
385 inline double rand01() {
return uniform<double>(0, 1); }
398 inline double gamma(
const double alpha =
double(1)) {
409 inline double gaussian(
const double mean =
double(0),
410 const double stdev =
double(1)) {
419 inline double normal(
const double mean =
double(0),
420 const double stdev =
double(1)) {
445 template<
typename Double>
455 template<
typename Double>
485 template<
typename Iterator>
486 inline void shuffle(Iterator begin, Iterator end) {
493 void pdf2cdf(std::vector<double>& pdf);