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"
29 template <typename DistFunc>
30 SOM<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
44 template <typename DistFunc>
45 const std::pair<std::size_t, std::size_t>& SOM<DistFunc>::getSize() const {
49 template <typename DistFunc>
50 std::size_t SOM<DistFunc>::getDimensions() const {
54 template <typename DistFunc>
55 auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) -> reference_type {
59 template <typename DistFunc>
60 auto SOM<DistFunc>::operator()(std::size_t x, std::size_t y) const -> const reference_type {
64 template <typename DistFunc>
65 typename SOM<DistFunc>::iterator SOM<DistFunc>::begin() {
66 return m_cells.begin();
69 template <typename DistFunc>
70 typename SOM<DistFunc>::iterator SOM<DistFunc>::end() {
74 template <typename DistFunc>
75 typename SOM<DistFunc>::const_iterator SOM<DistFunc>::begin() const {
76 return m_cells.begin();
79 template <typename DistFunc>
80 typename SOM<DistFunc>::const_iterator SOM<DistFunc>::end() const {
84 template <typename DistFunc>
85 typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cbegin() {
86 return m_cells.cbegin();
89 template <typename DistFunc>
90 typename SOM<DistFunc>::const_iterator SOM<DistFunc>::cend() {
91 return m_cells.cend();
94 template <typename DistFunc>
95 std::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);
111 template <typename DistFunc>
112 std::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);
129 template <typename DistFunc>
130 template <typename InputType, typename WeightFunc>
131 std::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));
140 template <typename DistFunc>
141 template <typename InputType, typename WeightFunc, typename UncertaintyFunc>
142 std::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));
154 } // namespace Euclid