Brush C++ API
A flexible interpretable machine learning framework
Loading...
Searching...
No Matches
rnd.cpp
Go to the documentation of this file.
1/* FEAT
2copyright 2017 William La Cava
3license: GNU/GPL v3
4*/
5
6#include "rnd.h"
7
8namespace Brush { namespace Util{
9
10 Rnd* Rnd::instance = NULL;
11
13 {
19
20
21 // TODO: stop using omp. this should be based on number of islands. make each island to use their respective
22 // when we resize, the constructor of new elements are invoked.
23 rg.resize(omp_get_max_threads());
24 }
25
27 {
28 // creates the static random generator by calling the constructor
29 if (!instance)
30 {
31 instance = new Rnd();
32 instance->set_seed(0); // setting a random initial state
33 }
34
35 return instance;
36 }
37
39 {
40 if (instance)
41 delete instance;
42
43 instance = NULL;
44 }
45
46 void Rnd::set_seed(unsigned int seed)
47 {
51 if (seed == 0) {
52 // use a non-deterministic random generator to seed the deterministics
53 std::random_device rd;
54 seed = rd();
55 }
56
57 // generating a seed sequence
58 std::seed_seq seq{seed};
59
60 std::vector<std::uint32_t> seeds(rg.size());
61 seq.generate(seeds.begin(), seeds.end());
62
63 for (size_t i = 0; i < rg.size(); ++i) {
64 rg[i].seed(seeds[i]);
65 }
66 }
67
68 int Rnd::rnd_int( int lowerLimit, int upperLimit )
69 {
70 std::uniform_int_distribution<> dist( lowerLimit, upperLimit );
71 return dist(rg[omp_get_thread_num()]);
72 }
73
74 float Rnd::rnd_flt(float min, float max)
75 {
76 std::uniform_real_distribution<float> dist(min, max);
77 return dist(rg[omp_get_thread_num()]);
78 }
79
80 float Rnd::rnd_alpha_beta(float alpha, float beta)
81 {
82 // use a beta distribution based on alphas and betas to sample probabilities.
83
84 // from https://stackoverflow.com/questions/4181403/generate-random-number-based-on-beta-distribution-using-boost
85 // You'll first want to draw a random number uniformly from the
86 // range (0,1). Given any distribution, you can then plug that number
87 // into the distribution's "quantile function," and the result is as
88 // if a random value was drawn from the distribution.
89
90 // from https://stackoverflow.com/questions/10358064/random-numbers-from-beta-distribution-c
91 // The beta distribution is related to the gamma distribution. Let X be a
92 // random number drawn from Gamma(α,1) and Y from Gamma(β,1), where the
93 // first argument to the gamma distribution is the shape parameter.
94 // Then Z=X/(X+Y) has distribution Beta(α,β).
95
96 std::gamma_distribution<float> distA(alpha, 1.0f);
97 std::gamma_distribution<float> distB(beta, 1.0f);
98
99 float X = distA(rg[omp_get_thread_num()]);
100 float Y = distB(rg[omp_get_thread_num()]);
101
102 float prob = X/(X+Y+0.001f);
103
104 return prob;
105 }
106 float Rnd::rnd_dbl(float min, float max)
107 {
108 std::uniform_real_distribution<float> dist(min, max);
109 return dist(rg[omp_get_thread_num()]);
110 }
111
112 float Rnd::operator()(unsigned i)
113 {
114 return rnd_dbl(0.0,i);
115 }
116
117 float Rnd::operator()() { return rnd_flt(0.0,1.0); }
118
120 //Returns a normally distributed deviate with zero mean and unit variance
121 {
122 float ran = rnd_flt(-1,1);
123 static int iset=0;
124 static float gset;
125 float fac,rsq,v1,v2;
126 if (iset == 0) {// We don't have an extra deviate handy, so
127 do{
128 v1=float(2.0*rnd_flt(-1,1)-1.0); //pick two uniform numbers in the square ex
129 v2=float(2.0*rnd_flt(-1,1)-1.0); //tending from -1 to +1 in each direction,
130 rsq=v1*v1+v2*v2; //see if they are in the unit circle,
131 } while (rsq >= 1.0 || rsq == 0.0); //and if they are not, try again.
132 fac=float(sqrt(-2.0*log(rsq)/rsq));
133 //Now make the Box-Muller transformation to get two normal deviates. Return one and
134 //save the other for next time.
135 gset=v1*fac;
136 iset=1; //Set flag.
137 return v2*fac;
138 }
139 else
140 { //We have an extra deviate handy,
141 iset=0; //so unset the flag,
142 return gset; //and return it.
143 }
144 }
145
147 vector<size_t> Rnd::shuffled_index(size_t n)
148 {
149 vector<size_t> idx(n);
150 std::iota(idx.begin(), idx.end(), 0);
151 this->shuffle(idx.begin(), idx.end());
152 return idx;
153 }
155} }
Defines a multi-core random number generator and its operators.
Definition rnd.h:29
float rnd_alpha_beta(float alpha, float beta)
Definition rnd.cpp:80
void shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition rnd.h:51
float rnd_flt(float min=0.0, float max=1.0)
Definition rnd.cpp:74
static Rnd * initRand()
Definition rnd.cpp:26
vector< size_t > shuffled_index(size_t n)
returns a shuffled index vector of length n
Definition rnd.cpp:147
void set_seed(unsigned int seed)
Definition rnd.cpp:46
static void destroy()
Definition rnd.cpp:38
vector< std::mt19937 > rg
Definition rnd.h:165
static Rnd * instance
Definition rnd.h:169
float rnd_dbl(float min=0.0, float max=1.0)
Definition rnd.cpp:106
float operator()()
Definition rnd.cpp:117
float gasdev()
Definition rnd.cpp:119
int rnd_int(int lowerLimit, int upperLimit)
Definition rnd.cpp:68
#define omp_get_max_threads()
Definition init.h:14
#define omp_get_thread_num()
Definition init.h:12
namespace containing various utility functions
Definition error.cpp:11
< nsga2 selection operator for getting the front
Definition bandit.cpp:4