Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
machine_learning Namespace Reference

Machine learning algorithms. More...

Classes

class  adaline
 

Functions

int save_u_matrix (const char *fname, const std::vector< std::vector< std::valarray< double >>> &W)
 
double update_weights (const std::valarray< double > &X, std::vector< std::vector< std::valarray< double >>> *W, std::vector< std::valarray< double >> *D, double alpha, int R)
 
void kohonen_som (const std::vector< std::valarray< double >> &X, std::vector< std::vector< std::valarray< double >>> *W, double alpha_min)
 
void update_weights (const std::valarray< double > &x, std::vector< std::valarray< double >> *W, std::valarray< double > *D, double alpha, int R)
 
void kohonen_som_tracer (const std::vector< std::valarray< double >> &X, std::vector< std::valarray< double >> *W, double alpha_min)
 
template<typename T >
std::ostreamoperator<< (std::ostream &out, std::vector< std::valarray< T >> const &A)
 
template<typename T >
std::ostreamoperator<< (std::ostream &out, const std::pair< T, T > &A)
 
template<typename T >
std::ostreamoperator<< (std::ostream &out, const std::valarray< T > &A)
 
template<typename T >
std::valarray< T > insert_element (const std::valarray< T > &A, const T &ele)
 
template<typename T >
std::valarray< T > pop_front (const std::valarray< T > &A)
 
template<typename T >
std::valarray< T > pop_back (const std::valarray< T > &A)
 
template<typename T >
void equal_shuffle (std::vector< std::vector< std::valarray< T >> > &A, std::vector< std::vector< std::valarray< T >> > &B)
 
template<typename T >
void uniform_random_initialization (std::vector< std::valarray< T >> &A, const std::pair< size_t, size_t > &shape, const T &low, const T &high)
 
template<typename T >
void unit_matrix_initialization (std::vector< std::valarray< T >> &A, const std::pair< size_t, size_t > &shape)
 
template<typename T >
void zeroes_initialization (std::vector< std::valarray< T >> &A, const std::pair< size_t, size_t > &shape)
 
template<typename T >
sum (const std::vector< std::valarray< T >> &A)
 
template<typename T >
std::pair< size_t, size_t > get_shape (const std::vector< std::valarray< T >> &A)
 
template<typename T >
std::vector< std::vector< std::valarray< T > > > minmax_scaler (const std::vector< std::vector< std::valarray< T >>> &A, const T &low, const T &high)
 
template<typename T >
size_t argmax (const std::vector< std::valarray< T >> &A)
 
template<typename T >
std::vector< std::valarray< T > > apply_function (const std::vector< std::valarray< T >> &A, T(*func)(const T &))
 
template<typename T >
std::vector< std::valarray< T > > operator* (const std::vector< std::valarray< T >> &A, const T &val)
 
template<typename T >
std::vector< std::valarray< T > > operator/ (const std::vector< std::valarray< T >> &A, const T &val)
 
template<typename T >
std::vector< std::valarray< T > > transpose (const std::vector< std::valarray< T >> &A)
 
template<typename T >
std::vector< std::valarray< T > > operator+ (const std::vector< std::valarray< T >> &A, const std::vector< std::valarray< T >> &B)
 
template<typename T >
std::vector< std::valarray< T > > operator- (const std::vector< std::valarray< T >> &A, const std::vector< std::valarray< T >> &B)
 
template<typename T >
std::vector< std::valarray< T > > multiply (const std::vector< std::valarray< T >> &A, const std::vector< std::valarray< T >> &B)
 
template<typename T >
std::vector< std::valarray< T > > hadamard_product (const std::vector< std::valarray< T >> &A, const std::vector< std::valarray< T >> &B)
 

Variables

constexpr double MIN_DISTANCE = 1e-4
 

Detailed Description

Machine learning algorithms.

Machine Learning algorithms.

Function Documentation

◆ apply_function()

template<typename T >
std::vector<std::valarray <T> > machine_learning::apply_function ( const std::vector< std::valarray< T >> &  A,
T(*)(const T &)  func 
)

Function which applys supplied function to every element of 2D vector

Template Parameters
Ttypename of the vector
Parameters
A2D vector on which function will be applied
funcFunction to be applied
Returns
new resultant vector
316  {
317  std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
318  for(auto &b : B) { // For every row in vector
319  b = b.apply(func); // Apply function to that row
320  }
321  return B; // Return new resultant 2D vector
322 }

