25 const double double_max = std::numeric_limits<double>::max();
26 const double double_min = std::numeric_limits<double>::min();
27 const double ln10 = std::log(10.0);
30 T* copyMetric(
const T& metric)
33 result->setNorm(metric.norm());
37 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
38 const std::vector<double>& weight_factors)
40 const size_t sim_size = sim_data.size();
41 if (sim_size != exp_data.size() || sim_size != weight_factors.size())
42 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
44 for (
size_t i = 0; i < sim_size; ++i)
45 if (sim_data[i] < 0.0)
46 throw std::runtime_error(
47 "Error in ObjectiveMetric: simulation data array contains negative values");
50 void checkIntegrity(
const std::vector<double>& sim_data,
const std::vector<double>& exp_data,
51 const std::vector<double>& exp_stdv,
const std::vector<double>& weight_factors)
53 if (sim_data.size() != exp_stdv.size())
54 throw std::runtime_error(
"Error in ObjectiveMetric: input arrays have different sizes");
56 checkIntegrity(sim_data, exp_data, weight_factors);
62 : m_norm(std::move(norm))
69 throw std::runtime_error(
"Error in ObjectiveMetric::compute: the metric is weighted, but "
70 "the simulation-data pair does not contain uncertainties");
93 return copyMetric(*
this);
97 std::vector<double> exp_stdv,
98 std::vector<double> weight_factors)
const
100 checkIntegrity(sim_data, exp_data, exp_stdv, weight_factors);
103 auto norm_fun =
norm();
104 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
105 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0 && exp_stdv[i] > 0.0)
106 result += norm_fun((exp_data[i] - sim_data[i]) / exp_stdv[i]) * weight_factors[i];
108 return std::isfinite(result) ? result : double_max;
112 std::vector<double> weight_factors)
const
114 checkIntegrity(sim_data, exp_data, weight_factors);
116 auto norm_fun =
norm();
118 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i)
119 if (exp_data[i] >= 0.0 && weight_factors[i] > 0.0)
120 result += norm_fun(exp_data[i] - sim_data[i]) * weight_factors[i];
122 return std::isfinite(result) ? result : double_max;
134 return copyMetric(*
this);
138 std::vector<double> exp_data,
139 std::vector<double> weight_factors)
const
141 checkIntegrity(sim_data, exp_data, weight_factors);
144 auto norm_fun =
norm();
145 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
146 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
148 const double variance = std::max(1.0, sim_data[i]);
149 const double value = (sim_data[i] - exp_data[i]) / std::sqrt(variance);
150 result += norm_fun(value) * weight_factors[i];
153 return std::isfinite(result) ? result : double_max;
165 return copyMetric(*
this);
169 std::vector<double> exp_stdv,
170 std::vector<double> weight_factors)
const
172 checkIntegrity(sim_data, exp_data, exp_stdv, weight_factors);
175 auto norm_fun =
norm();
176 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
177 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0 || exp_stdv[i] <= 0.0)
179 const double sim_val = std::max(double_min, sim_data[i]);
180 const double exp_val = std::max(double_min, exp_data[i]);
181 double value = std::log10(sim_val) - std::log10(exp_val);
182 value *= exp_val * ln10 / exp_stdv[i];
183 result += norm_fun(value) * weight_factors[i];
186 return std::isfinite(result) ? result : double_max;
190 std::vector<double> weight_factors)
const
192 checkIntegrity(sim_data, exp_data, weight_factors);
195 auto norm_fun =
norm();
196 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
197 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
199 const double sim_val = std::max(double_min, sim_data[i]);
200 const double exp_val = std::max(double_min, exp_data[i]);
201 result += norm_fun(std::log10(sim_val) - std::log10(exp_val)) * weight_factors[i];
204 return std::isfinite(result) ? result : double_max;
216 return copyMetric(*
this);
220 std::vector<double> exp_data,
221 std::vector<double> weight_factors)
const
223 checkIntegrity(sim_data, exp_data, weight_factors);
226 auto norm_fun =
norm();
227 for (
size_t i = 0, sim_size = sim_data.size(); i < sim_size; ++i) {
228 if (weight_factors[i] <= 0.0 || exp_data[i] < 0.0)
230 const double sim_val = std::max(double_min, sim_data[i]);
231 const double exp_val = std::max(double_min, exp_data[i]);
232 result += norm_fun((exp_val - sim_val) / (exp_val + sim_val)) * weight_factors[i];
235 return std::isfinite(result) ? result : double_max;
247 return copyMetric(*
this);
Defines and implements templated class Datafield.
Defines ObjectiveMetric utilities and corresponding namespace.
Defines ObjectiveMetric classes.
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 > exp_stdv, std::vector< double > weight_factors) const override
Computes metric value from data arrays. Negative values in exp_data are ignored as well as non-positi...
Chi2Metric * clone() const override
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 > exp_stdv, std::vector< double > weight_factors) const override
Computes metric value from data arrays. Negative values in exp_data are ignored as well as non-positi...
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. Calls computeFromArrays internally.
std::function< double(double)> m_norm
auto norm() const
Returns a copy of the normalization function used.
virtual double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > exp_stdv, std::vector< double > weight_factors) const =0
Computes metric value from data arrays. Negative values in exp_data are ignored as well as non-positi...
ObjectiveMetric(std::function< double(double)> norm)
void setNorm(std::function< double(double)> norm)
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 > exp_stdv, std::vector< double > weight_factors) const override
Computes metric value from data arrays. Negative values in exp_data are ignored as well as non-positi...
PoissonLikeMetric * clone() const override
Implementation of relative difference metric. With default L2 norm and weighting off corresponds to t...
double compute(const SimDataPair &data_pair, bool use_weights) const override
Computes metric value from SimDataPair object. Calls computeFromArrays internally.
RQ4Metric * 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. If no uncertainties are availab...
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::vector< double > flatVector(Coords units=Coords::UNDEFINED) const
Implementation of relative difference metric. With default L2 norm and weighting off corresponds to t...
double computeFromArrays(std::vector< double > sim_data, std::vector< double > exp_data, std::vector< double > exp_stdv, std::vector< double > weight_factors) const override
Computes metric value from data arrays. Negative values in exp_data are ignored as well as non-positi...
meanRelativeDifferenceMetric * clone() const override
meanRelativeDifferenceMetric()
Utility functions related to class ObjectiveMetric.
std::function< double(double)> l2Norm()
Returns L2 normalization function.