2 * Copyright (C) 2012-2022 Euclid Science Ground Segment
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)
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
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
24#include "SOM/ImplTools.h"
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)
35 // Initialize all the grid cells using the given function
36 for (auto array : m_cells) {
37 for (auto& w : array) {
42} // end of namespace SOM_impl
44template <typename DistFunc>
45const std::pair<std::size_t, std::size_t>& SOM<DistFunc>::getSize() const {
49template <typename DistFunc>
50std::size_t SOM<DistFunc>::getDimensions() const {
54template <typename DistFunc>
55auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) -> reference_type {
59template <typename DistFunc>
60auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) const -> const reference_type {
64template <typename DistFunc>
65typename SOM<DistFunc>::iterator SOM<DistFunc>::begin() {
66 return m_cells.begin();
69template <typename DistFunc>
70typename SOM<DistFunc>::iterator SOM<DistFunc>::end() {
74template <typename DistFunc>
75typename SOM<DistFunc>::const_iterator SOM<DistFunc>::begin() const {
76 return m_cells.begin();
79template <typename DistFunc>
80typename SOM<DistFunc>::const_iterator SOM<DistFunc>::end() const {
84template <typename DistFunc>
85typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cbegin() {
86 return m_cells.cbegin();
89template <typename DistFunc>
90typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cend() {
91 return m_cells.cend();
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);
98 auto result_iter = begin();
99 double closest_distance = std::numeric_limits<double>::max();
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) {
105 closest_distance = dist;
108 return std::make_tuple(result_iter.template axisValue<0>(), result_iter.template axisValue<1>(), closest_distance);
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) {
123 closest_distance = dist;
126 return std::make_tuple(result_iter.template axisValue<0>(), result_iter.template axisValue<1>(), closest_distance);
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 {
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>");
137 return findBMU(weight_func(input));
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 {
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>");
150 return findBMU(weight_func(input), uncertainty_func(input));