◆ argmax()

template<typename T >
size_t machine_learning::argmax ( const std::vector< std::valarray< T >> &  A)

Function to get index of maximum element in 2D vector

Template Parameters
Ttypename of the vector
Parameters
A2D vector for which maximum index is required
Returns
index of maximum element
296  {
297  const auto shape = get_shape(A);
298  // As this function is used on predicted (or target) vector, shape should be (1, X)
299  if(shape.first != 1) {
300  std::cerr << "ERROR: (argmax) Supplied vector is ineligible for argmax" << std::endl;
301  std::exit(EXIT_FAILURE);
302  }
303  // Return distance of max element from first element (i.e. index)
304  return std::distance(std::begin(A[0]), std::max_element(std::begin(A[0]), std::end(A[0])));
305 }
Here is the call graph for this function:

◆ equal_shuffle()

template<typename T >
void machine_learning::equal_shuffle ( std::vector< std::vector< std::valarray< T >> > &  A,
std::vector< std::vector< std::valarray< T >> > &  B 
)

Function to equally shuffle two 3D vectors (used for shuffling training data)

Template Parameters
Ttypename of the vector
Parameters
AFirst 3D vector
BSecond 3D vector
134  {
135  // If two vectors have different sizes
136  if(A.size() != B.size())
137  {
138  std::cerr << "ERROR : Can not equally shuffle two vectors with different sizes: ";
139  std::cerr << A.size() << " and " << B.size() << std::endl;
140  std::exit(EXIT_FAILURE);
141  }
142  for(size_t i = 0; i < A.size(); i++) { // For every element in A and B
143  // Genrating random index < size of A and B
144  std::srand(std::chrono::system_clock::now().time_since_epoch().count());
145  size_t random_index = std::rand() % A.size();
146  // Swap elements in both A and B with same random index
147  std::swap(A[i], A[random_index]);
148  std::swap(B[i], B[random_index]);
149  }
150  return;
151 }
Here is the call graph for this function:

◆ get_shape()

template<typename T >
std::pair<size_t, size_t> machine_learning::get_shape ( const std::vector< std::valarray< T >> &  A)

Function to get shape of given 2D vector

Template Parameters
Ttypename of the vector
Parameters
A2D vector for which shape is required
Returns
shape as pair
243  {
244  const size_t sub_size = (*A.begin()).size();
245  for(const auto &a : A) {
246  // If supplied vector don't have same shape in all rows
247  if(a.size() != sub_size) {
248  std::cerr << "ERROR: (get_shape) Supplied vector is not 2D Matrix" << std::endl;
249  std::exit(EXIT_FAILURE);
250  }
251  }
252  return std::make_pair(A.size(), sub_size); // Return shape as pair
253 }

◆ hadamard_product()

template<typename T >
std::vector<std::valarray <T> > machine_learning::hadamard_product ( const std::vector< std::valarray< T >> &  A,
const std::vector< std::valarray< T >> &  B 
)

Function to get hadamard product of two 2D vectors

Template Parameters
Ttypename of the vector
Parameters
AFirst 2D vector
BSecond 2D vector
Returns
new resultant vector
466  {
467  const auto shape_a = get_shape(A);
468  const auto shape_b = get_shape(B);
469  // If vectors are not eligible for hadamard product
470  if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
471  std::cerr << "ERROR: (hadamard_product) Supplied vectors have different shapes ";
472  std::cerr << shape_a << " and " << shape_b << std::endl;
473  std::exit(EXIT_FAILURE);
474  }
475  std::vector<std::valarray<T>> C; // Vector to store result
476  for(size_t i = 0; i < A.size(); i++) {
477  C.push_back(A[i] * B[i]); // Elementwise multiplication
478  }
479  return C; // Return new resultant 2D vector
480 }
Here is the call graph for this function:

◆ insert_element()

template<typename T >
std::valarray<T> machine_learning::insert_element ( const std::valarray< T > &  A,
const T &  ele 
)

Function to insert element into 1D vector

