22 const std::vector<double> & y,
const unsigned int polyorder,
23 double peak_ratio,
const double alpha,
const unsigned int loop,
const double eps,
24 const unsigned int loop_legend,
const double eps_legend,
const double eps_s
28 throw std::invalid_argument(
"BaselineGoldindec(): the length of y is zero.");
32 throw std::invalid_argument(
"BaselineGoldindec(): polyorder is zero.");
35 if(peak_ratio <= 0 || 1 < peak_ratio) {
36 throw std::invalid_argument(
"BaselineGoldindec(): peak_ratio must be between 0 and 1.");
39 if(alpha <= 0 || 1 < alpha) {
40 throw std::invalid_argument(
"BaselineGoldindec(): alpha must be between 0 and 1.");
44 throw std::invalid_argument(
"BaselineGoldindec(): loop is zero.");
48 throw std::invalid_argument(
"BaselineGoldindec(): non-positive eps value is given.");
51 if(loop_legend == 0) {
52 throw std::invalid_argument(
"BaselineGoldindec(): loop_legend is zero.");
56 throw std::invalid_argument(
"BaselineGoldindec(): non-positive eps_legend value is given.");
60 throw std::invalid_argument(
"BaselineGoldindec(): non-positive eps_s value is given.");
63 Eigen::VectorXd yy = Eigen::VectorXd::Map(y.data(), y.size());
64 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(y.size(), 0, 1);
66 Eigen::LDLT<Eigen::MatrixXd> ldltV = (V.transpose() * V).ldlt();
70 + 11.2358 * peak_ratio
71 - 39.7064 * peak_ratio * peak_ratio
72 + 92.3583 * peak_ratio * peak_ratio * peak_ratio;
73 double s = a + 0.618 * (b - a), s_old = s;
75 auto derivative = [&](
const double xx) {
80 return -s * s * s / (2 * xx * xx);
84 Eigen::VectorXd coeff = ldltV.solve(V.transpose() * yy);
85 Eigen::VectorXd z =
PolyVal(coeff, V);
87 for(
unsigned int i = 0; i < loop; i++) {
89 for(
unsigned int j = 0; j < loop_legend; j++) {
90 Eigen::VectorXd z_old = z;
92 Eigen::VectorXd e = yy - z_old;
93 Eigen::VectorXd d = -e + alpha * e.unaryExpr(derivative);
94 coeff = ldltV.solve(V.transpose() * (yy + d));
97 if((z - z_old).norm() / z_old.norm() < eps_legend) {
102 double up_down_ratio = (double)(yy.array() >= z.array()).count() / (double)(yy.array() < z.array()).count();
103 double diff = up_down_ratio - rud;
108 else if(diff < -eps) {
115 s = a + 0.618 * (b - a);
119 if(std::fabs(s - s_old) < eps_s) {
126 std::vector<double> result(z.size());
127 Eigen::VectorXd::Map(result.data(), result.size()) = z;
const std::vector< double > BaselineGoldindec(const std::vector< double > &y, const unsigned int polyorder, double peak_ratio, const double alpha, const unsigned int loop, const double eps, const unsigned int loop_legend, const double eps_legend, const double eps_s)
Performs baseline estimation using the Goldindec algorithm.
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.