24 const double double_max = std::numeric_limits<double>::max();
25 const double double_min = std::numeric_limits<double>::min();
26 const double ln10 = std::log(10.0);
28 template <
class T> T* copyMetric(
const T& metric)
31 result->setNorm(metric.norm());
35 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
36 const std::vector<double>& weight_factors)
38 const size_t sim_size = sim_data.size();
39 if (sim_size != exp_data.size() || sim_size != weight_factors.size())
40 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
42 for (
size_t i = 0; i < sim_size; ++i)
43 if (sim_data[i] < 0.0)
44 throw std::runtime_error(
45 "Error in ObjectiveMetric: simulation data array contains negative values");
48 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
49 const std::vector<double>& uncertainties,
50 const std::vector<double>& weight_factors)
52 if (sim_data.size() != uncertainties.size())
53 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
55 checkIntegrity(sim_data, exp_data, weight_factors);
59 ObjectiveMetric::ObjectiveMetric(std::function<
double(
double)> norm) : m_norm(std::move(norm)) {}
63 if (use_weights && !data_pair.containsUncertainties())
64 throw std::runtime_error(
"Error in ObjectiveMetric::compute: the metric is weighted, but "
65 "the simulation-data pair does not contain uncertainties");
75 void ObjectiveMetric::setNorm(std::function<
double(
double)> norm)
77 m_norm = std::move(
norm);
86 return copyMetric(*
this);
90 std::vector<double> uncertainties,
91 std::vector<double> weight_factors)
const
93 checkIntegrity(sim_data, exp_data, uncertainties, weight_factors);
96 auto norm_fun =
norm();
97 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
98 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0 && uncertainties[i] > 0.0)
99 result += norm_fun((exp_data[i] - sim_data[i]) / uncertainties[i]) * weight_factors[i];
101 return std::isfinite(result) ? result : double_max;
105 std::vector<double> weight_factors)
const
107 checkIntegrity(sim_data, exp_data, weight_factors);
109 auto norm_fun =
norm();
111 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
112 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0)
113 result += norm_fun(exp_data[i] - sim_data[i]) * weight_factors[i];
115 return std::isfinite(result) ? result : double_max;
120 PoissonLikeMetric::PoissonLikeMetric() :
Chi2Metric() {}
124 return copyMetric(*
this);
128 std::vector<double> exp_data,
129 std::vector<double> weight_factors)
const
131 checkIntegrity(sim_data, exp_data, weight_factors);
134 auto norm_fun =
norm();
135 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
136 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
138 const double variance = std::max(1.0, sim_data[i]);
139 const double value = (sim_data[i] - exp_data[i]) / std::sqrt(variance);
140 result += norm_fun(value) * weight_factors[i];
143 return std::isfinite(result) ? result : double_max;
148 LogMetric::LogMetric() :
ObjectiveMetric(ObjectiveMetricUtils::l2Norm()) {}
152 return copyMetric(*
this);
156 std::vector<double> uncertainties,
157 std::vector<double> weight_factors)
const
159 checkIntegrity(sim_data, exp_data, uncertainties, weight_factors);
162 auto norm_fun =
norm();
163 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
164 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0 || uncertainties[i] <= 0.0)
166 const double sim_val = std::max(double_min, sim_data[i]);
167 const double exp_val = std::max(double_min, exp_data[i]);
168 double value = std::log10(sim_val) - std::log10(exp_val);
169 value *= exp_val * ln10 / uncertainties[i];
170 result += norm_fun(value) * weight_factors[i];
173 return std::isfinite(result) ? result : double_max;
177 std::vector<double> weight_factors)
const
179 checkIntegrity(sim_data, exp_data, weight_factors);
182 auto norm_fun =
norm();
183 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
184 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
186 const double sim_val = std::max(double_min, sim_data[i]);
187 const double exp_val = std::max(double_min, exp_data[i]);
188 result += norm_fun(std::log10(sim_val) - std::log10(exp_val)) * weight_factors[i];
191 return std::isfinite(result) ? result : double_max;
196 RelativeDifferenceMetric::RelativeDifferenceMetric() :
Chi2Metric() {}
200 return copyMetric(*
this);
204 std::vector<double> exp_data,
205 std::vector<double> weight_factors)
const
207 checkIntegrity(sim_data, exp_data, weight_factors);
210 auto norm_fun =
norm();
211 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
212 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
214 const double sim_val = std::max(double_min, sim_data[i]);
215 const double exp_val = std::max(double_min, exp_data[i]);
216 result += norm_fun((exp_val - sim_val) / (exp_val + sim_val)) * weight_factors[i];
219 return std::isfinite(result) ? result : double_max;
228 return copyMetric(*
this);
240 return computeFromArrays(sim_data->getRawDataVector(), exp_data->getRawDataVector(),
Defines ObjectiveMetric utilities and corresponding namespace.
const std::function< double(double)> l2Norm()
Returns L2 normalization function.
Defines ObjectiveMetric classes.
Defines and implements template class OutputData.
Defines class SimDataPair.
Implementation of the standard metric derived from maximum likelihood with Gaussian uncertainties.
double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > uncertainties, std::vector< double > weight_factors) const override
Computes metric value from data arrays.
Implementation of the standard metric with intensity and experimental data being replaced by and ...
double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > uncertainties, std::vector< double > weight_factors) const override
Computes metric value from data arrays.
Base class for metric implementations.
virtual double compute(const SimDataPair &data_pair, bool use_weights) const
Computes metric value from SimDataPair object.
virtual double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > uncertainties, std::vector< double > weight_factors) const =0
Computes metric value from data arrays.
auto norm() const
Returns a copy of the normalization function used.
Implementation of metric with standard deviation , where is the simulated intensity.
double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > uncertainties, std::vector< double > weight_factors) const override
Computes metric value from data arrays.
Implementation of relative difference metric.
double compute(const SimDataPair &data_pair, bool use_weights) const override
Computes metric value from SimDataPair object.
Implementation of relative difference metric.
double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > uncertainties, std::vector< double > weight_factors) const override
Computes metric value from data arrays.
Holds pair of simulation/experimental data to fit.
std::vector< double > experimental_array() const
Returns the flattened experimental data cut to the ROI area.
std::vector< double > user_weights_array() const
Returns a flat array of user weights cut to the ROI area.
std::vector< double > uncertainties_array() const
Returns the flattened experimental uncertainties cut to the ROI area.
std::vector< double > simulation_array() const
Returns the flattened simulated intensities cut to the ROI area.
SimulationResult experimentalData() const
Returns the experimental data cut to the ROI area.
SimulationResult simulationResult() const
Returns the result of last computed simulation.