sablib
Loading...
Searching...
No Matches
imodpoly.cpp
Go to the documentation of this file.
1
6
7#include <cmath>
8#include <limits>
9
10#include "../misc/polyfit.h"
11
12#include "imodpoly.h"
13
14namespace sablib {
15
16//
17// Implementation of BaselineIModPoly() function
18//
19const std::vector<double> BaselineIModPoly(
20 const std::vector<double> & y, const unsigned int polyorder, const double k, const unsigned int loop, const double eps
21)
22{
23 if(y.size() == 0) {
24 throw std::invalid_argument("BaselineIModPoly(): the length of y is zero.");
25 }
26
27 if(polyorder == 0) {
28 throw std::invalid_argument("BaselineIModPoly(): polyorder is zero.");
29 }
30
31 if(k <= 0) {
32 throw std::invalid_argument("BaselineIModPoly(): non-positive k value is given.");
33 }
34
35 if(loop == 0) {
36 throw std::invalid_argument("BaselineIModPoly(): loop is zero.");
37 }
38
39 if(eps <= 0) {
40 throw std::invalid_argument("BaselineIModPoly(): non-positive eps value is given.");
41 }
42
43 Eigen::VectorXd yy = Eigen::VectorXd::Map(y.data(), y.size());
44 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(y.size(), 0, 1);
45 Eigen::MatrixXd V = Vandermonde(x, polyorder);
46 Eigen::LDLT<Eigen::MatrixXd> ldltV = (V.transpose() * V).ldlt();
47 Eigen::VectorXd y_old = yy, y_new;
48 double sd_old = std::numeric_limits<double>::infinity();
49
50 for(unsigned int i = 0; i < loop; i++) {
51 y_new = PolyVal(ldltV.solve(V.transpose() * y_old), V);
52
53 Eigen::VectorXd r = y_new - y_old;
54 double mean = r.mean();
55 double sd = std::sqrt((r.array() - mean).square().sum() / r.size());
56
57 if(std::fabs(sd - sd_old) < eps) {
58 break;
59 }
60
61 y_old = (y_old.array() > (y_new.array() + k * sd)).select(y_new, y_old);
62 sd_old = sd;
63 }
64
65 std::vector<double> result(y.size());
66 Eigen::VectorXd::Map(result.data(), result.size()) = y_new;
67
68 return result;
69}
70
71}; // namespace sablib
const std::vector< double > BaselineIModPoly(const std::vector< double > &y, const unsigned int polyorder, const double k, const unsigned int loop, const double eps)
Estimates the baseline using the Improved Modified Polynomial (IModPoly) method.
Definition imodpoly.cpp:19
Baseline estimation using Improved Modified Polynomial(IModPoly) method.
Polynomial fitting using the least squares method (Gauss-Newton for linear models) and evaluating pol...
const Derived::PlainObject PolyVal(const Eigen::MatrixBase< Derived > &coeff, const Eigen::MatrixX< typename Derived::PlainObject::Scalar > &V)
Evaluates the polynomial at specified points using a pre-calculated Vandermonde matrix.
Definition polyfit.h:122
const Eigen::MatrixX< typename Derived::PlainObject::Scalar > Vandermonde(const Eigen::MatrixBase< Derived > &x, const unsigned int polyorder)
Generates a Vandermonde matrix for a given vector and polynomial order.
Definition polyfit.h:25