Alexandria  2.27.0
SDC-CH common library for the Euclid project
Distances.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Euclid Science Ground Segment
3  *
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)
7  * any later version.
8  *
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
12  * details.
13  *
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
17  */
18 
19 #ifndef MATHUTILS_DISTANCES_H
20 #define MATHUTILS_DISTANCES_H
21 
22 #include <cmath>
23 
24 namespace Euclid {
25 namespace MathUtils {
26 
31 struct Chi2Distance {
32 
43  template <typename Scale, typename Iterator>
44  static auto distance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin)
45  -> decltype(ref_begin->getFlux()) {
46  decltype(ref_begin->getFlux()) acc = 0.;
47 
48  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
49  auto ref_val = scale * ri->getFlux();
50  auto ref_err = scale * ri->getError();
51  auto tar_val = ti->getFlux();
52  auto tar_err = ti->getError();
53  auto nom = (ref_val - tar_val) * (ref_val - tar_val);
54  auto den = ref_err * ref_err + tar_err * tar_err;
55  acc += nom / den;
56  }
57 
58  return acc;
59  }
60 
69  template <typename Iterator>
70  static auto guessScale(Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux()) {
71  decltype(ref_begin->getFlux()) nom = 0., den = 0.;
72 
73  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
74  auto err_sqr = (ti->getError() * ti->getError());
75  nom += (ri->getFlux() * ti->getFlux()) / err_sqr;
76  den += (ri->getFlux() * ri->getFlux()) / err_sqr;
77  }
78 
79  return nom / den;
80  }
81 
88  template <typename Scale, typename Iterator>
89  static auto daDistance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin)
90  -> decltype(ref_begin->getFlux()) {
91  decltype(ref_begin->getFlux()) acc = 0.;
92 
93  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
94  auto ref_val = ri->getFlux();
95  auto ref_err = ri->getError();
96  auto tar_val = ti->getFlux();
97  auto tar_err = ti->getError();
98 
99  auto ref_err_sq = ref_err * ref_err;
100  auto tar_err_sq = tar_err * tar_err;
101 
102  auto nom = 2 * (scale * ref_val - tar_val) * (ref_err_sq * scale * tar_val + ref_val * tar_err_sq);
103  auto den = ref_err_sq * scale * scale + tar_err_sq;
104  acc += nom / (den * den);
105  }
106 
107  return acc;
108  }
109 };
110 
116  template <typename Scale, typename Iterator>
117  static auto distance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin)
118  -> decltype(ref_begin->getFlux()) {
119  decltype(ref_begin->getFlux()) acc = 0.;
120 
121  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
122  auto d = (scale * ri->getFlux()) - (ti->getFlux());
123  acc += d * d;
124  }
125 
126  return std::sqrt(acc);
127  }
128 
137  template <typename Iterator>
138  static auto guessScale(Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux()) {
139  decltype(ref_begin->getFlux()) nom = 0., den = 0.;
140 
141  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
142  nom += (ti->getFlux() * ti->getFlux());
143  den += (ri->getFlux() * ri->getFlux());
144  }
145 
146  return std::sqrt(nom) / std::sqrt(den);
147  }
148 
155  template <typename Scale, typename Iterator>
156  static auto daDistance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin)
157  -> decltype(ref_begin->getFlux()) {
158  decltype(ref_begin->getFlux()) den = 0., nom_sum_sqr = 0., nom_sum_prod = 0.;
159 
160  for (auto ri = ref_begin, ti = target_begin; ri != ref_end; ++ri, ++ti) {
161  nom_sum_sqr += ri->getFlux() * ri->getFlux();
162  nom_sum_prod += ri->getFlux() * ti->getFlux();
163  den += (ti->getFlux() - scale * ri->getFlux()) * (ti->getFlux() - scale * ri->getFlux());
164  }
165 
166  return (scale * nom_sum_sqr - nom_sum_prod) / std::sqrt(den);
167  }
168 };
169 } // namespace MathUtils
170 } // namespace Euclid
171 
172 #endif // MATHUTILS_DISTANCES_H
T sqrt(T... args)
static auto daDistance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:89
static auto guessScale(Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:70
static auto distance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:44
static auto guessScale(Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:138
static auto daDistance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:156
static auto distance(Scale scale, Iterator ref_begin, Iterator ref_end, Iterator target_begin) -> decltype(ref_begin->getFlux())
Definition: Distances.h:117