/
LinearBackground.cpp
127 lines (108 loc) · 3.79 KB
/
LinearBackground.cpp
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
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidCurveFitting/Functions/LinearBackground.h"
#include "MantidAPI/FunctionFactory.h"
namespace Mantid::CurveFitting::Functions {
using namespace CurveFitting;
using namespace Kernel;
using namespace API;
DECLARE_FUNCTION(LinearBackground)
void LinearBackground::init() {
declareParameter("A0", 0.0, "coefficient for constant term");
declareParameter("A1", 0.0, "coefficient for linear term");
}
void LinearBackground::function1D(double *out, const double *xValues, const size_t nData) const {
const double a0 = getParameter("A0");
const double a1 = getParameter("A1");
for (size_t i = 0; i < nData; i++) {
out[i] = a0 + a1 * xValues[i];
}
}
void LinearBackground::functionDeriv1D(Jacobian *out, const double *xValues, const size_t nData) {
for (size_t i = 0; i < nData; i++) {
out->set(i, 0, 1);
out->set(i, 1, xValues[i]);
}
}
/**
* Do linear fit to the data in X and Y
* @param X :: Vector with x-values
* @param Y :: Vector with y-values
*/
void LinearBackground::fit(const std::vector<double> &X, const std::vector<double> &Y) {
if (X.size() != Y.size()) {
throw std::runtime_error("Background fit: different array sizes");
}
size_t n = X.size();
if (n == 0) {
setParameter("A0", 0);
setParameter("A1", 0);
return;
} else if (n == 1) {
setParameter("A0", Y[0]);
setParameter("A1", 0);
return;
}
double x_mean = 0;
double y_mean = 0;
double x2_mean = 0;
double xy_mean = 0;
for (size_t i = 0; i < n; i++) {
double x = X[i];
double y = Y[i];
x_mean += x;
y_mean += y;
x2_mean += x * x;
xy_mean += x * y;
}
x_mean /= static_cast<double>(n);
y_mean /= static_cast<double>(n);
x2_mean /= static_cast<double>(n);
xy_mean /= static_cast<double>(n);
double a1 = (xy_mean - x_mean * y_mean) / (x2_mean - x_mean * x_mean);
double a0 = y_mean - a1 * x_mean;
setParameter("A0", a0);
setParameter("A1", a1);
}
/// Calculate histogram data for the given bin boundaries.
/// @param out :: Output bin values (size == nBins) - integrals of the function
/// inside each bin.
/// @param left :: The left-most bin boundary.
/// @param right :: A pointer to an array of successive right bin boundaries
/// (size = nBins).
/// @param nBins :: Number of bins.
void LinearBackground::histogram1D(double *out, double left, const double *right, const size_t nBins) const {
const double a0 = getParameter("A0");
const double a1 = getParameter("A1");
auto cumulFun = [a0, a1](double x) { return (a0 + 0.5 * a1 * x) * x; };
double cLeft = cumulFun(left);
for (size_t i = 0; i < nBins; ++i) {
double cRight = cumulFun(right[i]);
out[i] = cRight - cLeft;
cLeft = cRight;
}
}
/// Derivatives of the histogram.
/// @param jacobian :: The output Jacobian.
/// @param left :: The left-most bin boundary.
/// @param right :: A pointer to an array of successive right bin boundaries
/// (size = nBins).
/// @param nBins :: Number of bins.
void LinearBackground::histogramDerivative1D(Jacobian *jacobian, double left, const double *right,
const size_t nBins) const {
double xl = left;
for (size_t i = 0; i < nBins; ++i) {
double xr = right[i];
jacobian->set(i, 0, xr - xl);
jacobian->set(i, 1, 0.5 * (xr * xr - xl * xl));
xl = xr;
}
}
} // namespace Mantid::CurveFitting::Functions