UFJF - Machine Learning Toolkit  0.51.8
DistanceMetric.hpp
1 #pragma once
2 
3 #include "Point.hpp"
4 #include <cmath>
5 
6 namespace mltk::metrics::dist{
10  template<typename T = double>
12  protected:
13  std::string m_family, m_name;
14  public:
15  DistanceMetric() = default;
16 
17  std::string& family() { return m_family; }
18  std::string& name() { return m_name; }
19 
20  virtual T operator()(const Point <T> &p1, const Point <T> &p2) const = 0;
21  };
22 
23  // Lp Minkowski metrics measures
24 
28  template<typename T = double>
29  class Euclidean : public DistanceMetric<T> {
30  public:
31  Euclidean(){
32  this->m_family = "Lp Minkowski distances";
33  this->m_name = "Euclidean";
34  }
35  T operator()(const Point <T> &p1, const Point <T> &p2) const {
36  T sum = 0;
37  Point<T> p = mltk::pow(p1 - p2, 2);
38  for(int i = 0; i < p.size(); i++)
39  sum += p[i];
40  return std::sqrt(sum);
41  }
42  };
43 
44  template<typename T = double>
45  class Manhattan : public DistanceMetric<T> {
46  public:
47  Manhattan(){
48  this->m_family = "Lp Minkowski distances";
49  this->m_name = "Manhattan";
50  }
51  T operator()(const Point <T> &p1, const Point <T> &p2) const {
52  return mltk::abs(p1 - p2).sum();
53  }
54  };
55 
56  template<typename T = double>
57  class Chebyshev : public DistanceMetric<T> {
58  public:
59  Chebyshev(){
60  this->m_family = "Lp Minkowski distances";
61  this->m_name = "Chebyshev";
62  }
63  T operator()(const Point <T> &p1, const Point <T> &p2) const {
64  return mltk::max(mltk::abs(p1 - p2));
65  }
66  };
67 
68  // L1 Distance measures
69 
70  template<typename T = double>
71  class Lorentzian : public DistanceMetric<T> {
72  public:
73  Lorentzian(){
74  this->m_family = "L1 Distance measures";
75  this->m_name = "Lorentzian";
76  }
77  T operator()(const Point <T> &p1, const Point <T> &p2) const {
78  return mltk::log(1 - mltk::abs(p1 - p2)).sum();
79  }
80  };
81 
82  template<typename T = double>
83  class Canberra : public DistanceMetric<T> {
84  public:
85  T operator()(const Point <T> &p1, const Point <T> &p2) const {
86  return (mltk::abs(p1 - p2) / (mltk::abs(p1) + mltk::abs(p2))).sum();
87  }
88  };
89 
90  template<typename T = double>
91  class Sorensen : public DistanceMetric<T> {
92  public:
93  T operator()(const Point <T> &p1, const Point <T> &p2) const {
94  return mltk::abs(p1 - p2).sum() / (p1 + p2).sum();
95  }
96  };
97 
98  template<typename T = double>
99  class AvgManhattan : public DistanceMetric<T> {
100  public:
101  T operator()(const Point <T> &p1, const Point <T> &p2) const {
102  return mltk::abs(p1 - p2).sum() / p1.size();
103  }
104  };
105 
106  template<typename T = double>
107  class NonIntersection : public DistanceMetric<T> {
108  public:
109  T operator()(const Point <T> &p1, const Point <T> &p2) const {
110  return (1 / 2) * mltk::abs(p1 - p2).sum();
111  }
112  };
113 
114  // Inner product metrics measures
115 
116  template<typename T = double>
117  class Jaccard : public DistanceMetric<T> {
118  public:
119  Jaccard(){
120  this->m_family = "Inner product metrics measures";
121  this->m_name = "Jaccard";
122  }
123  T operator()(const Point <T> &p1, const Point <T> &p2) const {
124  return mltk::pow(p1 - p2, 2).sum() /
125  (mltk::pow(p1, 2).sum() + mltk::pow(p2, 2).sum() - (p1 * p2).sum());
126  }
127  };
128 
129  template<typename T = double>
130  class Cosine : public DistanceMetric<T> {
131  public:
132  Cosine(){
133  this->m_family = "Inner product metrics measures";
134  this->m_name = "Cosine";
135  }
136  T operator()(const Point <T> &p1, const Point <T> &p2) const {
137  return 1 - (p1 * p2).sum() / (std::sqrt(mltk::pow(p1, 2).sum()) * std::sqrt(mltk::pow(p2, 2).sum()));
138  }
139  };
140 
141  template<typename T = double>
142  class Dice : public DistanceMetric<T> {
143  public:
144  Dice(){
145  this->m_family = "Inner product metrics measures";
146  this->m_name = "Dice";
147  }
148  T operator()(const Point <T> &p1, const Point <T> &p2) const {
149  return 1 - 2 * (p1 * p2).sum() / (mltk::pow(p1, 2).sum() + mltk::pow(p2, 2).sum());
150  }
151  };
152 
153  template<typename T = double>
154  class Chord : public DistanceMetric<T> {
155  public:
156  Chord(){
157  this->m_family = "Inner product metrics measures";
158  this->m_name = "Chord";
159  }
160  T operator()(const Point <T> &p1, const Point <T> &p2) const {
161  return std::sqrt(2 - 2 * ((p1 * p2).sum() / (mltk::pow(p1, 2).sum() * mltk::pow(p2, 2).sum())));
162  }
163  };
164 
165  //Squared Chord distance measures
166 
167  template<typename T = double>
168  class Bhattacharyya : public DistanceMetric<T> {
169  public:
170  Bhattacharyya(){
171  this->m_family = "Squared Chord distance measures";
172  this->m_name = "Bhattacharyya";
173  }
174  T operator()(const Point <T> &p1, const Point <T> &p2) const {
175  return -std::sqrt(mltk::pow(p1 * p2, 0.5).sum());
176  }
177  };
178 
179  template<typename T = double>
180  class SquaredChord : public DistanceMetric<T> {
181  public:
182  SquaredChord(){
183  this->m_family = "Squared Chord distance measures";
184  this->m_name = "SquaredChord";
185  }
186  T operator()(const Point <T> &p1, const Point <T> &p2) const {
187  return mltk::pow(mltk::pow(p1, 0.5) - mltk::pow(p2, 0.5), 2).sum();
188  }
189  };
190 
191  template<typename T = double>
192  class Matusita : public DistanceMetric<T> {
193  public:
194  Matusita(){
195  this->m_family = "Squared Chord distance measures";
196  this->m_name = "Matusita";
197  }
198  T operator()(const Point <T> &p1, const Point <T> &p2) const {
199  return std::sqrt(mltk::pow(mltk::pow(p1, 0.5) - mltk::pow(p2, 0.5), 2).sum());
200  }
201  };
202 
203  template<typename T = double>
204  class Hellinger : public DistanceMetric<T> {
205  public:
206  Hellinger(){
207  this->m_family = "Squared Chord distance measures";
208  this->m_name = "Hellinger";
209  }
210  T operator()(const Point <T> &p1, const Point <T> &p2) const {
211  return std::sqrt(2 * mltk::pow(mltk::pow(p1, 0.5) - mltk::pow(p2, 0.5), 2).sum());
212  }
213  };
214 
215  // Squared L2 distance measures
216 
217  template<typename T = double>
218  class SquaredEuclidean : public DistanceMetric<T> {
219  public:
221  this->m_family = "Squared L2 distance measures";
222  this->m_name = "SquaredEuclidean";
223  }
224  T operator()(const Point <T> &p1, const Point <T> &p2) const {
225  return mltk::pow(p1 - p2, 2).sum();
226  }
227  };
228 
229  template<typename T = double>
230  class Clark: public DistanceMetric<T> {
231  public:
232  Clark(){
233  this->m_family = "Squared L2 distance measures";
234  this->m_name = "Clark";
235  }
236  T operator()(const Point <T> &p1, const Point <T> &p2) const {
237  return mltk::pow((p1 - p2)/(mltk::abs(p1) + mltk::abs(p2)), 2).sum();
238  }
239  };
240 
241  template<typename T = double>
242  class Neyman: public DistanceMetric<T> {
243  public:
244  Neyman(){
245  this->m_family = "Squared L2 distance measures";
246  this->m_name = "Neyman";
247  }
248  T operator()(const Point <T> &p1, const Point <T> &p2) const {
249  return (mltk::pow(p1 - p2, 2)/p1).sum();
250  }
251  };
252 
253  template<typename T = double>
254  class Pearson: public DistanceMetric<T> {
255  public:
256  Pearson(){
257  this->m_family = "Squared L2 distance measures";
258  this->m_name = "Pearson";
259  }
260  T operator()(const Point <T> &p1, const Point <T> &p2) const {
261  return (mltk::pow(p1 - p2, 2)/p2).sum();
262  }
263  };
264 
265  template<typename T = double>
266  class Squared: public DistanceMetric<T> {
267  public:
268  Squared(){
269  this->m_family = "Squared L2 distance measures";
270  this->m_name = "Pearson";
271  }
272  T operator()(const Point <T> &p1, const Point <T> &p2) const {
273  return (mltk::pow(p1 - p2, 2)/(p1 + p2)).sum();
274  }
275  };
276 
277  template<typename T = double>
279  public:
281  this->m_family = "Squared L2 distance measures";
282  this->m_name = "ProbabilisticSymmetric";
283  }
284  T operator()(const Point <T> &p1, const Point <T> &p2) const {
285  return 2 * (mltk::pow(p1 - p2, 2)/(p1 + p2)).sum();
286  }
287  };
288 
289  template<typename T = double>
290  class Divergence: public DistanceMetric<T> {
291  public:
292  Divergence(){
293  this->m_family = "Squared L2 distance measures";
294  this->m_name = "Divergence";
295  }
296  T operator()(const Point <T> &p1, const Point <T> &p2) const {
297  return 2 * (mltk::pow(p1 - p2, 2)/mltk::pow(p1 + p2, 2)).sum();
298  }
299  };
300 
301  template<typename T = double>
303  public:
305  this->m_family = "Squared L2 distance measures";
306  this->m_name = "AdditiveSymmetric";
307  }
308  T operator()(const Point <T> &p1, const Point <T> &p2) const {
309  return 2 * ((mltk::pow(p1 - p2, 2) * (p1 + p2))/(p1 * p2)).sum();
310  }
311  };
312 
313  template<typename T = double>
314  class Average: public DistanceMetric<T> {
315  public:
316  Average(){
317  this->m_family = "Squared L2 distance measures";
318  this->m_name = "Average";
319  }
320  T operator()(const Point <T> &p1, const Point <T> &p2) const {
321  return std::sqrt((1/p1.size())*(mltk::pow(p1 - p2, 2)).sum());
322  }
323  };
324 
325 // template<typename T = double>
326 // class MeanCensoredEuclidean: public DistanceMetric<T> {
327 // public:
328 // T operator()(const Point <T> &p1, const Point <T> &p2) const {
329 // return mltk::pow(p1-p2,2)/;
330 // }
331 // };
332 
333  template<typename T = double>
335  public:
337  this->m_family = "Squared L2 distance measures";
338  this->m_name = "SquaredChiSquared";
339  }
340  T operator()(const Point <T> &p1, const Point <T> &p2) const {
341  return (mltk::pow(p1 - p2, 2)/mltk::abs(p1 + p2)).sum();
342  }
343  };
344 
345  // Shannon entropy distance measures
346 
347  template<typename T = double>
348  class KullbackLeibler: public DistanceMetric<T> {
349  public:
350  KullbackLeibler(){
351  this->m_family = "Shannon entropy distance measures";
352  this->m_name = "KullbackLeibler";
353  }
354  T operator()(const Point <T> &p1, const Point <T> &p2) const {
355  return (p1 * mltk::log(p1/p2)).sum();
356  }
357  };
358 
359  template<typename T = double>
360  class Jeffreys: public DistanceMetric<T> {
361  public:
362  Jeffreys(){
363  this->m_family = "Shannon entropy distance measures";
364  this->m_name = "Jeffreys";
365  }
366  T operator()(const Point <T> &p1, const Point <T> &p2) const {
367  return ((p1 - p2) * mltk::log(p1/p2)).sum();
368  }
369  };
370 
371  template<typename T = double>
372  class KDivergence: public DistanceMetric<T> {
373  public:
374  KDivergence(){
375  this->m_family = "Shannon entropy distance measures";
376  this->m_name = "KDivergence";
377  }
378  T operator()(const Point <T> &p1, const Point <T> &p2) const {
379  return (p1 * mltk::log((2 * p1)/(p1 + p2))).sum();
380  }
381  };
382 
383  template<typename T = double>
384  class Topsoe: public DistanceMetric<T> {
385  public:
386  Topsoe(){
387  this->m_family = "Shannon entropy distance measures";
388  this->m_name = "Topsoe";
389  }
390  T operator()(const Point <T> &p1, const Point <T> &p2) const {
391  return (p1 * mltk::log((2 * p1)/(p1 + p2))).sum() + (p2 * mltk::log((2 * p2)/(p1 + p2))).sum();
392  }
393  };
394 
395  template<typename T = double>
396  class JensenShannon: public DistanceMetric<T> {
397  public:
398  JensenShannon(){
399  this->m_family = "Shannon entropy distance measures";
400  this->m_name = "JensenShannon";
401  }
402  T operator()(const Point <T> &p1, const Point <T> &p2) const {
403  return (1/2) * (p1 * mltk::log((2 * p1)/(p1 + p2))).sum() + (p2 * mltk::log((2 * p2)/(p1 + p2))).sum();
404  }
405  };
406 
407  template<typename T = double>
408  class JensenDifference: public DistanceMetric<T> {
409  public:
411  this->m_family = "Shannon entropy distance measures";
412  this->m_name = "JensenDifference";
413  }
414  T operator()(const Point <T> &p1, const Point <T> &p2) const {
415  return (1/2) * ((p1 * mltk::log(p1) + p2 * mltk::log(p2))/2 - ((p1 + p2)/2) * mltk::log((p1 + p2)/2)).sum();
416  }
417  };
418 
419  // Vicissitude distance measures
420 
421 // template<typename T = double>
422 // class VicisWaveHedges: public DistanceMetric<T> {
423 // public:
424 // T operator()(const Point <T> &p1, const Point <T> &p2) const {
425 // return (mltk::abs(p1 - p2)/).sum();
426 // }
427 // };
428 
429  template<typename T = double>
430  class MaxSymmetric: public DistanceMetric<T> {
431  public:
432  T operator()(const Point <T> &p1, const Point <T> &p2) const {
433  return std::max((mltk::pow(p1 - p2, 2)/p1).sum(), (mltk::pow(p1 - p2, 2)/p2).sum());
434  }
435  };
436 
437  template<typename T = double>
438  class MinSymmetric: public DistanceMetric<T> {
439  public:
440  T operator()(const Point <T> &p1, const Point <T> &p2) const {
441  return std::max((mltk::pow(p1 - p2, 2)/p1).sum(), (mltk::pow(p1 - p2, 2)/p2).sum());
442  }
443  };
444 
445  // Other distance measures
446 
447  template<typename T = double>
448  class AverageL1Linf: public DistanceMetric<T> {
449  public:
450  AverageL1Linf(){
451  this->m_family = "Other distance measures";
452  this->m_name = "AverageL1Linf";
453  }
454  T operator()(const Point <T> &p1, const Point <T> &p2) const {
455  return (mltk::abs(p1-p2).sum() + mltk::max(mltk::abs(p1-p2)))/2;
456  }
457  };
458 
459  template<typename T = double>
460  class KumarJohnson: public DistanceMetric<T> {
461  public:
462  KumarJohnson(){
463  this->m_family = "Other distance measures";
464  this->m_name = "KumarJohnson";
465  }
466  T operator()(const Point <T> &p1, const Point <T> &p2) const {
467  return (mltk::pow(mltk::pow(p1, 2) + mltk::pow(p2, 2), 2)/(2 * mltk::pow(p1 * p2, 3/2))).sum();
468  }
469  };
470 
471  template<typename T = double>
472  class Taneja: public DistanceMetric<T> {
473  public:
474  Taneja(){
475  this->m_family = "Other distance measures";
476  this->m_name = "Taneja";
477  }
478  T operator()(const Point <T> &p1, const Point <T> &p2) const {
479  return (((p1 + p2)/2) * mltk::log((p1 + p2)/(2*mltk::pow(p1 * p2, 0.5)))).sum();
480  }
481  };
482 
483  template<typename T = double>
484  class Hassanat: public DistanceMetric<T> {
485  public:
486  Hassanat(){
487  this->m_family = "Other distance measures";
488  this->m_name = "Hassanat";
489  }
490  T operator()(const Point <T> &p1, const Point <T> &p2) const {
491  T sum = 0;
492  for(size_t i = 0; i < p1.size(); i++){
493  auto _min = std::min(p1[i], p2[i]);
494  if(_min >= 0){
495  sum += 1 - (1+_min)/(1+std::max(p1[i], p2[i]));
496  }else{
497  auto _max = std::max(p1[i], p2[i]);
498  sum += 1 - (1+_min + std::abs(_min))/(1+_max + std::abs(_max));
499  }
500  }
501  return sum;
502  }
503  };
504  }
std::size_t size() const
Returns the dimension of the point.
Definition: Point.hpp:133
Definition: DistanceMetric.hpp:302
Definition: DistanceMetric.hpp:448
Definition: DistanceMetric.hpp:314
Definition: DistanceMetric.hpp:99
Definition: DistanceMetric.hpp:168
Definition: DistanceMetric.hpp:83
Definition: DistanceMetric.hpp:57
Definition: DistanceMetric.hpp:154
Definition: DistanceMetric.hpp:230
Definition: DistanceMetric.hpp:130
Definition: DistanceMetric.hpp:142
Base functor class for the implementation of new metrics metrics.
Definition: DistanceMetric.hpp:11
Definition: DistanceMetric.hpp:290
Functor for the computation of the euclidean metrics between two points.
Definition: DistanceMetric.hpp:29
Definition: DistanceMetric.hpp:484
Definition: DistanceMetric.hpp:204
Definition: DistanceMetric.hpp:117
Definition: DistanceMetric.hpp:360
Definition: DistanceMetric.hpp:408
Definition: DistanceMetric.hpp:396
Definition: DistanceMetric.hpp:372
Definition: DistanceMetric.hpp:348
Definition: DistanceMetric.hpp:460
Definition: DistanceMetric.hpp:71
Definition: DistanceMetric.hpp:45
Definition: DistanceMetric.hpp:192
Definition: DistanceMetric.hpp:430
Definition: DistanceMetric.hpp:438
Definition: DistanceMetric.hpp:242
Definition: DistanceMetric.hpp:107
Definition: DistanceMetric.hpp:254
Definition: DistanceMetric.hpp:278
Definition: DistanceMetric.hpp:91
Definition: DistanceMetric.hpp:334
Definition: DistanceMetric.hpp:180
Definition: DistanceMetric.hpp:218
Definition: DistanceMetric.hpp:266
Definition: DistanceMetric.hpp:472
Definition: DistanceMetric.hpp:384
T min(const Point< T, R > &p)
Returns the min value of the point.
Definition: Point.hpp:557
T max(const Point< T, R > &p)
Returns the max value of the point.
Definition: Point.hpp:544