Mantid
Loading...
Searching...
No Matches
Chebyshev.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 <algorithm>
14#include <stdexcept>
15
17
18using namespace CurveFitting;
19
20using namespace Kernel;
21
22using namespace API;
23
24DECLARE_FUNCTION(Chebyshev)
25
26Chebyshev::Chebyshev() : m_n(0), m_StartX(-1.), m_EndX(1.) {
27 declareParameter("A0");
28 declareAttribute("n", Attribute(m_n));
29 declareAttribute("StartX", Attribute(m_StartX));
30 declareAttribute("EndX", Attribute(m_EndX));
31}
32
33void Chebyshev::function1D(double *out, const double *xValues, const size_t nData) const {
34 if (m_StartX >= m_EndX) {
35 throw std::runtime_error("Chebyshev: invalid x-range");
36 }
37 double b = 2. / (m_EndX - m_StartX);
38 double a = 1. - b * m_EndX;
39 if (static_cast<int>(m_b.size()) != m_n + 3) {
40 m_b.resize(m_n + 3);
41 }
42 for (size_t i = 0; i < nData; ++i) {
43 // scale to interval -1 < x < 1
44 double x = a + b * xValues[i];
45 m_b[m_n + 2] = 0.;
46 m_b[m_n + 1] = 0.;
47 for (int j = m_n; j > 0; --j) {
48 m_b[j] = m_b[j + 1] * x * 2 - m_b[j + 2] + getParameter(j);
49 }
50 out[i] = x * m_b[1] - m_b[2] + getParameter(0);
51 }
52}
53
54void Chebyshev::functionDeriv1D(Jacobian *out, const double *xValues, const size_t nData) {
55 if (m_n < 0) {
56 return;
57 }
58
59 double b = 2. / (m_EndX - m_StartX);
60 double a = 1. - b * m_EndX;
61
62 for (size_t i = 0; i < nData; i++) {
63 double t0 = 1.;
64 double x = a + b * xValues[i];
65 double t1 = x;
66 out->set(i, 0, 1);
67 if (m_n == 0)
68 continue;
69 out->set(i, 1, x);
70 for (int j = 2; j <= m_n; ++j) {
71 double t = 2 * x * t1 - t0;
72 out->set(i, j, t);
73 t0 = t1;
74 t1 = t;
75 }
76 }
77}
78
84void Chebyshev::setAttribute(const std::string &attName, const API::IFunction::Attribute &att) {
85 storeAttributeValue(attName, att);
86
87 if (attName == "n") {
88 // set the polynomial order
89
90 auto newN = att.asInt();
91 if (newN < 0) {
92 throw std::invalid_argument("Chebyshev: polynomial order cannot be negative.");
93 }
94
95 // Save old values
96 std::vector<double> oldValues(std::min(m_n, newN) + 1);
97 for (size_t i = 0; i < oldValues.size(); ++i) {
98 oldValues[i] = getParameter(i);
99 }
100
101 if (m_n >= 0) {
103 }
104 m_n = att.asInt();
105 for (int i = 0; i <= m_n; ++i) {
106 std::string parName = "A" + std::to_string(i);
107 declareParameter(parName);
108 }
109
110 // Reset old values to new parameters
111 for (size_t i = 0; i < oldValues.size(); ++i) {
112 setParameter(i, oldValues[i]);
113 }
114
115 } else if (attName == "StartX") {
116 m_StartX = att.asDouble();
117 } else if (attName == "EndX") {
118 m_EndX = att.asDouble();
119 }
120}
121
122} // namespace Mantid::CurveFitting::Functions
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Mantid::API::IFunction::Attribute Attribute
Definition: IsoRotDiff.cpp:25
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
Definition: IFunction.cpp:726
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
Definition: IFunction.cpp:739
void storeAttributeValue(const std::string &name, const API::IFunction::Attribute &value)
Store an attribute's value.
Definition: IFunction.cpp:1464
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.
void clearAllParameters()
Nonvirtual member which removes all declared parameters.
void setParameter(size_t, const double &value, bool explicitlySet=true) override
Set i-th parameter.
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.
Implements Chebyshev polynomial expansion.
Definition: Chebyshev.h:30
double m_EndX
Upper x boundary. The default is 1.
Definition: Chebyshev.h:50
void functionDeriv1D(API::Jacobian *out, const double *xValues, const size_t nData) override
Derivatives of function with respect to active parameters.
Definition: Chebyshev.cpp:54
void setAttribute(const std::string &attName, const Attribute &) override
Set a value to attribute attName.
Definition: Chebyshev.cpp:84
double m_StartX
Lower x boundary. The default is -1.
Definition: Chebyshev.h:48
std::valarray< double > m_b
Keep intermediate calculatons.
Definition: Chebyshev.h:52
void function1D(double *out, const double *xValues, const size_t nData) const override
Function you want to fit to.
Definition: Chebyshev.cpp:33
std::string to_string(const wide_integer< Bits, Signed > &n)