23 const double double_max = std::numeric_limits<double>::max();
24 const double double_min = std::numeric_limits<double>::min();
25 const double ln10 = std::log(10.0);
27 template <
class T> T* copyMetric(
const T& metric)
30 result->setNorm(metric.norm());
34 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
35 const std::vector<double>& weight_factors)
37 const size_t sim_size = sim_data.size();
38 if (sim_size != exp_data.size() || sim_size != weight_factors.size())
39 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
41 for (
size_t i = 0; i < sim_size; ++i)
42 if (sim_data[i] < 0.0)
43 throw std::runtime_error(
44 "Error in ObjectiveMetric: simulation data array contains negative values");
47 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
48 const std::vector<double>& uncertainties,
49 const std::vector<double>& weight_factors)
51 if (sim_data.size() != uncertainties.size())
52 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
54 checkIntegrity(sim_data, exp_data, weight_factors);
63 throw std::runtime_error(
"Error in ObjectiveMetric::compute: the metric is weighted, but "
64 "the simulation-data pair does not contain uncertainties");
85 return copyMetric(*
this);
89 std::vector<double> uncertainties,
90 std::vector<double> weight_factors)
const
92 checkIntegrity(sim_data, exp_data, uncertainties, weight_factors);
95 auto norm_fun =
norm();
96 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
97 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0 && uncertainties[i] > 0.0)
98 result += norm_fun((exp_data[i] - sim_data[i]) / uncertainties[i]) * weight_factors[i];
100 return std::isfinite(result) ? result : double_max;
104 std::vector<double> weight_factors)
const
106 checkIntegrity(sim_data, exp_data, weight_factors);
108 auto norm_fun =
norm();
110 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
111 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0)
112 result += norm_fun(exp_data[i] - sim_data[i]) * weight_factors[i];
114 return std::isfinite(result) ? result : double_max;
123 return copyMetric(*
this);
127 std::vector<double> exp_data,
128 std::vector<double> weight_factors)
const
130 checkIntegrity(sim_data, exp_data, weight_factors);
133 auto norm_fun =
norm();
134 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
135 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
137 const double variance = std::max(1.0, sim_data[i]);
138 const double value = (sim_data[i] - exp_data[i]) / std::sqrt(variance);
139 result += norm_fun(value) * weight_factors[i];
142 return std::isfinite(result) ? result : double_max;
151 return copyMetric(*
this);
155 std::vector<double> uncertainties,
156 std::vector<double> weight_factors)
const
158 checkIntegrity(sim_data, exp_data, uncertainties, weight_factors);
161 auto norm_fun =
norm();
162 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
163 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0 || uncertainties[i] <= 0.0)
165 const double sim_val = std::max(double_min, sim_data[i]);
166 const double exp_val = std::max(double_min, exp_data[i]);
167 double value = std::log10(sim_val) - std::log10(exp_val);
168 value *= exp_val * ln10 / uncertainties[i];
169 result += norm_fun(value) * weight_factors[i];
172 return std::isfinite(result) ? result : double_max;
176 std::vector<double> weight_factors)
const
178 checkIntegrity(sim_data, exp_data, weight_factors);
181 auto norm_fun =
norm();
182 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
183 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
185 const double sim_val = std::max(double_min, sim_data[i]);
186 const double exp_val = std::max(double_min, exp_data[i]);
187 result += norm_fun(std::log10(sim_val) - std::log10(exp_val)) * weight_factors[i];
190 return std::isfinite(result) ? result : double_max;
199 return copyMetric(*
this);
203 std::vector<double> exp_data,
204 std::vector<double> weight_factors)
const
206 checkIntegrity(sim_data, exp_data, weight_factors);
209 auto norm_fun =
norm();
210 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
211 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
213 const double sim_val = std::max(double_min, sim_data[i]);
214 const double exp_val = std::max(double_min, exp_data[i]);
215 result += norm_fun((exp_val - sim_val) / (exp_val + sim_val)) * weight_factors[i];
218 return std::isfinite(result) ? result : double_max;
227 return copyMetric(*
this);
239 return computeFromArrays(sim_data->getRawDataVector(), exp_data->getRawDataVector(),
Defines ObjectiveMetric utilities and corresponding namespace.
Defines ObjectiveMetric classes.
Defines and implements templated class OutputData.
Defines class SimDataPair.
Implementation of the standard metric derived from maximum likelihood with Gaussian uncertainties.
Chi2Metric * clone() const override
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.
LogMetric * clone() const override
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.
std::function< double(double)> m_norm
auto norm() const
Returns a copy of the normalization function used.
ObjectiveMetric(std::function< double(double)> norm)
void setNorm(std::function< double(double)> norm)
Implementation of metric with standard deviation , where is the simulated intensity.
PoissonLikeMetric * clone() const override
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.
RQ4Metric * clone() const override
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.
RelativeDifferenceMetric()
RelativeDifferenceMetric * clone() const override
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.
bool containsUncertainties() const
SimulationResult simulationResult() const
Returns the result of last computed simulation.
std::unique_ptr< OutputData< double > > data(Axes::Units units=Axes::Units::DEFAULT) const
Utility functions related to class ObjectiveMetric.
const std::function< double(double)> l2Norm()
Returns L2 normalization function.