Mantid
Loading...
Searching...
No Matches
UserFunction1D.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//----------------------------------------------------------------------
14
16
17using namespace CurveFitting;
18
19// Register the class into the algorithm factory
20DECLARE_ALGORITHM(UserFunction1D)
21
22using namespace Kernel;
23
24using namespace API;
25
31double *UserFunction1D::AddVariable(const char *varName, void *palg) {
32 UserFunction1D &alg = *reinterpret_cast<UserFunction1D *>(palg);
33
34 if (std::string(varName) != "x") {
35 alg.declareProperty(varName, 0.0);
36 alg.m_parameterNames.emplace_back(varName);
37 } else {
38 alg.m_x_set = true;
39 alg.m_x = 0.;
40 return &alg.m_x;
41 }
42
43 return &alg.m_parameters[alg.m_nPars++];
44}
45
49 declareProperty("Function", "", std::make_shared<MandatoryValidator<std::string>>(), "The fit function");
50 declareProperty("InitialParameters", "",
51 "The comma separated list of initial values of the fit "
52 "parameters in the form varName=value");
53}
54
58 m_parser.SetVarFactory(AddVariable, this);
59 std::string funct = getProperty("Function");
60 m_parser.SetExpr(funct);
61
62 // Call Eval() to implicitly initialize the variables
63 m_parser.Eval();
64
65 if (!m_x_set)
66 throw std::runtime_error("Formula does not contain the x variable");
67
68 // Set the initial values to the fit parameters
69 std::string initParams = getProperty("InitialParameters");
70 if (!initParams.empty()) {
72 for (const auto &it : values) {
73 size_t ieq = it.find('=');
74 if (ieq == std::string::npos)
75 throw std::invalid_argument("Property InitialParameters is malformed");
76 std::string varName = it.substr(0, ieq);
77 std::string varValue = it.substr(ieq + 1);
78 size_t i0 = varName.find_first_not_of(" \t");
79 size_t i1 = varName.find_last_not_of(" \t");
80 if (i0 == std::string::npos)
81 throw std::invalid_argument("Property InitialParameters is malformed");
82 varName = varName.substr(i0, i1 - i0 + 1);
83 if (varName.empty() || varValue.empty())
84 throw std::invalid_argument("Property InitialParameters is malformed");
85 double value = std::stod(varValue);
86 if (!existsProperty(varName))
87 throw std::invalid_argument("Fit parameter " + varName + " does not exist");
88 setProperty(varName, value);
89 }
90 }
91}
92
93/*double UserFunction1D::function(const double* in, const double& x)
94{
95 for(int i=0;i<m_nPars;i++)
96 m_parameters[i] = in[i];
97
98 m_x = x;
99 return m_parser.Eval();
100}*/
101
110void UserFunction1D::function(const double *in, double *out, const double *xValues, const size_t nData) {
111 for (size_t i = 0; i < static_cast<size_t>(m_nPars); i++)
112 m_parameters[i] = in[i];
113
114 for (size_t i = 0; i < nData; i++) {
115 m_x = xValues[i];
116 out[i] = m_parser.Eval();
117 }
118}
119
126void UserFunction1D::functionDeriv(const double *in, Jacobian *out, const double *xValues, const size_t nData) {
127 // throw Exception::NotImplementedError("No derivative function provided");
128 if (nData == 0)
129 return;
130 std::vector<double> dp(m_nPars);
131 std::vector<double> in1(m_nPars);
132 for (int i = 0; i < m_nPars; i++) {
133 in1[i] = in[i];
134 m_parameters[i] = in[i];
135 if (m_parameters[i] != 0.0)
136 dp[i] = m_parameters[i] * 0.01;
137 else
138 dp[i] = 0.01;
139 }
140
141 if (m_tmp.empty()) {
142 m_tmp.resize(nData);
143 m_tmp1.resize(nData);
144 }
145
146 function(in, m_tmp.data(), xValues, nData);
147
148 for (int j = 0; j < m_nPars; j++) {
149 in1[j] += dp[j];
150 function(&in1[0], m_tmp1.data(), xValues, nData);
151 for (size_t i = 0; i < nData; i++) {
152 out->set(i, j, (m_tmp1[i] - m_tmp[i]) / dp[j]);
153 }
154 in1[j] -= dp[j];
155 }
156}
157
158} // namespace Mantid::CurveFitting::Functions
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
double value
The value of the point.
Definition: FitMW.cpp:51
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
Definition: Algorithm.cpp:2008
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
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::vector< std::string > m_parameterNames
Holds a copy of the names of the fitting parameters.
Definition: Fit1D.h:114
Deprecation notice: instead of using this algorithm please use the Fit algorithm where the Function p...
int m_nPars
Number of actual parameters.
void declareAdditionalProperties() override
Declare properties that are not fit parameters.
std::vector< double > m_tmp
Temporary data storage.
std::vector< double > m_parameters
Pointer to muParser variables' buffer.
void functionDeriv(const double *in, API::Jacobian *out, const double *xValues, const size_t nData) override
Derivatives of function with respect to parameters you are trying to fit.
static double * AddVariable(const char *varName, void *palg)
Static callback function used by MuParser to initialize variables implicitly.
bool m_x_set
True indicates that input formula contains 'x' variable.
void function(const double *in, double *out, const double *xValues, const size_t nData) override
overwrite base class methods
void prepare() override
Declare fit parameters using muParser's implicit variable initialization.
double m_x
Used as 'x' variable in m_parser.
std::vector< double > m_tmp1
Temporary data storage.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
Validator to check that a property is not left empty.
@ TOK_TRIM
remove leading and trailing whitespace from tokens