Mantid
Loading...
Searching...
No Matches
UserFunction.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#include <boost/tokenizer.hpp>
15
17
18using namespace CurveFitting;
19
20// Register the class into the function factory
21DECLARE_FUNCTION(UserFunction)
22
24using namespace Kernel;
25using namespace API;
26
28UserFunction::UserFunction() : m_parser(new mu::Parser()), m_x(0.), m_x_set(false) {
29 extraOneVarFunctions(*m_parser);
30 declareAttribute("Formula", Attribute(""));
31}
32
35
40double *UserFunction::AddVariable(const char *varName, void *pufun) {
41 UserFunction &fun = *reinterpret_cast<UserFunction *>(pufun);
42
43 if (std::string(varName) != "x") {
44 try {
45 fun.declareParameter(varName, 0.0);
46 } catch (...) {
47 }
48 } else {
49 fun.m_x_set = true;
50 fun.m_x = 0.;
51 }
52
53 return &fun.m_x;
54}
55
61void UserFunction::setAttribute(const std::string &attName, const Attribute &value) {
62 auto const reevaluateFormula = attName == "Formula" && m_formula != value.value();
63
65
66 if (!reevaluateFormula) {
67 return;
68 }
69
70 m_x_set = false;
72
73 try {
74 mu::Parser tmp_parser;
75 extraOneVarFunctions(tmp_parser);
76 tmp_parser.SetVarFactory(AddVariable, this);
77
78 m_formula = value.asString();
79 tmp_parser.SetExpr(m_formula);
80
81 // Call Eval() to implicitly initialize the variables
82 tmp_parser.Eval();
83
84 } catch (...) {
85 // Formula may be edited by a GUI component
86 return;
87 }
88
89 if (!m_x_set) {
90 // Formula may be edited by a GUI component
91 return;
92 }
93
94 m_parser->ClearVar();
95 m_parser->DefineVar("x", &m_x);
96 for (size_t i = 0; i < nParams(); i++) {
98 }
99
100 m_parser->SetExpr(m_formula);
101}
102
110void UserFunction::function1D(double *out, const double *xValues, const size_t nData) const {
111 if (m_formula.empty()) {
112 throw std::invalid_argument("Empty formula supplied for user function");
113 }
114 for (size_t i = 0; i < nData; i++) {
115 m_x = xValues[i];
116 try {
117 out[i] = m_parser->Eval();
118 } catch (mu::Parser::exception_type &e) {
119 throw std::invalid_argument("Error evaluating function \"" + m_formula + "\" for x=" + std::to_string(m_x) +
120 ": " + e.GetMsg());
121 }
122 }
123}
124
131 calNumericalDeriv(domain, jacobian);
132}
133
134} // 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.
Base class that represents the domain of a function.
Attribute is a non-fitting parameter.
Definition IFunction.h:285
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
void calNumericalDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Calculate numerical derivatives.
Represents the Jacobian in IFitFunction::functionDeriv.
Definition Jacobian.h:22
void clearAllParameters()
Nonvirtual member which removes all declared parameters.
virtual double * getParameterAddress(size_t i)
Get the address of the parameter. For use in UserFunction with mu::Parser.
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.
size_t nParams() const override
Total number of parameters.
static double * AddVariable(const char *varName, void *pufun)
mu::Parser callback function for setting variables.
void function1D(double *out, const double *xValues, const size_t nData) const override
Function you want to fit to.
void setAttribute(const std::string &attName, const Attribute &value) override
Set a value to attribute attName.
bool m_x_set
True indicates that input formula contains 'x' variable.
double m_x
Used as 'x' variable in m_parser.
void functionDeriv(const API::FunctionDomain &domain, API::Jacobian &jacobian) override
Derivatives of function with respect to active parameters.
mu::Parser * m_parser
extended muParser instance
void MANTID_API_DLL extraOneVarFunctions(mu::Parser &parser)
std::string to_string(const wide_integer< Bits, Signed > &n)