19#include <nlohmann/json.hpp>
20using json = nlohmann::json;
37template<
typename Scalar =
double>
57 : _strategy(strategy), _polyDegree(polynomialDegree), _windowSize(windowSize), _incrementalLSQ(polynomialDegree)
67 INS_ASSERT_USER_ERROR(windowSize > _polyDegree,
"The window size needs to be greater than the polynomial degree.");
69 while (windowSize < _windowSize)
75 _windowSize = windowSize;
76 _data.resize(windowSize);
83 INS_ASSERT_USER_ERROR(polynomialDegree < _windowSize,
"The polynomial degree needs to be smaller than the window size.");
84 _polyDegree = polynomialDegree;
86 _incrementalLSQ.setPolynomialDegree(polynomialDegree);
103 void push_back(
const std::pair<Scalar, Scalar>& dataPoint)
105 push_back(dataPoint.first, dataPoint.second);
113 if (!_data.empty() && _data.back().first == x)
117 _incrementalLSQ.removeDataPoint(_data.back().first, _data.back().second);
118 _incrementalLSQ.addDataPoint(x, y);
120 _data.back().second = y;
125 if (_data.full()) { pop_front(); }
129 _incrementalLSQ.addDataPoint(x, y);
132 _data.push_back(std::make_pair(x, y));
138 _incrementalLSQ.reset();
145 auto prepareDataVectors = [&]() {
146 auto n =
static_cast<int>(_data.size());
147 Eigen::VectorX<Scalar> x = Eigen::VectorX<Scalar>(n);
148 Eigen::VectorX<Scalar> y = Eigen::VectorX<Scalar>(n);
150 for (
size_t i = 0; i < _data.size(); i++)
152 x(
static_cast<int>(i)) = _data.at(i).first;
153 y(
static_cast<int>(i)) = _data.at(i).second;
156 return std::make_pair(x, y);
162 return { _incrementalLSQ.calcCoefficients() };
165 auto [x, y] = prepareDataVectors();
170 auto [x, y] = prepareDataVectors();
175 auto [x, y] = prepareDataVectors();
180 auto [x, y] = prepareDataVectors();
186 return { Eigen::VectorX<Scalar>() };
192 return _data.size() == _windowSize;
196 [[nodiscard]]
bool empty()
const {
return _data.empty(); }
205 size_t _polyDegree = 2;
207 size_t _windowSize = 10;
216 if (_data.
empty()) {
return; }
218 auto [x, y] = _data.
front();
236template<
typename Scalar =
double>
240 {
"strategy", obj._strategy },
241 {
"polyDegree", obj._polyDegree },
242 {
"windowSize", obj._windowSize },
249template<
typename Scalar =
double>
252 if (j.contains(
"strategy"))
254 j.at(
"strategy").get_to(obj._strategy);
256 if (j.contains(
"polyDegree"))
258 j.at(
"polyDegree").get_to(obj._polyDegree);
259 obj._incrementalLSQ.setPolynomialDegree(obj._polyDegree);
261 if (j.contains(
"windowSize"))
263 j.at(
"windowSize").get_to(obj._windowSize);
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Bidiagonal Divide and Conquer SVD Curve Fit.
Complete Orthogonal Decomposition Curve Fit.
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
Incremental Least Squares Curve Fit.
static Eigen::VectorX< Scalar > calcCoefficients(const Eigen::MatrixBase< DerivedX > &x, const Eigen::MatrixBase< DerivedY > &y, size_t polynomialDegree=2)
Calculates the polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
Definition BDCSVD.hpp:40
static Eigen::VectorX< Scalar > calcCoefficients(const Eigen::MatrixBase< DerivedX > &x, const Eigen::MatrixBase< DerivedY > &y, size_t polynomialDegree=2)
Calculates the polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
Definition COD.hpp:40
static Eigen::VectorX< Scalar > calcCoefficients(const Eigen::MatrixBase< DerivedX > &x, const Eigen::MatrixBase< DerivedY > &y, size_t polynomialDegree=2)
Calculates the polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
Definition HouseholderQr.hpp:39
Incremental Least Squares Curve Fitting.
Definition IncrementalLeastSquares.hpp:30
void removeDataPoint(const Scalar &x, const Scalar &y)
Removes a data point from the polynomial fit.
Definition IncrementalLeastSquares.hpp:71
static Eigen::VectorX< Scalar > calcCoefficients(const Eigen::MatrixBase< DerivedX > &x, const Eigen::MatrixBase< DerivedY > &y, size_t polynomialDegree=2)
Calculates the polynomial coefficients in order a0 + a1 * x + a2 * x^2 + ...
Definition LeastSquares.hpp:40
Polynomial Curve Fitting.
Definition PolynomialRegressor.hpp:39
PolynomialRegressor(size_t polynomialDegree, size_t windowSize, Strategy strategy=Strategy::HouseholderQR)
Constructor.
Definition PolynomialRegressor.hpp:56
const ScrollingBuffer< std::pair< Scalar, Scalar > > & data() const
Gets the underlying buffer.
Definition PolynomialRegressor.hpp:199
bool windowSizeReached() const
Checks if the amount of data points equals the window size.
Definition PolynomialRegressor.hpp:190
bool empty() const
Checks if the container has no elements.
Definition PolynomialRegressor.hpp:196
void push_back(const Scalar &x, const Scalar &y)
Add a data point to the polynomial.
Definition PolynomialRegressor.hpp:111
void setStrategy(Strategy strategy)
Set the strategy for the fit and resets the data.
Definition PolynomialRegressor.hpp:93
void setWindowSize(size_t windowSize)
Sets the amount of points used for the fit (sliding window)
Definition PolynomialRegressor.hpp:65
void setPolynomialDegree(size_t polynomialDegree)
Set the Polynomial Degree and resets the data.
Definition PolynomialRegressor.hpp:81
void reset()
Reset the polynomial coefficients and saved data.
Definition PolynomialRegressor.hpp:136
Polynomial< Scalar > calcPolynomial() const
Calculates the polynomial.
Definition PolynomialRegressor.hpp:143
void push_back(const std::pair< Scalar, Scalar > &dataPoint)
Add a data point to the polynomial.
Definition PolynomialRegressor.hpp:103
Strategy
Possible Fit strategies.
Definition PolynomialRegressor.hpp:43
@ BDCSVD
Bidiagonal Divide and Conquer SVD.
@ IncrementalLeastSquares
Incremental Least Squares (only polynomials of order <= 2)
@ COUNT
Amount of items in the enum.
@ HouseholderQR
Householder QR decomposition.
@ COD
Complete Orthogonal Decomposition.
@ LeastSquares
Least Squares (bas if even mildly ill-conditioned)
Polynomial.
Definition Polynomial.hpp:26