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);
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");
64 throw std::runtime_error(
"Error in ObjectiveMetric::compute: the metric is weighted, but "
65 "the simulation-data pair does not contain uncertainties");
90 std::vector<double> uncertainties,
91 std::vector<double> weight_factors)
const
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
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;
128 std::vector<double> exp_data,
129 std::vector<double> weight_factors)
const
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;
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
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;
204 std::vector<double> exp_data,
205 std::vector<double> weight_factors)
const
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;
240 return computeFromArrays(sim_data->getRawDataVector(), exp_data->getRawDataVector(),
Defines ObjectiveMetric utilities and corresponding namespace.
Defines ObjectiveMetric classes.
Defines and implements template 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
const std::function< double(double)> l2Norm()
Returns L2 normalization function.
void checkIntegrity(const std::vector< double > &sim_data, const std::vector< double > &exp_data, const std::vector< double > &uncertainties, const std::vector< double > &weight_factors)
T * copyMetric(const T &metric)