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 has_spare_normal = false;
68 spare_normal = 0.0f;
69 }
70
71 int Rnd::rnd_int( int lowerLimit, int upperLimit )
72 {
73 std::uniform_int_distribution<> dist( lowerLimit, upperLimit );
74 return dist(rg[omp_get_thread_num()]);
75 }
76
77 float Rnd::rnd_flt(float min, float max)
78 {
79 std::uniform_real_distribution<float> dist(min, max);
80 return dist(rg[omp_get_thread_num()]);
81 }
82
83 float Rnd::rnd_alpha_beta(float alpha, float beta)
84 {
85 // use a beta distribution based on alphas and betas to sample probabilities.
86
87 // from https://stackoverflow.com/questions/4181403/generate-random-number-based-on-beta-distribution-using-boost
88 // You'll first want to draw a random number uniformly from the
89 // range (0,1). Given any distribution, you can then plug that number
90 // into the distribution's "quantile function," and the result is as
91 // if a random value was drawn from the distribution.
92
93 // from https://stackoverflow.com/questions/10358064/random-numbers-from-beta-distribution-c
94 // The beta distribution is related to the gamma distribution. Let X be a
95 // random number drawn from Gamma(α,1) and Y from Gamma(β,1), where the
96 // first argument to the gamma distribution is the shape parameter.
97 // Then Z=X/(X+Y) has distribution Beta(α,β).
98
99 std::gamma_distribution<float> distA(alpha, 1.0f);
100 std::gamma_distribution<float> distB(beta, 1.0f);
101
102 float X = distA(rg[omp_get_thread_num()]);
103 float Y = distB(rg[omp_get_thread_num()]);
104
105 float prob = X/(X+Y+0.001f);
106
107 return prob;
108 }
109 float Rnd::rnd_dbl(float min, float max)
110 {
111 std::uniform_real_distribution<float> dist(min, max);
112 return dist(rg[omp_get_thread_num()]);
113 }
114
115 float Rnd::operator()(unsigned i)
116 {
117 return rnd_dbl(0.0,i);
118 }
119
120 float Rnd::operator()() { return rnd_flt(0.0,1.0); }
121
123 //Returns a normally distributed deviate with zero mean and unit variance
124 {
125 // Box–Muller / polar implementation
126 // Returns a normally distributed deviate with zero mean
127 // and unit variance.
128
129 if (has_spare_normal) {
130 has_spare_normal = false;
131 return spare_normal;
132 }
133
134 // float ran = rnd_flt(-1,1);
135
136 float rsq,v1,v2;
137
138 do{
139 v1=float(rnd_flt(-1.0f,1.0f)); //pick two uniform numbers in the square ex
140 v2=float(rnd_flt(-1.0f,1.0f)); //tending from -1 to +1 in each direction,
141 rsq=v1*v1+v2*v2; //see if they are in the unit circle,
142 } while (rsq >= 1.0 || rsq == 0.0); //and if they are not, try again.
143
144 const float fac = float(sqrt(-2.0*log(rsq)/rsq));
145
146 //Now make the Box-Muller transformation to get two normal deviates. Return one and
147 //save the other for next time.
148 spare_normal=v1*fac;
149 has_spare_normal=true;
150
151 return v2*fac;
152 }
153
155 vector<size_t> Rnd::shuffled_index(size_t n)
156 {
157 vector<size_t> idx(n);
158 std::iota(idx.begin(), idx.end(), 0);
159 this->shuffle(idx.begin(), idx.end());
160 return idx;
161 }
163} }
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:83
void shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition rnd.h:51
float rnd_flt(float min=0.0, float max=1.0)
Definition rnd.cpp:77
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:155
void set_seed(unsigned int seed)
Definition rnd.cpp:46
static void destroy()
Definition rnd.cpp:38
float spare_normal
Definition rnd.h:174
vector< std::mt19937 > rg
Definition rnd.h:165
static Rnd * instance
Definition rnd.h:178
float rnd_dbl(float min=0.0, float max=1.0)
Definition rnd.cpp:109
float operator()()
Definition rnd.cpp:120
float gasdev()
Definition rnd.cpp:122
bool has_spare_normal
Definition rnd.h:173
int rnd_int(int lowerLimit, int upperLimit)
Definition rnd.cpp:71
#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:3