Mantid
Loading...
Searching...
No Matches
ChudleyElliotSQE.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// Mantid Coding standars <http://www.mantidproject.org/Coding_Standards>
8// Main Module Header
10// Mantid Headers from the same project
11// N/A
12// Mantid headers from other projects
14#include "MantidAPI/IFunction.h"
15#include "MantidAPI/Jacobian.h"
16// third party library headers
17// N/A
18// standard library headers
19#include <cmath>
20#include <limits>
21
22namespace {
23Mantid::Kernel::Logger g_log("ChudleyElliotSQE");
24}
25
27
28DECLARE_FUNCTION(ChudleyElliotSQE)
29
30
33void ChudleyElliotSQE::declareParameters() {
34 this->declareParameter("Height", 1.0, "scaling factor");
35 this->declareParameter("Centre", 0.0, "Shift along the X-axis");
36 this->declareParameter("Tau", 1.25, "Residence time");
37 this->declareParameter("L", 1.25, "Jump length");
38}
39
46void ChudleyElliotSQE::function1D(double *out, const double *xValues, const size_t nData) const {
47 double hbar(0.658211626); // ps*meV
48 auto H = this->getParameter("Height");
49 auto C = this->getParameter("Centre");
50 auto Q = this->getAttribute("Q").asDouble();
51 auto T = this->getParameter("Tau");
52 auto L = this->getParameter("L");
53
54 // Penalize negative parameters, just in case they show up
55 // when calculating the numeric derivative
56 if (H < std::numeric_limits<double>::epsilon() || T < std::numeric_limits<double>::epsilon()) {
57 for (size_t j = 0; j < nData; j++) {
58 out[j] = std::numeric_limits<double>::infinity();
59 }
60 return;
61 }
62
63 // Lorentzian intensities and HWHM
64 auto G = hbar * (1 - (sin(Q * L) / (Q * L))) / T;
65 for (size_t j = 0; j < nData; j++) {
66 auto E = xValues[j] - C;
67 out[j] += H * G / (G * G + E * E) / M_PI;
68 }
69}
70
77void ChudleyElliotSQE::functionDeriv1D(Mantid::API::Jacobian *jacobian, const double *xValues, const size_t nData) {
78 const double deltaF{0.1}; // increase parameter by this fraction
79 const size_t nParam = this->nParams();
80 // cutoff defines the smallest change in the parameter when calculating the
81 // numerical derivative
82 std::map<std::string, double> cutoff;
83 cutoff["Tau"] = 0.2; // 0.2ps
84 cutoff["Centre"] = 0.0001; // 0.1micro-eV
85 std::vector<double> out(nData);
86 this->applyTies();
87 this->function1D(out.data(), xValues, nData);
88
89 for (size_t iP = 0; iP < nParam; iP++) {
90 std::vector<double> derivative(nData);
91 if (this->isActive(iP)) {
92 const double pVal = this->activeParameter(iP);
93 const std::string pName = this->parameterName(iP);
94 if (pName == "Height") {
95 // exact derivative
96 this->setActiveParameter(iP, 1.0);
97 this->applyTies();
98 this->function1D(derivative.data(), xValues, nData);
99 } else {
100 // numerical derivative
101 double delta = cutoff[pName] > fabs(pVal * deltaF) ? cutoff[pName] : pVal * deltaF;
102 this->setActiveParameter(iP, pVal + delta);
103 this->applyTies();
104 this->function1D(derivative.data(), xValues, nData);
105 for (size_t i = 0; i < nData; i++) {
106 derivative[i] = (derivative[i] - out[i]) / delta;
107 }
108 }
109 this->setActiveParameter(iP, pVal); // restore the value of the parameter
110 // fill the jacobian for this parameter
111 for (size_t i = 0; i < nData; i++) {
112 jacobian->set(i, iP, derivative[i]);
113 }
114 }
115 }
116}
117
118} // namespace Mantid::CurveFitting::Functions
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
#define fabs(x)
Definition: Matrix.cpp:22
virtual void derivative(const FunctionDomain &domain, FunctionValues &values, const size_t order=1) const
Definition: IFunction1D.cpp:65
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
Definition: IFunction.cpp:739
bool isActive(size_t i) const
Check if an active parameter i is actually active.
Definition: IFunction.cpp:160
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
Definition: IFunction.cpp:1394
virtual void applyTies()
Apply the ties.
Definition: IFunction.cpp:306
virtual double activeParameter(size_t i) const
Value of i-th active parameter.
Definition: IFunction.cpp:988
virtual void setActiveParameter(size_t i, double value)
Set new value of i-th active parameter.
Definition: IFunction.cpp:997
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.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
size_t nParams() const override
Total number of parameters.
Definition: ParamFunction.h:53
double getParameter(size_t i) const override
Get i-th parameter.
Chudley-Elliots jump diffusion model.
void function1D(double *out, const double *xValues, const size_t nData) const override
Calculate function values on an energy domain.
void functionDeriv1D(Mantid::API::Jacobian *jacobian, const double *xValues, const size_t nData) override
analytical/numerical derivative with respect to fitting parameters We carry out analytical derivative...
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
Kernel::Logger g_log("ExperimentInfo")
static logger object