Brush C++ API
A flexible interpretable machine learning framework
Loading...
Searching...
No Matches
rnd.h
Go to the documentation of this file.
1/* Brush
2copyright 2020 William La Cava
3license: GNU/GPL v3
4*/
5
6#ifndef RND_H
7#define RND_H
8//external includes
9#include <random>
10#include <limits>
11#include <vector>
12
13#include "../init.h"
14
15// Defines a multi-core random number generator and its operators.
16
17using namespace std;
18using std::swap;
19
20namespace Brush { namespace Util{
21
23
28 class Rnd
29 {
30 public:
31
32 static Rnd* initRand();
33
34 static void destroy();
35
36 void set_seed(unsigned int seed);
37
38 int rnd_int( int lowerLimit, int upperLimit );
39
40 float rnd_flt(float min=0.0, float max=1.0);
41
42 float rnd_dbl(float min=0.0, float max=1.0);
43
44 float operator()(unsigned i);
45
46 float operator()();
47
48 template <class RandomAccessIterator>
50 {
51 for (auto i=(last-first)-1; i>0; --i)
52 {
53 std::uniform_int_distribution<decltype(i)> d(0,i);
54 swap (first[i], first[d(rg[omp_get_thread_num()])]);
55 }
56 }
57
58 vector<size_t> shuffled_index(size_t n);
59
60 template<typename Iter>
62 {
63 std::uniform_int_distribution<> dis(0, distance(start, end) - 1);
65 return start;
66 }
67
69 // The probability of picking the i-th element is w_i/S, with S
70 // being the sum of all weights. select_randomly works even if the
71 // weights does not sum up to 1
72 template<typename Iter, typename Iter2>
74 {
75 // discrete_distribution creates a Generator for a probability
76 // distribution function. `dis` generate integers from [0, s),
77 // where `s` is the number of probabilities in the iterator
78 // passed as argument. To generate a new value, the
79 // `operator()( Generator& g )` needs a uniform random bit
80 // generator object, which is stored in `rg`.
81
82 // std::uniform_int_distribution<> dis(0, distance(start, end) - 1);
83 std::discrete_distribution<size_t> dis(wstart, wend);
84
85 // `advance(it, n)` increments the iterator by n elements
87
88 // start was originally an iterator pointing to the beggining
89 // of the sequence we want to take a random value. It is incremented
90 // to point to a random element, with probabilities taken from
91 // the second iterator Iter2.
92 return start;
93 }
94
95 template<typename T>
96 T random_choice(const map<T, float>& m)
97 {
103 assert(m.size()>0
104 && " attemping to return random choice from an empty map");
105
106 vector<T> keys;
107 vector<float> w;
108 for (const auto& [k, v]: m)
109 {
110 keys.push_back(k);
111 w.push_back(v);
112 }
113 return *select_randomly(keys.begin(),keys.end(),
114 w.begin(), w.end());
115 }
116 template<class V, class T>
117 T random_choice(const V& v)
118 {
122 assert(v.size()>0
123 && " attemping to return random choice from empty vector");
124 return *select_randomly(v.begin(),v.end());
125 }
126
127 template<template<class, class> class C, class T>
128 T random_choice(const C<T, std::allocator<T>>& v, const vector<float>& w )
129 {
134 if(w.size() == 0)
135 {
136 fmt::format("w size = {} and v size = {}, returning uniform random choice\n",
137 w.size(), v.size());
138 return random_choice(v);
139 }
140 if(w.size() != v.size())
141 {
142 fmt::format("w ({}) != v size ({}), returning uniform random choice\n",
143 w.size(), v.size());
144 return random_choice(v);
145 }
146 else
147 {
148 assert(v.size() == w.size());
149 std::discrete_distribution<size_t> dis(w.begin(), w.end());
150 return v.at(dis(rg[omp_get_thread_num()]));
151 }
152 }
153
154 float gasdev();
155
156 private:
157
158 Rnd();
159
160 ~Rnd();
161
162 // Vector of pseudo-random number generators, one for each thread
163 vector<std::mt19937> rg;
164
165 // private static attribute used by every instance of the class.
166 // All threads share common static members of the class
167 static Rnd* instance;
168 };
169
170 // `Brush.Util` static attribute holding an singleton instance of Rnd.
171 // the instance is created by calling `initRand`, which creates
172 // an instance of the private static attribute `instance`. `r` will contain
173 // one generator for each thread (since it called the constructor)
174 static Rnd &r = *Rnd::initRand();
175} // Util
176} // Brush
177#endif
void bind_engine(py::module &m, string name)
Defines a multi-core random number generator and its operators.
Definition rnd.h:29
T random_choice(const map< T, float > &m)
Definition rnd.h:96
T random_choice(const V &v)
Definition rnd.h:117
void shuffle(RandomAccessIterator first, RandomAccessIterator last)
Definition rnd.h:49
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:121
Iter select_randomly(Iter start, Iter end, Iter2 wstart, Iter2 wend)
select randomly with weighted distribution.
Definition rnd.h:73
void set_seed(unsigned int seed)
Definition rnd.cpp:46
static void destroy()
Definition rnd.cpp:38
vector< std::mt19937 > rg
Definition rnd.h:163
T random_choice(const C< T, std::allocator< T > > &v, const vector< float > &w)
Definition rnd.h:128
Iter select_randomly(Iter start, Iter end)
Definition rnd.h:61
static Rnd * instance
Definition rnd.h:167
float rnd_dbl(float min=0.0, float max=1.0)
Definition rnd.cpp:80
float operator()()
Definition rnd.cpp:91
float gasdev()
Definition rnd.cpp:93
int rnd_int(int lowerLimit, int upperLimit)
Definition rnd.cpp:68
#define omp_get_thread_num()
Definition init.h:12
static Rnd & r
Definition rnd.h:174
< nsga2 selection operator for getting the front
Definition data.cpp:12
tree< Node >::pre_order_iterator Iter
Definition program.h:37
STL namespace.