Template Parameters
Ttypename of the 1D vector and the element
Parameters
A1D vector in which element will to be inserted
eleelement to be inserted
Returns
new resultant vector
84  {
85  std::valarray <T> B; // New 1D vector to store resultant vector
86  B.resize(A.size() + 1); // Resizing it accordingly
87  for(size_t i = 0; i < A.size(); i++) { // For every element in A
88  B[i] = A[i]; // Copy element in B
89  }
90  B[B.size() - 1] = ele; // Inserting new element in last position
91  return B; // Return resultant vector
92 }

◆ kohonen_som()

void machine_learning::kohonen_som ( const std::vector< std::valarray< double >> &  X,
std::vector< std::vector< std::valarray< double >>> *  W,
double  alpha_min 
)

Apply incremental algorithm with updating neighborhood and learning rates on all samples in the given datset.

Parameters
[in]Xdata set
[in,out]Wweights matrix
[in]alpha_minterminal value of alpha
271  {
272  size_t num_samples = X.size(); // number of rows
273  // size_t num_features = X[0].size(); // number of columns
274  size_t num_out = W->size(); // output matrix size
275  size_t R = num_out >> 2, iter = 0;
276  double alpha = 1.f;
277 
279  for (int i = 0; i < num_out; i++) D[i] = std::valarray<double>(num_out);
280 
281  double dmin = 1.f; // average minimum distance of all samples
282  double past_dmin = 1.f; // average minimum distance of all samples
283  double dmin_ratio = 1.f; // change per step
284 
285  // Loop alpha from 1 to slpha_min
286  for (; alpha > 0 && dmin_ratio > 1e-5; alpha -= 1e-4, iter++) {
287  // Loop for each sample pattern in the data set
288  for (int sample = 0; sample < num_samples; sample++) {
289  // update weights for the current input pattern sample
290  dmin += update_weights(X[sample], W, &D, alpha, R);
291  }
292 
293  // every 100th iteration, reduce the neighborhood range
294  if (iter % 300 == 0 && R > 1) {
295  R--;
296  }
297 
298  dmin /= num_samples;
299 
300  // termination condition variable -> % change in minimum distance
301  dmin_ratio = (past_dmin - dmin) / past_dmin;
302  if (dmin_ratio < 0) {
303  dmin_ratio = 1.f;
304  }
305  past_dmin = dmin;
306 
307  std::cout << "iter: " << iter << "\t alpha: " << alpha << "\t R: " << R
308  << "\t d_min: " << dmin_ratio << "\r";
309  }
310 
311  std::cout << "\n";
312 }
Here is the call graph for this function:

◆ kohonen_som_tracer()

void machine_learning::kohonen_som_tracer ( const std::vector< std::valarray< double >> &  X,
std::vector< std::valarray< double >> *  W,
double  alpha_min 
)

Apply incremental algorithm with updating neighborhood and learning rates on all samples in the given datset.

Parameters
[in]Xdata set
[in,out]Wweights matrix
[in]alpha_minterminal value of alpha
151  {
152  int num_samples = X.size(); // number of rows
153  // int num_features = X[0].size(); // number of columns
154  int num_out = W->size(); // number of rows
155  int R = num_out >> 2, iter = 0;
156  double alpha = 1.f;
157 
158  std::valarray<double> D(num_out);
159 
160  // Loop alpha from 1 to slpha_min
161  do {
162  // Loop for each sample pattern in the data set
163  for (int sample = 0; sample < num_samples; sample++) {
164  // update weights for the current input pattern sample
165  update_weights(X[sample], W, &D, alpha, R);
166  }
167 
168  // every 10th iteration, reduce the neighborhood range
169  if (iter % 10 == 0 && R > 1) {
170  R--;
171  }
172 
173  alpha -= 0.01;
174  iter++;
175  } while (alpha > alpha_min);
176 }
Here is the call graph for this function:

◆ minmax_scaler()

template<typename T >
std::vector<std::vector<std::valarray<T> > > machine_learning::minmax_scaler ( const std::vector< std::vector< std::valarray< T >>> &  A,
const T &  low,
const T &  high 
)

Function to scale given 3D vector using min-max scaler

