BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ObjectiveMetric.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Core/Fitting/ObjectiveMetric.h
6 //! @brief Defines ObjectiveMetric classes.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifdef SWIG
16 #error no need to expose this header to Swig
17 #endif
18 
19 #ifndef USER_API
20 #ifndef BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
21 #define BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
22 
23 #include "Base/Types/ICloneable.h"
24 #include <functional>
25 #include <memory>
26 #include <vector>
27 
28 class SimDataPair;
29 
30 //! Base class for metric implementations
31 class ObjectiveMetric : public ICloneable {
32 public:
33  ObjectiveMetric(std::function<double(double)> norm);
34 
35  ObjectiveMetric* clone() const override = 0;
36 
37  //! Computes metric value from SimDataPair object. Calls computeFromArrays internally.
38  //! @param data_pair: SimDataPair object. Can optionally contain data uncertainties
39  //! @param use_weights: boolean, defines if data uncertainties should be taken into account
40  virtual double compute(const SimDataPair& data_pair, bool use_weights) const;
41 
42  //! Computes metric value from data arrays. Negative values in exp_data
43  //! are ignored as well as non-positive weight_factors and uncertainties.
44  //! All arrays involved in the computation must be of the same size.
45  //! @param sim_data: array with simulated intensities.
46  //! @param exp_data: array with intensity values obtained from an experiment.
47  //! @param uncertainties: array with experimental data uncertainties.
48  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
49  //! is chosen.
50  virtual double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
51  std::vector<double> uncertainties,
52  std::vector<double> weight_factors) const = 0;
53 
54  //! Computes metric value from data arrays. Negative values in exp_data
55  //! are ignored as well as non-positive weight_factors.
56  //! All arrays involved in the computation must be of the same size.
57  //! @param sim_data: array with simulated intensities.
58  //! @param exp_data: array with intensity values obtained from an experiment.
59  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
60  //! is chosen.
61  virtual double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
62  std::vector<double> weight_factors) const = 0;
63 
64  void setNorm(std::function<double(double)> norm);
65 
66  //! Returns a copy of the normalization function used.
67  auto norm() const { return m_norm; }
68 
69 private:
70  std::function<double(double)> m_norm; //! normalization function.
71 };
72 
73 //! Implementation of the standard \f$ \chi^2 \f$ metric
74 //! derived from maximum likelihood with Gaussian uncertainties.
75 //! With default L2 norm corresponds to the formula
76 //! \f[\chi^2 = \sum \frac{(I - D)^2}{\delta_D^2}\f]
77 class Chi2Metric : public ObjectiveMetric {
78 public:
79  Chi2Metric();
80  Chi2Metric* clone() const override;
81 
82  //! Computes metric value from data arrays. Negative values in exp_data
83  //! are ignored as well as non-positive weight_factors and uncertainties.
84  //! All arrays involved in the computation must be of the same size.
85  //! @param sim_data: array with simulated intensities.
86  //! @param exp_data: array with intensity values obtained from an experiment.
87  //! @param uncertainties: array with experimental data uncertainties.
88  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
89  //! is chosen.
90  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
91  std::vector<double> uncertainties,
92  std::vector<double> weight_factors) const override;
93 
94  //! Computes metric value from data arrays. Negative values in exp_data
95  //! are ignored as well as non-positive weight_factors.
96  //! All arrays involved in the computation must be of the same size.
97  //! @param sim_data: array with simulated intensities.
98  //! @param exp_data: array with intensity values obtained from an experiment.
99  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
100  //! is chosen.
101  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
102  std::vector<double> weight_factors) const override;
103 };
104 
105 //! Implementation of \f$ \chi^2 \f$ metric
106 //! with standard deviation\f$\sigma = max(\sqrt{I}, 1)\f$,
107 //! where \f$I\f$ is the simulated intensity.
108 //! With default L2 norm corresponds to the formula
109 //! \f[\chi^2 = \sum \frac{(I - D)^2}{max(I, 1)}\f]
110 //! for unweighted experimental data. Falls to standard
111 //! Chi2Metric when data uncertainties are taken into account.
113 public:
115  PoissonLikeMetric* clone() const override;
116 
118 
119  //! Computes metric value from data arrays. Negative values in exp_data
120  //! are ignored as well as non-positive weight_factors.
121  //! All arrays involved in the computation must be of the same size.
122  //! @param sim_data: array with simulated intensities.
123  //! @param exp_data: array with intensity values obtained from an experiment.
124  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
125  //! is chosen.
126  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
127  std::vector<double> weight_factors) const override;
128 };
129 
130 //! Implementation of the standard \f$ \chi^2 \f$ metric with intensity \f$I\f$
131 //! and experimental data \f$D\f$
132 //! being replaced by \f$ \log_{10} I \f$ and \f$\log_{10} D\f$ accordingly.
133 //! With default L2 norm corresponds to the formula
134 //! \f[\chi^2 = \sum \frac{(\log_{10} I - log_{10} D)^2 D^2 \ln^2{10}}{\delta_D^2}\f]
135 class LogMetric : public ObjectiveMetric {
136 public:
137  LogMetric();
138  LogMetric* clone() const override;
139 
140  //! Computes metric value from data arrays. Negative values in exp_data
141  //! are ignored as well as non-positive weight_factors and uncertainties.
142  //! All arrays involved in the computation must be of the same size.
143  //! @param sim_data: array with simulated intensities.
144  //! @param exp_data: array with intensity values obtained from an experiment.
145  //! @param uncertainties: array with experimental data uncertainties.
146  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
147  //! is chosen.
148  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
149  std::vector<double> uncertainties,
150  std::vector<double> weight_factors) const override;
151 
152  //! Computes metric value from data arrays. Negative values in exp_data
153  //! are ignored as well as non-positive weight_factors.
154  //! All arrays involved in the computation must be of the same size.
155  //! @param sim_data: array with simulated intensities.
156  //! @param exp_data: array with intensity values obtained from an experiment.
157  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
158  //! is chosen.
159  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
160  std::vector<double> weight_factors) const override;
161 };
162 
163 //! Implementation of relative difference metric.
164 //! With default L2 norm and weighting off corresponds to the formula
165 //! \f[Result = \sum \frac{(I - D)^2}{(I + D)^2}\f]
166 //! where \f$I\f$ is the simulated intensity, \f$D\f$ - experimental data.
167 //! If weighting is on, falls back to the standard \f$\chi^2\f$ metric.
169 public:
171  RelativeDifferenceMetric* clone() const override;
172 
174 
175  //! Computes metric value from data arrays. Negative values in exp_data
176  //! are ignored as well as non-positive weight_factors.
177  //! All arrays involved in the computation must be of the same size.
178  //! @param sim_data: array with simulated intensities.
179  //! @param exp_data: array with intensity values obtained from an experiment.
180  //! @param weight_factors: user-defined weighting factors. Used linearly, no matter which norm
181  //! is chosen.
182  double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
183  std::vector<double> weight_factors) const override;
184 };
185 
186 //! Implementation of relative difference metric.
187 //! With default L2 norm and weighting off corresponds to the formula
188 //! \f[Result = \sum (I \cdot Q^4 - D \cdot Q^4)^2\f]
189 //! where \f$Q\f$ is the scattering vector magnitude. If weighting is on,
190 //! coincides with the metric provided by Chi2Metric class.
191 class RQ4Metric : public Chi2Metric {
192 public:
193  RQ4Metric();
194  RQ4Metric* clone() const override;
195  //! Computes metric value from SimDataPair object. Calls computeFromArrays internally.
196  //! @param data_pair: SimDataPair object. Can optionally contain data uncertainties
197  //! @param use_weights: boolean, defines if data uncertainties should be taken into account
198  double compute(const SimDataPair& data_pair, bool use_weights) const override;
199 };
200 
201 #endif // BORNAGAIN_CORE_FITTING_OBJECTIVEMETRIC_H
202 #endif // USER_API
Defines and implements the standard mix-in ICloneable.
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.
Interface for polymorphic classes that should not be copied, except by explicit cloning.
Definition: ICloneable.h:25
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 > weight_factors) const =0
Computes metric value from data arrays.
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
ObjectiveMetric * clone() const override=0
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 * clone() const override
Holds pair of simulation/experimental data to fit.
Definition: SimDataPair.h:30