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
26 throw std::invalid_argument(
"BaselineBackcor(): the length of y is zero.");
30 throw std::invalid_argument(
"BaselineBackcor(): polyorder is zero.");
34 throw std::invalid_argument(
"BaselineBackcor(): non-positive s value is given.");
37 if(alpha <= 0 || 1 < alpha) {
38 throw std::invalid_argument(
"BaselineBackcor(): alpha must be between 0 and 1.");
42 throw std::invalid_argument(
"BaselineBackcor(): loop is zero.");
46 throw std::invalid_argument(
"BaselineBackcor(): non-positive eps value is given.");
49 Eigen::VectorXd yy = Eigen::VectorXd::Map(y.data(), y.size());
50 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(y.size(), 0, 1);
52 Eigen::LDLT<Eigen::MatrixXd> ldltV = (V.transpose() * V).ldlt();
54 std::function<double(
double)> derivative;
58 derivative = [&](
const double xx) {
71 derivative = [&](
const double xx) {
81 derivative = [&](
const double xx) {
82 if(std::fabs(xx) < s) {
91 derivative = [&](
const double xx) {
101 derivative = [&](
const double xx) {
103 return -s * s * s / (2 * xx * xx);
106 return s * s * s / (2 * xx * xx);
114 derivative = [&](
const double xx) {
119 return -s * s * s / (2 * xx * xx);
125 Eigen::VectorXd coeff = ldltV.solve(V.transpose() * yy);
126 Eigen::VectorXd z =
PolyVal(coeff, V);
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));
137 if((z - z_old).norm() / z_old.norm() < eps) {
142 std::vector<double> result(z.size());
143 Eigen::VectorXd::Map(result.data(), result.size()) = z;
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...
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.