Alexandria  2.16
Please provide a description of the project.
NeighborhoodFunc.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * @file NeighborhoodFunc.h
21  * @author nikoapos
22  */
23 
24 #ifndef SOM_NEIGHBORHOODFUNC_H
25 #define SOM_NEIGHBORHOODFUNC_H
26 
27 #include <functional>
28 #include <cmath>
29 
30 namespace Euclid {
31 namespace SOM {
32 namespace NeighborhoodFunc {
33 
34 using Signature = std::function<double(std::pair<std::size_t, std::size_t> bmu,
35  std::pair<std::size_t, std::size_t> cell,
36  std::size_t iteration, std::size_t total_iterations)>;
37 
38 Signature linearUnitDisk(double initial_radius) {
39  double r_square = initial_radius * initial_radius;
40  return [r_square](std::pair<std::size_t, std::size_t> bmu,
41  std::pair<std::size_t, std::size_t> cell,
42  std::size_t iteration, std::size_t total_iterations) -> double {
43  double iter_factor = 1.0 * (total_iterations - iteration) / total_iterations;
44  iter_factor = iter_factor * iter_factor; // We compare the squared distances
45  double x = bmu.first - cell.first;
46  double y = bmu.second - cell.second;
47  double dist_square = x * x + y * y;
48  if (dist_square < r_square * iter_factor) {
49  return 1.;
50  } else {
51  return 0.;
52  }
53  };
54 }
55 
56 Signature kohonen(std::size_t x_size, std::size_t y_size, double sigma_cutoff_mult=1.) {
57 
58  double init_sigma = std::max(x_size, y_size) / 2.;
59  std::tuple<std::size_t, std::size_t, double> sigma_buffer {0, 0, 0.};
60  double cutoff_mult_square = sigma_cutoff_mult * sigma_cutoff_mult;
61 
62  return [init_sigma, sigma_buffer, cutoff_mult_square](
63  std::pair<std::size_t, std::size_t> bmu,
64  std::pair<std::size_t, std::size_t> cell,
65  std::size_t iteration, std::size_t total_iterations) mutable -> double {
66 
67  // If we have new iteration we recompute the sigma, otherwise we use the already
68  // calculated one
69  if (std::get<0>(sigma_buffer) != iteration || std::get<1>(sigma_buffer) != total_iterations) {
70  std::get<0>(sigma_buffer) = iteration;
71  std::get<1>(sigma_buffer) = total_iterations;
72  double time_constant = total_iterations / std::log(init_sigma);
73  std::get<2>(sigma_buffer) = init_sigma * std::exp(-1. * iteration / time_constant);
74  }
75  double sigma_square = std::get<2>(sigma_buffer) * std::get<2>(sigma_buffer);
76 
77  double x = static_cast<double>(bmu.first) - cell.first;
78  double y = static_cast<double>(bmu.second) - cell.second;
79  double dist_square = x * x + y * y;
80 
81  if (dist_square < cutoff_mult_square * sigma_square) {
82  return std::exp(-1. * dist_square / (2. * sigma_square));
83  } else {
84  return 0.;
85  }
86 
87 
88  };
89 }
90 
91 }
92 }
93 }
94 
95 #endif /* SOM_NEIGHBORHOODFUNC_H */
96 
std::function< double(std::pair< std::size_t, std::size_t > bmu, std::pair< std::size_t, std::size_t > cell, std::size_t iteration, std::size_t total_iterations)> Signature
Signature linearUnitDisk(double initial_radius)
Signature kohonen(std::size_t x_size, std::size_t y_size, double sigma_cutoff_mult=1.)