Template Parameters
Ttypename of the vector
Parameters
A3D vector which will be scaled
lownew minimum value
highnew maximum value
Returns
new scaled 3D vector
265  {
266  std::vector<std::vector<std::valarray<T>>> B = A; // Copying into new vector B
267  const auto shape = get_shape(B[0]); // Storing shape of B's every element
268  // As this function is used for scaling training data vector should be of shape (1, X)
269  if(shape.first != 1) {
270  std::cerr << "ERROR: (MinMax Scaling) Supplied vector is not supported for minmax scaling, shape: ";
271  std::cerr << shape << std::endl;
272  std::exit(EXIT_FAILURE);
273  }
274  for(size_t i = 0; i < shape.second; i++) {
275  T min = B[0][0][i], max = B[0][0][i];
276  for(size_t j = 0; j < B.size(); j++) {
277  // Updating minimum and maximum values
278  min = std::min(min, B[j][0][i]);
279  max = std::max(max, B[j][0][i]);
280  }
281  for(size_t j = 0; j < B.size(); j++) {
282  // Applying min-max scaler formula
283  B[j][0][i] = ((B[j][0][i] - min) / (max - min)) * (high - low) + low;
284  }
285  }
286  return B; // Return new resultant 3D vector
287 }
Here is the call graph for this function:

◆ multiply()

template<typename T >
std::vector<std::valarray <T> > machine_learning::multiply ( const std::vector< std::valarray< T >> &  A,
const std::vector< std::valarray< T >> &  B 
)

Function to multiply two 2D vectors

Template Parameters
Ttypename of the vector
Parameters
AFirst 2D vector
BSecond 2D vector
Returns
new resultant vector
434  {
435  const auto shape_a = get_shape(A);
436  const auto shape_b = get_shape(B);
437  // If vectors are not eligible for multiplication
438  if(shape_a.second != shape_b.first ) {
439  std::cerr << "ERROR: (multiply) Supplied vectors are not eligible for multiplication ";
440  std::cerr << shape_a << " and " << shape_b << std::endl;
441  std::exit(EXIT_FAILURE);
442  }
443  std::vector<std::valarray<T>> C; // Vector to store result
444  // Normal matrix multiplication
445  for (size_t i = 0; i < shape_a.first; i++) {
446  std::valarray<T> row;
447  row.resize(shape_b.second);
448  for(size_t j = 0; j < shape_b.second; j++) {
449  for(size_t k = 0; k < shape_a.second; k++) {
450  row[j] += A[i][k] * B[k][j];
451  }
452  }
453  C.push_back(row);
454  }
455  return C; // Return new resultant 2D vector
456 }
Here is the call graph for this function:

◆ operator*()

template<typename T >
std::vector<std::valarray <T> > machine_learning::operator* ( const std::vector< std::valarray< T >> &  A,
const T &  val 
)

Overloaded operator "*" to multiply given 2D vector with scaler

Template Parameters
Ttypename of both vector and the scaler
Parameters
A2D vector to which scaler will be multiplied
valScaler value which will be multiplied
Returns
new resultant vector
332  {
333  std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
334  for(auto &b : B) { // For every row in vector
335  b = b * val; // Multiply row with scaler
336  }
337  return B; // Return new resultant 2D vector
338 }

◆ operator+()

template<typename T >
std::vector<std::valarray <T> > machine_learning::operator+ ( const std::vector< std::valarray< T >> &  A,
const std::vector< std::valarray< T >> &  B 
)

Overloaded operator "+" to add two 2D vectors

Template Parameters
Ttypename of the vector
Parameters
AFirst 2D vector
BSecond 2D vector
Returns
new resultant vector
386  {
387  const auto shape_a = get_shape(A);
388  const auto shape_b = get_shape(B);
389  // If vectors don't have equal shape
390  if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
391  std::cerr << "ERROR: (vector addition) Supplied vectors have different shapes ";
392  std::cerr << shape_a << " and " << shape_b << std::endl;
393  std::exit(EXIT_FAILURE);
394  }
396  for(size_t i = 0; i < A.size(); i++) { // For every row
397  C.push_back(A[i] + B[i]); // Elementwise addition
398  }
399  return C; // Return new resultant 2D vector
400 }
Here is the call graph for this function:

◆ operator-()

template<typename T >
std::vector<std::valarray <T> > machine_learning::operator- ( const std::vector< std::valarray< T >> &  A,
const std::vector< std::valarray< T >> &  B 
)

Overloaded operator "-" to add subtract 2D vectors

