Theoretica
A C++ numerical and automatic mathematical library
Loading...
Searching...
No Matches
distance.h
Go to the documentation of this file.
1
7
8#ifndef THEORETICA_DISTANCE_H
9#define THEORETICA_DISTANCE_H
10
11#include "./vec.h"
12#include "./algebra.h"
13#include "../core/constants.h"
14#include "../core/core_traits.h"
15#include "../core/real_analysis.h"
16#include "../complex/complex_analysis.h"
17
18
19namespace theoretica {
20
21 namespace algebra {
22
23
25
26
33 template<typename Vector>
34 inline real lp_norm(const Vector& v, unsigned int p) {
35
36 real sum = 0;
37
38 for (unsigned int i = 0; i < v.size(); ++i)
39 sum += pow(abs(v[i]), p);
40
41 return root(sum, p);
42 }
43
44
50 template<typename Vector>
51 inline real l1_norm(const Vector& v) {
52
53 real sum = 0;
54
55 for (unsigned int i = 0; i < v.size(); ++i)
56 sum += abs(v[i]);
57
58 return sum;
59 }
60
66 template<typename Vector>
67 inline real l2_norm(const Vector& v) {
68
69 auto sum = pair_inner_product(v[0], v[0]);
70
71 for (unsigned int i = 1; i < v.size(); ++i)
72 sum += pair_inner_product(v[i], v[i]);
73
74 return real(sqrt(sum));
75 }
76
77
83 template<typename Vector>
84 inline real linf_norm(const Vector& v) {
85
86 real res = abs(v[0]);
87
88 for (unsigned int i = 1; i < v.size(); ++i)
89 res = max(res, abs(v[i]));
90
91 return res;
92 }
93
94
96
97
104 template<typename Vector>
105 inline real euclidean_distance(const Vector& v1, const Vector& v2) {
106
107 if(v1.size() != v2.size()) {
108 TH_MATH_ERROR("euclidean_distance", v1.size(), INVALID_ARGUMENT);
109 return nan();
110 }
111
112 return l2_norm(v1 - v2);
113 }
114
115
122 template<unsigned int N>
123 inline real distance(const vec<real, N>& v1, const vec<real, N>& v2) {
124 return euclidean_distance(v1, v2);
125 }
126
127
135 return abs(a - b);
136 }
137
138
145 inline real distance(real a, real b) {
146 return euclidean_distance(a, b);
147 }
148
149
156 template<typename T>
158 return (z1 - z2).norm();
159 }
160
161
169 template<typename Vector>
170 inline real minkowski_distance(const Vector& v1, const Vector& v2, unsigned int p) {
171
172 if(v1.size() != v2.size()) {
173 TH_MATH_ERROR("minkowski_distance", v1.size(), INVALID_ARGUMENT);
174 return nan();
175 }
176
177 return lp_norm(v1 - v2, p);
178 }
179
180
188 inline real minkowski_distance(real a, real b, unsigned int p) {
189 return root(pow(abs(b - a), p), p);
190 }
191
192
199 template<typename Vector, typename T = real>
200 inline auto hermitian_distance(const Vector& v1, const Vector& v2) {
201
202 if(v1.size() != v2.size()) {
203 TH_MATH_ERROR("hermitian_distance", v1.size(), INVALID_ARGUMENT);
204 return complex<T>(nan());
205 }
206
207 complex<T> sum = 0;
208
209 for (size_t i = 0; i < v1.size(); ++i) {
210 const complex<T> diff = v1[i] - conjugate(v2[i]);
211 sum += diff * diff.conjugate();
212 }
213
214 return sqrt(sum);
215 }
216
217
224 template<unsigned int N, typename T>
226 const vec<complex<T>, N>& v1, const vec<complex<T>, N>& v2) {
227
229 }
230
231
238 template<typename Vector>
239 inline real manhattan_distance(const Vector& v1, const Vector& v2) {
240
241 if(v1.size() != v2.size()) {
242 TH_MATH_ERROR("manhattan_distance", v1.size(), INVALID_ARGUMENT);
243 return nan();
244 }
245
246 return l1_norm(v1 - v2);
247 }
248
249
256 template<typename Vector>
257 inline real chebyshev_distance(const Vector& v1, const Vector& v2) {
258
259 if(v1.size() != v2.size()) {
260 TH_MATH_ERROR("chebyshev_distance", v1.size(), INVALID_ARGUMENT);
261 return nan();
262 }
263
264 return linf_norm(v1 - v2);
265 }
266
267
275 template<typename Vector>
277 const Vector& v1, const Vector& v2, real tolerance = MACH_EPSILON) {
278
279 if(v1.size() != v2.size()) {
280 TH_MATH_ERROR("discrete_distance", v1.size(), INVALID_ARGUMENT);
281 return nan();
282 }
283
284 bool diff = false;
285
286 for (size_t i = 0; i < v1.size(); ++i) {
287
288 // The vectors differ if a pair of elements differs
289 // more than the given tolerance
290 if(abs(v1[i] - v2[i]) > tolerance) {
291 diff = true;
292 break;
293 }
294 }
295
296 return diff ? 1 : 0;
297 }
298
299
305 template<typename Vector>
306 inline real canberra_distance(const Vector& v1, const Vector& v2) {
307
308 if(v1.size() != v2.size()) {
309 TH_MATH_ERROR("canberra_distance", v1.size(), INVALID_ARGUMENT);
310 return nan();
311 }
312
313 real sum = 0;
314
315 for (size_t i = 0; i < v1.size(); ++i)
316 sum += abs(v1[i] - v2[i]) / (abs(v1[i]) + abs(v2[i]));
317
318 return sum;
319 }
320
321
327 template<typename Vector>
328 inline real cosine_distance(const Vector& v1, const Vector& v2) {
329
330 if(v1.size() != v2.size()) {
331 TH_MATH_ERROR("cosine_distance", v1.size(), INVALID_ARGUMENT);
332 return nan();
333 }
334
335 real product = 0;
336 real sum_sqr_x = 0;
337 real sum_sqr_y = 0;
338
339 for (size_t i = 0; i < v1.size(); ++i) {
340 product += v1[i] * v2[i];
341 sum_sqr_x += square(v1[i]);
342 sum_sqr_y += square(v2[i]);
343 }
344
345 return product / sqrt(sum_sqr_x * sum_sqr_y);
346 }
347
348
356 template<typename Vector>
358 const Vector& v1, const Vector& v2, real tolerance = MACH_EPSILON) {
359
360 if(v1.size() != v2.size()) {
361 TH_MATH_ERROR("hamming_distance", v1.size(), INVALID_ARGUMENT);
362 return nan();
363 }
364
365 unsigned int count = 0;
366
367 // Count how many elements differ to some tolerance
368 for (unsigned int i = 0; i < v1.size(); ++i)
369 if(abs(v1[i] - v2[i]) > tolerance)
370 count++;
371
372 return count;
373 }
374 }
375}
376
377#endif
Linear algebra routines.
A statically allocated N-dimensional vector with elements of the given type.
Definition vec.h:92
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:225
real l2_norm(const Vector &v)
Compute the L2 norm of a vector: .
Definition distance.h:67
real discrete_distance(const Vector &v1, const Vector &v2, real tolerance=MACH_EPSILON)
Compute the discrete distance between two vectors.
Definition distance.h:276
real l1_norm(const Vector &v)
Compute the L1 norm of a vector: .
Definition distance.h:51
real minkowski_distance(const Vector &v1, const Vector &v2, unsigned int p)
Compute the Minkowski distance between two vectors: .
Definition distance.h:170
real manhattan_distance(const Vector &v1, const Vector &v2)
Compute the Manhattan distance between two vectors: .
Definition distance.h:239
real euclidean_distance(const Vector &v1, const Vector &v2)
Distances.
Definition distance.h:105
real cosine_distance(const Vector &v1, const Vector &v2)
Compute the cosine distance between two vectors.
Definition distance.h:328
auto pair_inner_product(const Type &v_i, const Type &w_i)
Compute the contribution of the inner product between a pair of elements of two vectors,...
Definition algebra.h:252
auto hermitian_distance(const Vector &v1, const Vector &v2)
Compute the Hermitian distance between two vectors: .
Definition distance.h:200
real linf_norm(const Vector &v)
Compute the Linf norm of a vector: .
Definition distance.h:84
real canberra_distance(const Vector &v1, const Vector &v2)
Compute the Canberra distance between two vectors.
Definition distance.h:306
real lp_norm(const Vector &v, unsigned int p)
Norms.
Definition distance.h:34
real hamming_distance(const Vector &v1, const Vector &v2, real tolerance=MACH_EPSILON)
Compute the Hamming distance between two vectors.
Definition distance.h:357
real distance(const vec< real, N > &v1, const vec< real, N > &v2)
Compute the Euclidean distance between two vectors: .
Definition distance.h:123
real chebyshev_distance(const Vector &v1, const Vector &v2)
Compute the Chebyshev distance between two vectors: .
Definition distance.h:257
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:198
dual2 sqrt(dual2 x)
Compute the square root of a second order dual number.
Definition dual2_functions.h:54
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:198
std::remove_reference_t< decltype(std::declval< Structure >()[0])> vector_element_t
Extract the type of a vector (or any indexable container) from its operator[].
Definition core_traits.h:134
auto sum(const Vector &X)
Compute the sum of a vector of real values using pairwise summation to reduce round-off error.
Definition dataset.h:219
dual2 conjugate(dual2 x)
Return the conjugate of a second order dual number.
Definition dual2_functions.h:35
auto max(const Vector &X)
Finds the maximum value inside a dataset.
Definition dataset.h:330
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:207
real root(real x, int n)
Compute the n-th root of x.
Definition real_analysis.h:812
auto product(const Vector &X)
Compute the product of a set of values.
Definition dataset.h:29
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition dual2_functions.h:23
dual2 pow(dual2 x, int n)
Compute the n-th power of a second order dual number.
Definition dual2_functions.h:41
Vector class and operations.