Alexandria 2.31.0
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
SOM.icpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2022 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 SOM.icpp
21 * @author nikoapos
22 */
23
24#include "SOM/ImplTools.h"
25
26namespace Euclid {
27namespace SOM {
28
29template <typename DistFunc>
30SOM<DistFunc>::SOM(std::size_t dimensions, std::size_t x, std::size_t y, InitFunc::Signature init_func)
31 : m_dimensions(dimensions)
32 , m_cells(std::make_tuple(ImplTools::indexAxis("X", x), ImplTools::indexAxis("Y", y)), m_dimensions)
33 , m_size(x, y) {
34
35 // Initialize all the grid cells using the given function
36 for (auto array : m_cells) {
37 for (auto& w : array) {
38 w = init_func();
39 }
40 }
41
42} // end of namespace SOM_impl
43
44template <typename DistFunc>
45const std::pair<std::size_t, std::size_t>& SOM<DistFunc>::getSize() const {
46 return m_size;
47}
48
49template <typename DistFunc>
50std::size_t SOM<DistFunc>::getDimensions() const {
51 return m_dimensions;
52}
53
54template <typename DistFunc>
55auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) -> reference_type {
56 return m_cells(x, y);
57}
58
59template <typename DistFunc>
60auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) const -> const reference_type {
61 return m_cells(x, y);
62}
63
64template <typename DistFunc>
65typename SOM<DistFunc>::iterator SOM<DistFunc>::begin() {
66 return m_cells.begin();
67}
68
69template <typename DistFunc>
70typename SOM<DistFunc>::iterator SOM<DistFunc>::end() {
71 return m_cells.end();
72}
73
74template <typename DistFunc>
75typename SOM<DistFunc>::const_iterator SOM<DistFunc>::begin() const {
76 return m_cells.begin();
77}
78
79template <typename DistFunc>
80typename SOM<DistFunc>::const_iterator SOM<DistFunc>::end() const {
81 return m_cells.end();
82}
83
84template <typename DistFunc>
85typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cbegin() {
86 return m_cells.cbegin();
87}
88
89template <typename DistFunc>
90typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cend() {
91 return m_cells.cend();
92}
93
94template <typename DistFunc>
95std::tuple<std::size_t, std::size_t, double> SOM<DistFunc>::findBMU(const std::vector<double>& input) const {
96 assert(input.size() == m_dimensions);
97 DistFunc dist_func{};
98 auto result_iter = begin();
99 double closest_distance = std::numeric_limits<double>::max();
100 auto end_ = end();
101 for (auto iter = begin(); iter != end_; ++iter) {
102 double dist = dist_func.distance(iter->cbegin(), iter->cend(), input.cbegin());
103 if (dist < closest_distance) {
104 result_iter = iter;
105 closest_distance = dist;
106 }
107 }
108 return std::make_tuple(result_iter.template axisValue<0>(), result_iter.template axisValue<1>(), closest_distance);
109}
110
111template <typename DistFunc>
112std::tuple<std::size_t, std::size_t, double> SOM<DistFunc>::findBMU(const std::vector<double>& input,
113 const std::vector<double>& uncertainties) const {
114 assert(input.size() == m_dimensions);
115 DistFunc dist_func{};
116 auto result_iter = begin();
117 double closest_distance = std::numeric_limits<double>::max();
118 const auto end_ = end();
119 for (auto iter = begin(); iter != end_; ++iter) {
120 double dist = dist_func.distance(iter->cbegin(), iter->cend(), input.cbegin(), uncertainties.cbegin());
121 if (dist < closest_distance) {
122 result_iter = iter;
123 closest_distance = dist;
124 }
125 }
126 return std::make_tuple(result_iter.template axisValue<0>(), result_iter.template axisValue<1>(), closest_distance);
127}
128
129template <typename DistFunc>
130template <typename InputType, typename WeightFunc>
131std::tuple<std::size_t, std::size_t, double> SOM<DistFunc>::findBMU(const InputType& input,
132 WeightFunc weight_func) const {
133
134 static_assert(std::is_same<decltype(std::declval<WeightFunc>()(input)), std::vector<double>>::value,
135 "WeightFunc must be callable with input as parameter, returning an std::vector<double>");
136
137 return findBMU(weight_func(input));
138}
139
140template <typename DistFunc>
141template <typename InputType, typename WeightFunc, typename UncertaintyFunc>
142std::tuple<std::size_t, std::size_t, double> SOM<DistFunc>::findBMU(const InputType& input, WeightFunc weight_func,
143 UncertaintyFunc uncertainty_func) const {
144
145 static_assert(std::is_same<decltype(std::declval<WeightFunc>()(input)), std::vector<double>>::value,
146 "WeightFunc must be callable with input as parameter, returning an std::vector<double>");
147 static_assert(std::is_same<decltype(std::declval<UncertaintyFunc>()(input)), std::vector<double>>::value,
148 "UncertaintyFunc must be callable with input as parameter, returning an std::vector<double>");
149
150 return findBMU(weight_func(input), uncertainty_func(input));
151}
152
153} // namespace SOM
154} // namespace Euclid