Template Parameters
Ttypename of the vector
Parameters
AFirst 2D vector
BSecond 2D vector
Returns
new resultant vector
410  {
411  const auto shape_a = get_shape(A);
412  const auto shape_b = get_shape(B);
413  // If vectors don't have equal shape
414  if(shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
415  std::cerr << "ERROR: (vector subtraction) Supplied vectors have different shapes ";
416  std::cerr << shape_a << " and " << shape_b << std::endl;
417  std::exit(EXIT_FAILURE);
418  }
419  std::vector<std::valarray<T>> C; // Vector to store result
420  for(size_t i = 0; i < A.size(); i++) { // For every row
421  C.push_back(A[i] - B[i]); // Elementwise substraction
422  }
423  return C; // Return new resultant 2D vector
424 }
Here is the call graph for this function:

◆ operator/()

template<typename T >
std::vector<std::valarray <T> > machine_learning::operator/ ( const std::vector< std::valarray< T >> &  A,
const T &  val 
)

Overloaded operator "/" to divide given 2D vector with scaler

Template Parameters
Ttypename of the vector and the scaler
Parameters
A2D vector to which scaler will be divided
valScaler value which will be divided
Returns
new resultant vector
348  {
349  std::vector<std::valarray<double>> B = A; // New vector to store resultant vector
350  for(auto &b : B) { // For every row in vector
351  b = b / val; // Divide row with scaler
352  }
353  return B; // Return new resultant 2D vector
354 }

◆ operator<<() [1/3]

template<typename T >
std::ostream& machine_learning::operator<< ( std::ostream out,
const std::pair< T, T > &  A 
)

Overloaded operator "<<" to print a pair

Template Parameters
Ttypename of the pair
Parameters
outstd::ostream to output
APair to be printed
51  {
52  // Setting output precision to 4 in case of floating point numbers
53  out.precision(4);
54  // printing pair in the form (p, q)
55  std::cerr << "(" << A.first << ", " << A.second << ")";
56  return out;
57 }
Here is the call graph for this function:

◆ operator<<() [2/3]

template<typename T >
std::ostream& machine_learning::operator<< ( std::ostream out,
const std::valarray< T > &  A 
)

Overloaded operator "<<" to print a 1D vector

Template Parameters
Ttypename of the vector
Parameters
outstd::ostream to output
A1D vector to be printed
66  {
67  // Setting output precision to 4 in case of floating point numbers
68  out.precision(4);
69  for(const auto &a : A) { // For every element in the vector.
70  std::cerr << a << ' '; // Print element
71  }
73  return out;
74 }
Here is the call graph for this function:

◆ operator<<() [3/3]

template<typename T >
std::ostream& machine_learning::operator<< ( std::ostream out,
std::vector< std::valarray< T >> const &  A 
)

Overloaded operator "<<" to print 2D vector

Template Parameters
Ttypename of the vector
Parameters
outstd::ostream to output
A2D vector to be printed
32  {
33  // Setting output precision to 4 in case of floating point numbers
34  out.precision(4);
35  for(const auto &a : A) { // For each row in A
36  for(const auto &x : a) { // For each element in row
37  std::cerr << x << ' '; // print element
38  }
40  }
41  return out;
42 }
Here is the call graph for this function:

◆ pop_back()

template<typename T >
std::valarray<T> machine_learning::pop_back ( const std::valarray< T > &  A)

Function to remove last element from 1D vector

Template Parameters
Ttypename of the vector
Parameters
A1D vector from which last element will be removed
Returns
new resultant vector
117  {
118  std::valarray <T> B; // New 1D vector to store resultant vector
119  B.resize(A.size() - 1); // Resizing it accordingly
120  for(size_t i = 0; i < A.size() - 1; i ++) { // For every (except last) element in A
121  B[i] = A[i]; // Copy element in B
122  }
123  return B; // Return resultant vector
124 }

◆ pop_front()

template<typename T >
std::valarray<T> machine_learning::pop_front ( const std::valarray< T > &  A)

Function to remove first element from 1D vector

