Mantid
Loading...
Searching...
No Matches
SimpleChebfun.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 +
9
10#include <memory>
11#include <utility>
12
14
15using namespace CurveFitting;
16
17//----------------------------------------------------------------------------------------------
25SimpleChebfun::SimpleChebfun(size_t n, ChebfunFunctionType fun, double start, double end)
26 : m_base(std::make_shared<ChebfunBase>(n, start, end)), m_badFit(false) {
27 m_P = m_base->fit(std::move(fun));
28}
29
30SimpleChebfun::SimpleChebfun(size_t n, const API::IFunction &fun, double start, double end)
31 : m_base(std::make_shared<ChebfunBase>(n, start, end)), m_badFit(false) {
32 m_P = m_base->fit(fun);
33}
34
47SimpleChebfun::SimpleChebfun(const ChebfunFunctionType &fun, double start, double end, double accuracy, size_t badSize)
48 : m_badFit(false) {
49 m_base = ChebfunBase::bestFitAnyTolerance<ChebfunFunctionType>(start, end, fun, m_P, m_A, accuracy);
50 if (!m_base) {
51 m_base = std::make_shared<ChebfunBase>(badSize - 1, start, end, accuracy);
52 m_P = m_base->fit(fun);
53 m_badFit = true;
54 }
55}
56
57SimpleChebfun::SimpleChebfun(const API::IFunction &fun, double start, double end, double accuracy, size_t badSize)
58 : m_badFit(false) {
59 m_base = ChebfunBase::bestFitAnyTolerance<const API::IFunction &>(start, end, fun, m_P, m_A, accuracy);
60 if (!m_base) {
61 m_base = std::make_shared<ChebfunBase>(badSize - 1, start, end, accuracy);
62 m_P = m_base->fit(fun);
63 m_badFit = true;
64 }
65}
66
70SimpleChebfun::SimpleChebfun(const std::vector<double> &x, const std::vector<double> &y)
71 : m_base(std::make_shared<ChebfunBase>(x.size() - 1, x.front(), x.back())), m_badFit(false) {
72 m_P = m_base->smooth(x, y);
73}
74
76SimpleChebfun::SimpleChebfun(const ChebfunBase_sptr &base) : m_badFit(false) {
77 assert(base);
78 m_base = base;
79 m_P.resize(base->size());
80}
81
83const std::vector<double> &SimpleChebfun::coeffs() const {
84 if (m_A.empty()) {
85 m_A = m_base->calcA(m_P);
86 }
87 return m_A;
88}
89
92double SimpleChebfun::operator()(double x) const { return m_base->eval(x, m_P); }
93
96std::vector<double> SimpleChebfun::operator()(const std::vector<double> &x) const { return m_base->evalVector(x, m_P); }
97
100std::vector<double> SimpleChebfun::linspace(size_t n) const { return m_base->linspace(n); }
101
103double SimpleChebfun::accuracy() const { return m_base->tolerance(); }
104
107 SimpleChebfun cheb(m_base);
108 if (m_A.empty()) {
109 m_A = m_base->calcA(m_P);
110 }
111 m_base->derivative(m_A, cheb.m_A);
112 cheb.m_P = m_base->calcP(cheb.m_A);
113 return cheb;
114}
115
118 if (m_A.empty()) {
119 m_A = m_base->calcA(m_P);
120 }
121 std::vector<double> A;
122 auto base = m_base->integral(m_A, A);
123 SimpleChebfun cheb(base);
124 cheb.m_P = base->calcP(A);
125 cheb.m_A = A;
126 return cheb;
127}
128
131std::vector<double> SimpleChebfun::roughRoots(double level) const {
132 std::vector<double> rs;
133 if (m_P.empty())
134 return rs;
135 auto &x = m_base->xPoints();
136 auto y1 = m_P.front() - level;
137 for (size_t i = 1; i < m_P.size(); ++i) {
138 auto y = m_P[i] - level;
139 if (y == 0.0) {
140 rs.emplace_back(x[i]);
141 } else if (y1 * y < 0.0) {
142 rs.emplace_back((-x[i - 1] * y + x[i] * y1) / (y1 - y));
143 }
144 y1 = y;
145 }
146 return rs;
147}
148
150double SimpleChebfun::integrate() const { return m_base->integrate(m_P); }
151
155 auto &x = xPoints();
156 for (size_t i = 0; i < x.size(); ++i) {
157 m_P[i] += fun(x[i]);
158 }
159 m_A.clear();
160 return *this;
161}
162
163} // namespace Mantid::CurveFitting::Functions
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
The ChebfunBase class provides a base for function approximation with Chebyshev polynomials.
Definition: ChebfunBase.h:66
SimpleChebfun : approximates smooth 1d functions and provides methods to manipulate them.
Definition: SimpleChebfun.h:21
SimpleChebfun(size_t n, ChebfunFunctionType fun, double start, double end)
Constructor.
std::vector< double > roughRoots(double level=0.0) const
Get rough estimates of the roots.
SimpleChebfun derivative() const
Create a derivative of this function.
ChebfunBase_sptr m_base
Underlying base that does actual job.
Definition: SimpleChebfun.h:74
double accuracy() const
Get the accuracy of the approximation.
std::vector< double > m_P
Function values at the chebfun x-points.
Definition: SimpleChebfun.h:76
SimpleChebfun integral() const
Create an integral of this function.
SimpleChebfun & operator+=(const ChebfunFunctionType &fun)
Add a C++ function to the function.
std::vector< double > m_A
Chebyshev expansion coefficients.
Definition: SimpleChebfun.h:78
const std::vector< double > & xPoints() const
Get a reference to the x-points.
Definition: SimpleChebfun.h:46
bool m_badFit
Set in a case of a bad fit.
Definition: SimpleChebfun.h:81
double integrate() const
Integrate the function on its interval.
double operator()(double x) const
Evaluate the function.
std::vector< double > linspace(size_t n) const
Create a vector of x values linearly spaced on the approximation interval.
const std::vector< double > & coeffs() const
Get a reference to the Chebyshev expansion coefficients.
std::shared_ptr< ChebfunBase > ChebfunBase_sptr
Definition: ChebfunBase.h:174
std::function< double(double)> ChebfunFunctionType
Type of the approximated function.
Definition: ChebfunBase.h:26
STL namespace.