SOMHunter Core
vector.hpp
Go to the documentation of this file.
1 /* This file is part of SOMHunter.
2  *
3  * Copyright (C) 2021 Frantisek Mejzlik <frankmejzlik@protonmail.com>
4  * Mirek Kratochvil <exa.exa@gmail.com>
5  * Patrik Vesely <prtrikvesely@gmail.com>
6  *
7  * SOMHunter is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free
9  * Software Foundation, either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * SOMHunter is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * SOMHunter. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
26 #ifndef VECTOR_H_
27 #define VECTOR_H_
28 
29 #include <execution>
30 #include <vector>
31 // ---
32 #include "common.h"
33 #include "distances.hpp"
34 
35 namespace math {
36 namespace vector {
37 
43 template <typename T_>
44 inline std::vector<T_> sub(const std::vector<T_>& left, const std::vector<T_>& right) {
45  if (left.size() != right.size()) {
46  SHLOG_E("Vectors have different sizes.");
47 #ifndef NDEBUG
48  throw std::runtime_error("Vectors have different sizes.");
49 #endif
50  }
51 
52  std::vector<T_> result;
53  result.resize(left.size());
54 
55  size_t i = 0;
56  for (auto& v : result) {
57  v = left[i] - right[i];
58  ++i;
59  }
60 
61  return result;
62 }
63 
69 template <typename T_>
70 inline std::vector<T_> add(const std::vector<T_>& left, const std::vector<T_>& right) {
71  if (left.size() != right.size()) {
72  SHLOG_E("Vectors have different sizes.");
73 #ifndef NDEBUG
74  throw std::runtime_error("Vectors have different sizes.");
75 #endif
76  }
77 
78  std::vector<T_> result;
79  result.resize(left.size());
80 
81  size_t i = 0;
82  for (auto& v : result) {
83  v = left[i] + right[i];
84  ++i;
85  }
86 
87  return result;
88 }
89 
95 template <typename T_, typename S_>
96 inline std::vector<T_> mult(const std::vector<T_>& left, S_ right) {
97  std::vector<T_> result(left.size());
98 
99  std::transform(std::execution::par_unseq, left.begin(), left.end(), result.begin(),
100  [right](const T_& l) { return l * right; });
101 
102  return result;
103 }
104 
110 template <typename T_>
111 inline std::vector<T_> mult(const std::vector<T_>& left, const std::vector<T_>& right) {
112  if (left.size() != right.size()) {
113  SHLOG_E("Vectors have different sizes.");
114 #ifndef NDEBUG
115  throw std::runtime_error("Vectors have different sizes.");
116 #endif
117  }
118 
119  std::vector<T_> result;
120 
121  std::transform(left.begin(), left.end(), right.begin(), std::back_inserter(result),
122  [](const T_& l, const T_& r) { return l * r; });
123 
124  return result;
125 }
126 
132 template <typename T_>
133 inline T_ dot(const std::vector<T_>& left, const std::vector<T_>& right) {
134  if (left.size() != right.size()) {
135  SHLOG_E("Vectors have different sizes.");
136 #ifndef NDEBUG
137  throw std::runtime_error("Vectors have different sizes.");
138 #endif
139  }
140 
141  std::vector<T_> sum = mult<T_>(left, right);
142 
143  return std::accumulate(sum.begin(), sum.end(), 0.0f, std::plus<T_>());
144 }
145 
146 template <typename T_>
147 inline std::vector<T_> mat_mult(const std::vector<std::vector<T_>>& mat, const std::vector<T_>& vec) {
148  if (mat.empty() || mat[0].size() != vec.size()) {
149  SHLOG_E("Vectors have different sizes.");
150 #ifndef NDEBUG
151  throw std::runtime_error("Vectors have different sizes.");
152 #endif
153  }
154 
155  std::vector<T_> result;
156  result.resize(mat.size());
157 
158  size_t i = 0;
159  for (auto&& mat_row_vec : mat) result[i++] = dot(mat_row_vec, vec);
160 
161  return result;
162 }
163 
164 template <typename T_>
165 inline float length(const std::vector<T_>& left) {
166  return sqrtf(dot(left, left));
167 }
168 
169 template <typename T_>
170 inline std::vector<T_> normalize(const std::vector<T_>& left) {
171  float vec_size = length(left);
172 
173  if (vec_size > 0.0f)
174  return mult(left, (1.0f / vec_size));
175  else {
176  SHLOG_E("Zero vector!");
177 #ifndef NDEBUG
178  throw std::runtime_error("Zero vector!");
179 #else
180  return std::vector<T_>{};
181 #endif
182  }
183 }
184 
185 }; // namespace vector
186 }; // namespace math
187 
188 #endif // VECTOR_H_
File implementing distance calculations on vectors.
std::vector< T_ > mult(const std::vector< T_ > &left, S_ right)
Computes the element-wise multiplication of the given vector and constant right.
Definition: vector.hpp:96
T_ dot(const std::vector< T_ > &left, const std::vector< T_ > &right)
Computes the dot product of the given vectors.
Definition: vector.hpp:133
float length(const std::vector< T_ > &left)
Definition: vector.hpp:165
std::vector< T_ > normalize(const std::vector< T_ > &left)
Definition: vector.hpp:170
std::vector< T_ > mat_mult(const std::vector< std::vector< T_ >> &mat, const std::vector< T_ > &vec)
Definition: vector.hpp:147
std::vector< T_ > sub(const std::vector< T_ > &left, const std::vector< T_ > &right)
Computes the substraction of the given vectors (left - right).
Definition: vector.hpp:44
std::vector< T_ > add(const std::vector< T_ > &left, const std::vector< T_ > &right)
Computes the addition of the given vectors (left + right).
Definition: vector.hpp:70
Definition: vector.hpp:35
#define SHLOG_E(x)
Definition: static-logger.hpp:157