sablib
Loading...
Searching...
No Matches
arpls.cpp
Go to the documentation of this file.
1
6
7#include <cmath>
8#include <limits>
9
10#include "arpls.h"
11
12namespace sablib {
13
14//
15// Implementation of BaselineArPLS() function
16//
17const std::vector<double> BaselineArPLS(
18 std::vector<double> & y, const double lambda, const unsigned int s,
19 const unsigned int loop, const double eps
20)
21{
22 if(y.size() == 0) {
23 throw std::invalid_argument("BaselineArPLS(): the length of y is zero.");
24 }
25
26 if(lambda <= 0) {
27 throw std::invalid_argument("BaselineArPLS(): non-positive lambda value is given.");
28 }
29
30 if(s == 0 || s > 3) {
31 throw std::invalid_argument("BaselineArPLS(): s must be 1, 2 or 3.");
32 }
33
34 if(loop == 0) {
35 throw std::invalid_argument("BaselineArPLS(): loop is zero.");
36 }
37
38 if(eps <= 0) {
39 throw std::invalid_argument("BaselineArPLS(): non-positive eps value is given.");
40 }
41
42 size_t m = y.size();
43 Eigen::VectorXd yy, w, wt, z, d, tmp;
44 Eigen::SparseMatrix<double> I, D, lambdaDTD;
45 double mean, sd;
46 Eigen::Index ct;
47
48 const double overflow = std::log(std::numeric_limits<double>::max()) / 2;
49
50 yy = Eigen::VectorXd::Map(y.data(), m);
51
52 w.setOnes(m);
53
54 I.resize(m, m);
55 I.setIdentity();
56 D = Diff(I, s);
57 lambdaDTD = lambda * (D.transpose() * D);
58
59 for(unsigned int i = 0; i < loop; i++) {
60 z = Whittaker(yy, w, lambdaDTD);
61
62 d = yy - z;
63
64 ct = (d.array() < 0).count();
65 mean = (d.array() < 0).select(d, 0).sum() / ct;
66 sd = std::sqrt((d.array() < 0).select((d.array() - mean).matrix(), 0).squaredNorm() / (ct - 1));
67
68 tmp = ((d.array() + mean - 2 * sd) / sd).matrix();
69 tmp = (tmp.array() >= overflow).select(0, (1.0 / (1 + (2 * tmp).array().exp())).matrix());
70
71 wt = (d.array() >= 0).select(tmp, 1);
72
73 if ((w - wt).norm() / w.norm() < eps) {
74 break;
75 }
76
77 w = wt;
78 }
79
80 std::vector<double> result(z.size());
81
82 Eigen::VectorXd::Map(result.data(), result.size()) = z;
83
84 return result;
85}
86
87}; // namespace sablib
const std::vector< double > BaselineArPLS(std::vector< double > &y, const double lambda, const unsigned int s, const unsigned int loop, const double eps)
Performs baseline estimation using asymmetrically reweighted Penalized Least Squares(arPLS).
Definition arpls.cpp:17
Baseline estimation using asymmetrically reweighted Penalized Least Squares(arPLS).
const Derived::PlainObject Diff(const Eigen::MatrixBase< Derived > &m0, const int n=1, const Dir dir=Dir::RowWise)
Calculates the n-th discrete difference along the given axis.
Definition diff.h:32
const std::vector< double > Whittaker(const std::vector< double > &y, const std::vector< double > &w, const double lambda, const unsigned int s)
Performs Whittaker smoothing (std::vector<double> version, with weights).
Definition whittaker.cpp:14