Template Parameters
Ttypename of the vector
Parameters
A1D vector from which first element will be removed
Returns
new resultant vector
101  {
102  std::valarray <T> B; // New 1D vector to store resultant vector
103  B.resize(A.size() - 1); // Resizing it accordingly
104  for(size_t i = 1; i < A.size(); i ++) { // // For every (except first) element in A
105  B[i - 1] = A[i]; // Copy element in B with left shifted position
106  }
107  return B; // Return resultant vector
108 }

◆ save_u_matrix()

int machine_learning::save_u_matrix ( const char *  fname,
const std::vector< std::vector< std::valarray< double >>> &  W 
)

Create the distance matrix or U-matrix from the trained 3D weiths matrix and save to disk.

Parameters
[in]fnamefilename to save in (gets overwriten without confirmation)
[in]Wmodel matrix to save
Returns
0 if all ok
-1 if file creation failed
143  {
144  std::ofstream fp(fname);
145  if (!fp) { // error with fopen
146  std::cerr << "File error (" << fname << "): " << std::strerror(errno)
147  << std::endl;
148  return -1;
149  }
150 
151  // neighborhood range
152  unsigned int R = 1;
153 
154  for (int i = 0; i < W.size(); i++) { // for each x
155  for (int j = 0; j < W[0].size(); j++) { // for each y
156  double distance = 0.f;
157 
158  int from_x = std::max<int>(0, i - R);
159  int to_x = std::min<int>(W.size(), i + R + 1);
160  int from_y = std::max<int>(0, j - R);
161  int to_y = std::min<int>(W[0].size(), j + R + 1);
162  int l = 0, m = 0;
163 #ifdef _OPENMP
164 #pragma omp parallel for reduction(+ : distance)
165 #endif
166  for (l = from_x; l < to_x; l++) { // scan neighborhoor in x
167  for (m = from_y; m < to_y; m++) { // scan neighborhood in y
168  auto d = W[i][j] - W[l][m];
169  double d2 = std::pow(d, 2).sum();
170  distance += std::sqrt(d2);
171  // distance += d2;
172  }
173  }
174 
175  distance /= R * R; // mean distance from neighbors
176  fp << distance; // print the mean separation
177  if (j < W[0].size() - 1) { // if not the last column
178  fp << ','; // suffix comma
179  }
180  }
181  if (i < W.size() - 1) { // if not the last row
182  fp << '\n'; // start a new line
183  }
184  }
185 
186  fp.close();
187  return 0;
188 }
Here is the call graph for this function:

◆ sum()

template<typename T >
T machine_learning::sum ( const std::vector< std::valarray< T >> &  A)

Function to get sum of all elements in 2D vector

Template Parameters
Ttypename of the vector
Parameters
A2D vector for which sum is required
Returns
returns sum of all elements of 2D vector
228  {
229  T cur_sum = 0; // Initially sum is zero
230  for(const auto &a : A) { // For every row in A
231  cur_sum += a.sum(); // Add sum of that row to current sum
232  }
233  return cur_sum; // Return sum
234 }

◆ transpose()

template<typename T >
std::vector<std::valarray <T> > machine_learning::transpose ( const std::vector< std::valarray< T >> &  A)

Function to get transpose of 2D vector

Template Parameters
Ttypename of the vector
Parameters
A2D vector which will be transposed
Returns
new resultant vector
363  {
364  const auto shape = get_shape(A); // Current shape of vector
365  std::vector <std::valarray <T> > B; // New vector to store result
366  // Storing transpose values of A in B
367  for(size_t j = 0; j < shape.second; j++) {
368  std::valarray <T> row;
369  row.resize(shape.first);
370  for(size_t i = 0; i < shape.first; i++) {
371  row[i] = A[i][j];
372  }
373  B.push_back(row);
374  }
375  return B; // Return new resultant 2D vector
376 }
Here is the call graph for this function:

◆ uniform_random_initialization()

template<typename T >
void machine_learning::uniform_random_initialization ( std::vector< std::valarray< T >> &  A,
const std::pair< size_t, size_t > &  shape,
const T &  low,
const T &  high 
)

Function to initialize given 2D vector using uniform random initialization

