sablib
Loading...
Searching...
No Matches
backcor.cpp
Go to the documentation of this file.
1
6
7#include <cmath>
8#include <functional>
9
10#include "../misc/polyfit.h"
11
12#include "backcor.h"
13
14namespace sablib {
15
16//
17// Implementation of BaselineBackcor() function.
18//
19const std::vector<double>
21 const std::vector<double> & y, const unsigned int polyorder, const BackcorFunc func,
22 const double s, const double alpha, const unsigned int loop, const double eps
23)
24{
25 if(y.size() == 0) {
26 throw std::invalid_argument("BaselineBackcor(): the length of y is zero.");
27 }
28
29 if(polyorder == 0) {
30 throw std::invalid_argument("BaselineBackcor(): polyorder is zero.");
31 }
32
33 if(s <= 0) {
34 throw std::invalid_argument("BaselineBackcor(): non-positive s value is given.");
35 }
36
37 if(alpha <= 0 || 1 < alpha) {
38 throw std::invalid_argument("BaselineBackcor(): alpha must be between 0 and 1.");
39 }
40
41 if(loop == 0) {
42 throw std::invalid_argument("BaselineBackcor(): loop is zero.");
43 }
44
45 if(eps <= 0) {
46 throw std::invalid_argument("BaselineBackcor(): non-positive eps value is given.");
47 }
48
49 Eigen::VectorXd yy = Eigen::VectorXd::Map(y.data(), y.size());
50 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(y.size(), 0, 1);
51 Eigen::MatrixXd V = Vandermonde(x, polyorder);
52 Eigen::LDLT<Eigen::MatrixXd> ldltV = (V.transpose() * V).ldlt();
53
54 std::function<double(double)> derivative;
55
56 switch(func) {
58 derivative = [&](const double xx) {
59 if(xx <= -s) {
60 return -2 * s;
61 }
62 else if(s <= xx) {
63 return 2 * s;
64 }
65 else {
66 return 2 * xx;
67 }
68 };
69 break;
71 derivative = [&](const double xx) {
72 if(xx < s) {
73 return 2 * xx;
74 }
75 else {
76 return 2 * s;
77 }
78 };
79 break;
81 derivative = [&](const double xx) {
82 if(std::fabs(xx) < s) {
83 return 2 * xx;
84 }
85 else {
86 return 0.0;
87 }
88 };
89 break;
91 derivative = [&](const double xx) {
92 if(xx < s) {
93 return 2 * xx;
94 }
95 else {
96 return 0.0;
97 }
98 };
99 break;
101 derivative = [&](const double xx) {
102 if(s <= xx) {
103 return -s * s * s / (2 * xx * xx);
104 }
105 else if(xx <= s) {
106 return s * s * s / (2 * xx * xx);
107 }
108 else {
109 return 2 * xx;
110 }
111 };
112 break;
114 derivative = [&](const double xx) {
115 if(xx < s) {
116 return 2 * xx;
117 }
118 else {
119 return -s * s * s / (2 * xx * xx);
120 }
121 };
122 break;
123 }
124
125 Eigen::VectorXd coeff = ldltV.solve(V.transpose() * yy);
126 Eigen::VectorXd z = PolyVal(coeff, V);
127
128 // LEGEND algorithm
129 for(unsigned int i = 0; i < loop; i++) {
130 Eigen::VectorXd z_old = z;
131 Eigen::VectorXd e = yy - z_old;
132 Eigen::VectorXd d = -e + alpha * e.unaryExpr(derivative);
133 Eigen::VectorXd coeff_new = ldltV.solve(V.transpose() * (yy + d));
134
135 z = PolyVal(coeff_new, V);
136
137 if((z - z_old).norm() / z_old.norm() < eps) {
138 break;
139 }
140 }
141
142 std::vector<double> result(z.size());
143 Eigen::VectorXd::Map(result.data(), result.size()) = z;
144
145 return result;
146}
147
148}; // namespace sablib
const std::vector< double > BaselineBackcor(const std::vector< double > &y, const unsigned int polyorder, const BackcorFunc func, const double s, const double alpha, const unsigned int loop, const double eps)
Performs baseline estimation using iterative polynomial fitting with a non-quadratic cost function (B...
Definition backcor.cpp:20
Baseline estimation using iterative polynomial fitting with a non-quadratic cost function(Backcor alg...
BackcorFunc
Cost function types for the Backcor algorithm.
Definition backcor.h:26
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