20 const std::vector<double> & y,
const unsigned int polyorder,
const double k,
const unsigned int loop,
const double eps
24 throw std::invalid_argument(
"BaselineIModPoly(): the length of y is zero.");
28 throw std::invalid_argument(
"BaselineIModPoly(): polyorder is zero.");
32 throw std::invalid_argument(
"BaselineIModPoly(): non-positive k value is given.");
36 throw std::invalid_argument(
"BaselineIModPoly(): loop is zero.");
40 throw std::invalid_argument(
"BaselineIModPoly(): non-positive eps value is given.");
43 Eigen::VectorXd yy = Eigen::VectorXd::Map(y.data(), y.size());
44 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(y.size(), 0, 1);
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();
50 for(
unsigned int i = 0; i < loop; i++) {
51 y_new =
PolyVal(ldltV.solve(V.transpose() * y_old), V);
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());
57 if(std::fabs(sd - sd_old) < eps) {
61 y_old = (y_old.array() > (y_new.array() + k * sd)).select(y_new, y_old);
65 std::vector<double> result(y.size());
66 Eigen::VectorXd::Map(result.data(), result.size()) = y_new;
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.
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.
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.