Template Parameters
Ttypename of the vector
Parameters
A2D vector to be initialized
shaperequired shape
lowlower limit on value
highupper limit on value
165  {
166  A.clear(); // Making A empty
167  // Uniform distribution in range [low, high]
168  std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
169  std::uniform_real_distribution <T> distribution(low, high);
170  for(size_t i = 0; i < shape.first; i++) { // For every row
171  std::valarray <T> row; // Making empty row which will be inserted in vector
172  row.resize(shape.second);
173  for(auto &r : row) { // For every element in row
174  r = distribution(generator); // copy random number
175  }
176  A.push_back(row); // Insert new row in vector
177  }
178  return;
179 }
Here is the call graph for this function:

◆ unit_matrix_initialization()

template<typename T >
void machine_learning::unit_matrix_initialization ( std::vector< std::valarray< T >> &  A,
const std::pair< size_t, size_t > &  shape 
)

Function to Intialize 2D vector as unit matrix

Template Parameters
Ttypename of the vector
Parameters
A2D vector to be initialized
shaperequired shape
191  {
192  A.clear(); // Making A empty
193  for(size_t i = 0; i < shape.first; i++) {
194  std::valarray <T> row; // Making empty row which will be inserted in vector
195  row.resize(shape.second);
196  row[i] = T(1); // Insert 1 at ith position
197  A.push_back(row); // Insert new row in vector
198  }
199  return;
200 }

◆ update_weights() [1/2]

void machine_learning::update_weights ( const std::valarray< double > &  x,
std::vector< std::valarray< double >> *  W,
std::valarray< double > *  D,
double  alpha,
int  R 
)

Update weights of the SOM using Kohonen algorithm

Parameters
[in]Xdata point
[in,out]Wweights matrix
[in,out]Dtemporary vector to store distances
[in]alphalearning rate \(0<\alpha\le1\)
[in]Rneighborhood range
105  {
106  int j = 0, k = 0;
107  int num_out = W->size(); // number of SOM output nodes
108  // int num_features = x.size(); // number of data features
109 
110 #ifdef _OPENMP
111 #pragma omp for
112 #endif
113  // step 1: for each output point
114  for (j = 0; j < num_out; j++) {
115  // compute Euclidian distance of each output
116  // point from the current sample
117  (*D)[j] = (((*W)[j] - x) * ((*W)[j] - x)).sum();
118  }
119 
120  // step 2: get closest node i.e., node with snallest Euclidian distance to
121  // the current pattern
122  auto result = std::min_element(std::begin(*D), std::end(*D));
123  // double d_min = *result;
124  int d_min_idx = std::distance(std::begin(*D), result);
125 
126  // step 3a: get the neighborhood range
127  int from_node = std::max(0, d_min_idx - R);
128  int to_node = std::min(num_out, d_min_idx + R + 1);
129 
130  // step 3b: update the weights of nodes in the
131  // neighborhood
132 #ifdef _OPENMP
133 #pragma omp for
134 #endif
135  for (j = from_node; j < to_node; j++) {
136  // update weights of nodes in the neighborhood
137  (*W)[j] += alpha * (x - (*W)[j]);
138  }
139 }
Here is the call graph for this function:

◆ update_weights() [2/2]

double machine_learning::update_weights ( const std::valarray< double > &  X,
std::vector< std::vector< std::valarray< double >>> *  W,
std::vector< std::valarray< double >> *  D,
double  alpha,
int  R 
)

Update weights of the SOM using Kohonen algorithm

