Mantid
Loading...
Searching...
No Matches
Gaussian.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
12
13#include <cmath>
14#include <numeric>
15
17
18using namespace CurveFitting;
19using namespace Kernel;
20using namespace API;
21
22DECLARE_FUNCTION(Gaussian)
23
24Gaussian::Gaussian() : IPeakFunction(), m_intensityCache(0.0) {}
25
27 declareParameter("Height", 0.0, "Height of peak");
28 declareParameter("PeakCentre", 0.0, "Centre of peak");
29 declareParameter("Sigma", 0.0, "Width parameter");
30}
31
32void Gaussian::functionLocal(double *out, const double *xValues, const size_t nData) const {
33 const auto peakHeight = getParameter("Height");
34 const auto peakCentre = getParameter("PeakCentre");
35 const auto weight = 1 / getParameter("Sigma");
36
37 for (size_t i = 0; i < nData; i++) {
38 const auto diff = (xValues[i] - peakCentre) * weight;
39 out[i] = peakHeight * exp(-0.5 * diff * diff);
40 }
41}
42
43void Gaussian::functionDerivLocal(Jacobian *out, const double *xValues, const size_t nData) {
44 const auto peakHeight = getParameter("Height");
45 const auto peakCentre = getParameter("PeakCentre");
46 const auto weight = 1 / getParameter("Sigma");
47 const auto weight_sq = weight * weight;
48
49 for (size_t i = 0; i < nData; i++) {
50 const auto diff = xValues[i] - peakCentre;
51 const auto e = exp(-0.5 * diff * diff * weight_sq);
52 out->set(i, 0, e);
53 out->set(i, 1, diff * peakHeight * e * weight_sq);
54 out->set(i, 2,
55 -weight * diff * diff * peakHeight * e); // derivative with respect to weight not sigma
56 }
57}
58
59void Gaussian::setActiveParameter(size_t i, double value) {
60 if (!isActive(i)) {
61 throw std::runtime_error("Attempt to use an inactive parameter");
62 }
63 if (parameterName(i) == "Sigma")
64 setParameter(i, 1. / value, false);
65 else
66 setParameter(i, value, false);
67}
68
69double Gaussian::activeParameter(size_t i) const {
70 if (!isActive(i)) {
71 throw std::runtime_error("Attempt to use an inactive parameter");
72 }
73 if (parameterName(i) == "Sigma")
74 return 1. / getParameter(i);
75 else
76 return getParameter(i);
77}
78
79double Gaussian::centre() const { return getParameter("PeakCentre"); }
80double Gaussian::height() const { return getParameter("Height"); }
81double Gaussian::fwhm() const { return 2.0 * sqrt(2.0 * M_LN2) * getParameter("Sigma"); }
82double Gaussian::intensity() const {
83 auto sigma = getParameter("Sigma");
84 if (sigma == 0.0) {
85 auto peakHeight = getParameter("Height");
86 if (std::isfinite(peakHeight)) {
87 m_intensityCache = peakHeight;
88 }
89 } else {
90 m_intensityCache = getParameter("Height") * getParameter("Sigma") * sqrt(2.0 * M_PI);
91 }
92 return m_intensityCache;
93}
95 const double heightError = getError("Height");
96 const double sigmaError = getError("Sigma");
97
98 return intensity() * sqrt(pow(heightError / getParameter("Height"), 2) + pow(sigmaError / getParameter("Sigma"), 2));
99}
100
101void Gaussian::setCentre(const double c) { setParameter("PeakCentre", c); }
102void Gaussian::setHeight(const double h) { setParameter("Height", h); }
103void Gaussian::setFwhm(const double w) { setParameter("Sigma", w / (2.0 * sqrt(2.0 * M_LN2))); }
104void Gaussian::setIntensity(const double i) {
106 auto sigma = getParameter("Sigma");
107 if (sigma == 0.0) {
108 setParameter("Height", i);
109 } else {
110 setParameter("Height", i / (sigma * sqrt(2.0 * M_PI)));
111 }
112}
113
114void Gaussian::fixCentre(bool isDefault) { fixParameter("PeakCentre", isDefault); }
115
116void Gaussian::unfixCentre() { unfixParameter("PeakCentre"); }
117
118void Gaussian::fixIntensity(bool isDefault) {
119 std::string formula = std::to_string(intensity() / sqrt(2.0 * M_PI)) + "/Sigma";
120 tie("Height", formula, isDefault);
121}
122
124
132void Gaussian::histogram1D(double *out, double left, const double *right, const size_t nBins) const {
133
134 const auto amplitude = intensity();
135 const auto peakCentre = getParameter("PeakCentre");
136 const auto sigma2 = getParameter("Sigma") * sqrt(2.0);
137
138 auto cumulFun = [sigma2, peakCentre](double x) { return 0.5 * erf((x - peakCentre) / sigma2); };
139 auto cLeft = cumulFun(left);
140 auto xLeft = left;
141 for (size_t i = 0; i < nBins; ++i) {
142 const auto bin_width = right[i] - xLeft;
143 const auto cRight = cumulFun(right[i]);
144 out[i] = amplitude * (cRight - cLeft) / bin_width;
145 cLeft = cRight;
146 xLeft = right[i];
147 }
148}
149
156void Gaussian::histogramDerivative1D(Jacobian *jacobian, double left, const double *right, const size_t nBins) const {
157 const auto h = getParameter("Height");
158 const auto c = getParameter("PeakCentre");
159 const auto w = 1 / getParameter("Sigma");
160
161 auto e = [w](const double d) { return exp(-0.5 * w * w * d * d); };
162 auto eint = [w](double d) {
163 return std::sqrt(M_PI / 2.0) * (1.0 / w) * std::erf(w * d / M_SQRT2);
164 }; // integral of gaussian (h=1)
165
166 auto dLeft = left - c;
167 auto eLeft = e(dLeft);
168 auto eintLeft = eint(dLeft);
169 for (size_t i = 0; i < nBins; ++i) {
170 const auto dRight = right[i] - c;
171 const auto bin_width = dRight - dLeft;
172 const auto eRight = e(dRight);
173 const auto eintRight = eint(dRight);
174 jacobian->set(i, 0, (eintRight - eintLeft) / bin_width); // height
175 jacobian->set(i, 1, -h * (eRight - eLeft) / bin_width); // centre
176 jacobian->set(i, 2,
177 h * ((dRight * eRight - eintRight) - (dLeft * eLeft - eintLeft)) / (w * bin_width)); // weight
178 eLeft = eRight;
179 eintLeft = eintRight;
180 dLeft = dRight;
181 }
182}
183
184} // namespace Mantid::CurveFitting::Functions
double value
The value of the point.
Definition FitMW.cpp:51
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
double sigma
Definition GetAllEi.cpp:156
double left
double right
bool isActive(size_t i) const
Check if an active parameter i is actually active.
void unfixParameter(const std::string &name)
Free a parameter.
virtual void tie(const std::string &parName, const std::string &expr, bool isDefault=false)
Tie a parameter to other parameters (or a constant)
void fixParameter(const std::string &name, bool isDefault=false)
Fix a parameter.
virtual void removeTie(const std::string &parName)
Removes the tie off a parameter.
An interface to a peak function, which extend the interface of IFunctionWithLocation by adding method...
void setParameter(const std::string &name, const double &value, bool explicitlySet=true) override
Override parent so that we may bust the cache when a parameter is set.
Represents the Jacobian in IFitFunction::functionDeriv.
Definition Jacobian.h:22
virtual void set(size_t iY, size_t iP, double value)=0
Set a value to a Jacobian matrix element.
double getError(size_t i) const override
Get the fitting error for a parameter.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
double getParameter(size_t i) const override
Get i-th parameter.
Provide gaussian peak shape function interface to IPeakFunction.
Definition Gaussian.h:36
void fixIntensity(bool isDefault=false) override
Fix a parameter or set up a tie such that value returned by intensity() is constant during fitting.
Definition Gaussian.cpp:118
void setHeight(const double h) override
Sets the parameters such that height == h.
Definition Gaussian.cpp:102
double centre() const override
overwrite IPeakFunction base class methods
Definition Gaussian.cpp:79
void histogramDerivative1D(API::Jacobian *jacobian, double left, const double *right, const size_t nBins) const override
Devivatives of the histogram.
Definition Gaussian.cpp:156
void setFwhm(const double w) override
Sets the parameters such that FWHM = w.
Definition Gaussian.cpp:103
void setIntensity(const double i) override
Sets the integral intensity of the peak.
Definition Gaussian.cpp:104
void setCentre(const double c) override
Sets the parameters such that centre == c.
Definition Gaussian.cpp:101
double intensity() const override
Returns the integral intensity of the peak.
Definition Gaussian.cpp:82
double fwhm() const override
Returns the peak FWHM.
Definition Gaussian.cpp:81
void functionLocal(double *out, const double *xValues, const size_t nData) const override
Function evaluation method to be implemented in the inherited classes.
Definition Gaussian.cpp:32
double activeParameter(size_t i) const override
Value of i-th active parameter.
Definition Gaussian.cpp:69
double intensityError() const override
Error in the integrated intensity of the peak due to uncertainties in the values of the fit parameter...
Definition Gaussian.cpp:94
void unfixIntensity() override
Free the intensity parameter.
Definition Gaussian.cpp:123
void init() override
overwrite IFunction base class method, which declare function parameters
Definition Gaussian.cpp:26
void unfixCentre() override
Free the centre parameter.
Definition Gaussian.cpp:116
void histogram1D(double *out, double left, const double *right, const size_t nBins) const override
Calculate histogram data.
Definition Gaussian.cpp:132
double height() const override
Returns the height of the function.
Definition Gaussian.cpp:80
double m_intensityCache
Intensity cache to help recover form Sigma==0 situation.
Definition Gaussian.h:73
void functionDerivLocal(API::Jacobian *out, const double *xValues, const size_t nData) override
Derivative evaluation method. Default is to calculate numerically.
Definition Gaussian.cpp:43
void fixCentre(bool isDefault=false) override
Fix a parameter or set up a tie such that value returned by centre() is constant during fitting.
Definition Gaussian.cpp:114
void setActiveParameter(size_t i, double value) override
Set new value of i-th active parameter.
Definition Gaussian.cpp:59
std::string to_string(const wide_integer< Bits, Signed > &n)