File: ObjectiveMetric.h

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (193 lines) | stat: -rw-r--r-- 8,514 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Sim/Fitting/ObjectiveMetric.h
//! @brief     Defines class ObjectiveMetrices.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#ifdef SWIG
#error no need to expose this header to Swig
#endif // SWIG
#ifndef BORNAGAIN_SIM_FITTING_OBJECTIVEMETRIC_H
#define BORNAGAIN_SIM_FITTING_OBJECTIVEMETRIC_H

#include "Base/Type/ICloneable.h"
#include <functional>
#include <memory>
#include <vector>

class SimDataPair;

//! Base class for metric implementations
class ObjectiveMetric : public ICloneable {
public:
    ObjectiveMetric(const std::function<double(double)>& norm);

#ifndef SWIG
    ObjectiveMetric* clone() const override = 0;
#endif // SWIG

    //! Computes metric value from SimDataPair object. Calls computeFromArrays internally.
    //! @param data_pair: SimDataPair object. Can optionally contain data uncertainties
    //! @param use_weights: boolean, defines if data uncertainties should be taken into account
    virtual double computeMetric(const SimDataPair& data_pair, bool use_weights) const;

    //! Computes metric value from data arrays. Negative values in exp_data
    //! are ignored as well as non-positive uncertainties.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    //! @param exp_stdv: array with experimental data uncertainties.
    virtual double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
                                     std::vector<double> exp_stdv) const = 0;

    //! Computes metric value from data arrays. Negative values in exp_data are ignored.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    virtual double computeFromArrays(std::vector<double> sim_data,
                                     std::vector<double> exp_data) const = 0;

    void setNorm(std::function<double(double)> norm);

    //! Returns a copy of the normalization function used.
    auto norm() const { return m_norm; }

private:
    std::function<double(double)> m_norm; //! normalization function.
};

//! Implementation of the standard \f$ \chi^2 \f$ metric
//! derived from maximum likelihood with Gaussian uncertainties.
//! With default L2 norm corresponds to the formula
//! \f[\chi^2 = \sum \frac{(I - D)^2}{\delta_D^2}\f]
class Chi2Metric : public ObjectiveMetric {
public:
    Chi2Metric();

#ifndef SWIG
    Chi2Metric* clone() const override;
#endif // SWIG

    //! Computes metric value from data arrays. Negative values in exp_data
    //! are ignored as well as non-positive uncertainties.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    //! @param exp_stdv: array with experimental data uncertainties.
    double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
                             std::vector<double> exp_stdv) const override;

    //! Computes metric value from data arrays. Negative values in exp_data are ignored.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    double computeFromArrays(std::vector<double> sim_data,
                             std::vector<double> exp_data) const override;
};

//! Implementation of \f$ \chi^2 \f$ metric
//! with standard deviation\f$\sigma = max(\sqrt{I}, 1)\f$,
//! where \f$I\f$ is the simulated intensity.
//! With default L2 norm corresponds to the formula
//! \f[\chi^2 = \sum \frac{(I - D)^2}{max(I, 1)}\f]
//! for unweighted experimental data. Falls to standard
//! Chi2Metric when data uncertainties are taken into account.
class PoissonLikeMetric : public Chi2Metric {
public:
    PoissonLikeMetric();

#ifndef SWIG
    PoissonLikeMetric* clone() const override;
#endif // SWIG

    using Chi2Metric::computeFromArrays;

    //! Computes metric value from data arrays. Negative values in exp_data are ignored.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    double computeFromArrays(std::vector<double> sim_data,
                             std::vector<double> exp_data) const override;
};

//! Implementation of the standard \f$ \chi^2 \f$ metric with intensity \f$I\f$
//! and experimental data \f$D\f$
//! being replaced by \f$ \log_{10} I \f$ and \f$\log_{10} D\f$ accordingly.
//! With default L2 norm corresponds to the formula
//! \f[\chi^2 = \sum \frac{(\log_{10} I - log_{10} D)^2 D^2 \ln^2{10}}{\delta_D^2}\f]
class LogMetric : public ObjectiveMetric {
public:
    LogMetric();

#ifndef SWIG
    LogMetric* clone() const override;
#endif // SWIG

    //! Computes metric value from data arrays. Negative values in exp_data
    //! are ignored as well as non-positive uncertainties.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    //! @param exp_stdv: array with experimental data uncertainties.
    double computeFromArrays(std::vector<double> sim_data, std::vector<double> exp_data,
                             std::vector<double> exp_stdv) const override;

    //! Computes metric value from data arrays. Negative values in exp_data are ignored.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    double computeFromArrays(std::vector<double> sim_data,
                             std::vector<double> exp_data) const override;
};

//! Implementation of relative difference metric.
//! With default L2 norm and weighting off corresponds to the formula
//! \f[Result = \sum \frac{(I - D)^2}{(I + D)^2}\f]
//! where \f$I\f$ is the simulated intensity, \f$D\f$ - experimental data.
//! If weighting is on, falls back to the standard \f$\chi^2\f$ metric.
class meanRelativeDifferenceMetric : public Chi2Metric {
public:
    meanRelativeDifferenceMetric();

#ifndef SWIG
    meanRelativeDifferenceMetric* clone() const override;
#endif // SWIG

    using Chi2Metric::computeFromArrays;

    //! Computes metric value from data arrays. Negative values in exp_data are ignored.
    //! All arrays involved in the computation must be of the same size.
    //! @param sim_data: array with simulated intensities.
    //! @param exp_data: array with intensity values obtained from an experiment.
    double computeFromArrays(std::vector<double> sim_data,
                             std::vector<double> exp_data) const override;
};

//! Implementation of relative difference metric.
//! With default L2 norm and weighting off corresponds to the formula
//! \f[Result = \sum (I \cdot Q^4 - D \cdot Q^4)^2\f]
//! where \f$Q\f$ is the scattering vector magnitude. If weighting is on,
//! coincides with the metric provided by Chi2Metric class.
class RQ4Metric : public Chi2Metric {
public:
    RQ4Metric();

#ifndef SWIG
    RQ4Metric* clone() const override;
#endif // SWIG

    //! Computes metric value from SimDataPair object. Calls computeFromArrays internally.
    //! @param data_pair: SimDataPair object. Can optionally contain data uncertainties
    //! @param use_weights: boolean, defines if data uncertainties should be taken into account
    double computeMetric(const SimDataPair& data_pair, bool use_weights) const override;
};

#endif // BORNAGAIN_SIM_FITTING_OBJECTIVEMETRIC_H