Parameters
[in]Xdata point - N features
[in,out]Wweights matrix - PxQxN
[in,out]Dtemporary vector to store distances PxQ
[in]alphalearning rate \(0<\alpha\le1\)
[in]Rneighborhood range
Returns
minimum distance of sample and trained weights
203  {
204  int x = 0, y = 0;
205  int num_out_x = static_cast<int>(W->size()); // output nodes - in X
206  int num_out_y = static_cast<int>(W[0][0].size()); // output nodes - in Y
207  // int num_features = static_cast<int>(W[0][0][0].size()); // features =
208  // in Z
209  double d_min = 0.f;
210 
211 #ifdef _OPENMP
212 #pragma omp for
213 #endif
214  // step 1: for each output point
215  for (x = 0; x < num_out_x; x++) {
216  for (y = 0; y < num_out_y; y++) {
217  (*D)[x][y] = 0.f;
218  // compute Euclidian distance of each output
219  // point from the current sample
220  auto d = ((*W)[x][y] - X);
221  (*D)[x][y] = (d * d).sum();
222  (*D)[x][y] = std::sqrt((*D)[x][y]);
223  }
224  }
225 
226  // step 2: get closest node i.e., node with snallest Euclidian distance
227  // to the current pattern
228  int d_min_x = 0, d_min_y = 0;
229  get_min_2d(*D, &d_min, &d_min_x, &d_min_y);
230 
231  // step 3a: get the neighborhood range
232  int from_x = std::max(0, d_min_x - R);
233  int to_x = std::min(num_out_x, d_min_x + R + 1);
234  int from_y = std::max(0, d_min_y - R);
235  int to_y = std::min(num_out_y, d_min_y + R + 1);
236 
237  // step 3b: update the weights of nodes in the
238  // neighborhood
239 #ifdef _OPENMP
240 #pragma omp for
241 #endif
242  for (x = from_x; x < to_x; x++) {
243  for (y = from_y; y < to_y; y++) {
244  /* you can enable the following normalization if needed.
245  personally, I found it detrimental to convergence */
246  // const double s2pi = sqrt(2.f * M_PI);
247  // double normalize = 1.f / (alpha * s2pi);
248 
249  /* apply scaling inversely proportional to distance from the
250  current node */
251  double d2 =
252  (d_min_x - x) * (d_min_x - x) + (d_min_y - y) * (d_min_y - y);
253  double scale_factor = std::exp(-d2 / (2.f * alpha * alpha));
254 
255  (*W)[x][y] += (X - (*W)[x][y]) * alpha * scale_factor;
256  }
257  }
258  return d_min;
259 }
Here is the call graph for this function:

◆ zeroes_initialization()

template<typename T >
void machine_learning::zeroes_initialization ( std::vector< std::valarray< T >> &  A,
const std::pair< size_t, size_t > &  shape 
)

Function to Intialize 2D vector as zeroes

Template Parameters
Ttypename of the vector
Parameters
A2D vector to be initialized
shaperequired shape
211  {
212  A.clear(); // Making A empty
213  for(size_t i = 0; i < shape.first; i++) {
214  std::valarray <T> row; // Making empty row which will be inserted in vector
215  row.resize(shape.second); // By default all elements are zero
216  A.push_back(row); // Insert new row in vector
217  }
218  return;
219 }

Variable Documentation

◆ MIN_DISTANCE

constexpr double machine_learning::MIN_DISTANCE = 1e-4
constexpr

Minimum average distance of image nodes

std::srand
T srand(T... args)
std::max_element
T max_element(T... args)
machine_learning::update_weights
void update_weights(const std::valarray< double > &x, std::vector< std::valarray< double >> *W, std::valarray< double > *D, double alpha, int R)
Definition: kohonen_som_trace.cpp:103
std::vector
STL class.
std::vector::size
T size(T... args)
std::default_random_engine
std::distance
T distance(T... args)
std::strerror
T strerror(T... args)
machine_learning::update_weights
double update_weights(const std::valarray< double > &X, std::vector< std::vector< std::valarray< double >>> *W, std::vector< std::valarray< double >> *D, double alpha, int R)
Definition: kohonen_som_topology.cpp:200
get_min_2d
void get_min_2d(const std::vector< std::valarray< double >> &X, double *val, int *x_idx, int *y_idx)
Definition: kohonen_som_topology.cpp:105
std::sqrt
T sqrt(T... args)
std::vector::clear
T clear(T... args)
std::uniform_real_distribution
std::vector::push_back
T push_back(T... args)
std::cerr
std::ofstream
STL class.
std::min_element
T min_element(T... args)
std::valarray
STL class.
std::rand
T rand(T... args)
std::swap
T swap(T... args)
std::min
T min(T... args)
std::endl
T endl(T... args)
std::exp
T exp(T... args)
std::begin
T begin(T... args)
machine_learning::get_shape
std::pair< size_t, size_t > get_shape(const std::vector< std::valarray< T >> &A)
Definition: vector_ops.hpp:243
std::make_pair
T make_pair(T... args)
std::end
T end(T... args)
std::max
T max(T... args)
std::exit
T exit(T... args)
std::ostream::precision
T precision(T... args)
machine_learning::sum
T sum(const std::vector< std::valarray< T >> &A)
Definition: vector_ops.hpp:228
std::pow
T pow(T... args)
std::chrono::system_clock::now
T now(T... args)