36 const arma::vec &abscissa,
40 const arma::uword poly_order,
41 const arma::uword max_it,
42 const double threshold)
45 throw std::invalid_argument(
"Polynomial order must be 1 (linear) or greater.");
46 if (threshold >= 1 || threshold <= 0)
47 throw std::invalid_argument(
"Threshold value must be between 0 and 1.");
48 if (spectrum.n_rows != abscissa.n_rows)
49 throw std::invalid_argument(
"Spectrum and abscissa must be the same size.");
52 bool no_max_it = (max_it == 0);
63 double prev_dev = dev;
66 arma::uvec non_peak_ind =
NonPeakInd(spectrum, dev);
67 arma::vec new_abscissa = abscissa(non_peak_ind);
69 arma::vec prev_fit = spectrum(non_peak_ind);;
73 arma::uword rows = new_abscissa.n_rows;
83 fit += dev * arma::ones(rows);
85 arma::uvec ind = arma::find (prev_fit < fit);
86 fit(ind) = prev_fit(ind);
90 }
while (err > threshold && (no_max_it || i <= max_it));
93 corrected = spectrum - baseline;
105 using namespace arma;
106 arma::vec R = spectrum - fit;
107 double R_avg = mean(R);
108 arma::vec centered = R - R_avg*arma::ones(R.n_rows);
109 centered = arma::pow(centered, 2.0);
110 return std::sqrt(sum(centered)/centered.n_rows);
121 using namespace arma;
122 arma::vec SUM = spectrum + dev * arma::ones(spectrum.n_rows);
123 return arma::find(spectrum <= SUM);
134 arma::vec y = coefs(0) + x*coefs(1);
136 if (coefs.n_rows > 1){
137 for (arma::uword i = 2; i < coefs.n_rows; ++i)
138 y += coefs(i) * arma::pow(x, i);
153 return arma::solve(R, Q.t()) * y;
164 arma::mat X(x.n_rows, poly_order + 1);
165 X.col(0) = arma::ones(x.n_rows);
167 for (arma::uword i = 2; i < X.n_cols; ++i)
168 X.col(i) = arma::pow(x, i);
180 return std::abs( (dev - prev_dev) / dev );
187 std::map<std::string, double> &stats)
191 double y_bar = arma::mean(y);
196 arma::vec residuals = y - fit;
198 arma::vec centered = y - y_bar;
199 double residual_sumsq = arma::as_scalar(arma::sum(arma::pow(residuals, 2.0)));
200 double total_sumsq = arma::as_scalar(arma::sum(arma::pow(centered, 2.0)));
201 double regression_sumsq = arma::as_scalar(arma::sum(arma::pow((fit - y_bar), 2.0)));
202 double R_squared = 1.0 - (residual_sumsq/total_sumsq);
203 double adj_R_squared = 1 - (1 - R_squared)*(n - 1)/dof;
205 arma::mat var_hat = (residual_sumsq / dof) * inv(X.t() * X);
207 std::string param_name;
208 for(arma::uword i = 0; i < coefs.n_rows; ++i){
209 param_name =
"a" + std::to_string(i);
210 stats[param_name] = coefs(i);
211 stats[
"s_" + param_name] = var_hat(i,i);
213 stats[
"R squared"] = R_squared;
214 stats[
"Adjusted R squared"] = adj_R_squared;
215 stats[
"s(y)"] = std::sqrt(regression_sumsq / n);
216 stats[
"F"] =(regression_sumsq) / (residual_sumsq/dof);
217 stats[
"Degrees of Freedom"] = dof;
218 stats[
"SSreg"] = regression_sumsq;
219 stats[
"SSres"] = residual_sumsq;
220 stats[
"Norm of residuals"] = std::sqrt(residual_sumsq);
234 arma::vec log_x = arma::log(x);
235 arma::vec log_y = arma::log(y);
238 fit = arma::exp(fit);
239 stats[
"A"] = std::exp(stats[
"a_0"] - (0.5*stats[
"a_1"]/stats[
"a_2"]));
240 stats[
"b"] = -0.5 * stats[
"a_1"] / stats[
"a_2"];
241 if (stats[
"a_2"] >= 0){
242 return arma::zeros(3);
244 stats[
"c"] = std::sqrt(-1.0/(2.0*stats[
"a_2"]));
245 stats[
"s_A"] = stats[
"A"] * std::sqrt(std::pow((0.5*std::sqrt( std::pow(stats[
"s_a_1"]/stats[
"a_1"], 2.0)) +
246 std::pow(stats[
"s_a_2"]/stats[
"a_2"], 2.0)), 2.0)
247 + std::pow(stats[
"s_a_0"], 2.0));
248 stats[
"s_b"] = 0.5 * std::sqrt(std::pow(stats[
"s_a_1"]/stats[
"s_a"], 2.0)
249 + std::pow(stats[
"s_a_2"]/stats[
"a_2"], 2.0));
251 stats[
"s_c"] = std::sqrt(0.5)*0.5*stats[
"s_a_2"]/stats[
"a_2"];
double CalcErr(const double &dev, const double &prev_dev)
Vespucci::Math::LinLeastSq::CalcErr Calculate the error criterion.
VESPUCCI_EXPORT arma::uword IModPoly(const arma::vec &spectrum, const arma::vec &abscissa, arma::vec &baseline, arma::vec &corrected, double &err, const arma::uword poly_order, const arma::uword max_it, const double threshold)
Vespucci::Math::LinLeastSq::IModPoly Perform the Vancouver Raman Algorithm to correct baseline...
VESPUCCI_EXPORT arma::vec FitGaussian(const arma::vec &x, const arma::vec &y, arma::vec &fit, std::map< std::string, double > &stats)
Vespucci::Math::LinLeastSq::FitGaussian.
arma::uvec NonPeakInd(const arma::vec &spectrum, const double dev)
Vespucci::Math::LinLeastSq::NonPeakInd.
arma::vec CalcPoly(const arma::vec &coefs, const arma::vec &x)
Vespucci::Math::LinLeastSq::CalcPoly Calculate the values of a polynomial.
double CalcDev(const arma::vec &spectrum, const arma::vec &fit)
Vespucci::Math::LinLeastSq::CalcDev.
VESPUCCI_EXPORT arma::mat Vandermonde(const arma::vec &x, const int poly_order)
Vespucci::Math::LinLeastSq::Vandermonde Build a Vandermonde matrix for OLS.
VESPUCCI_EXPORT arma::mat OrdinaryLeastSquares(const arma::mat &X, const arma::mat &y)
Vespucci::Math::LinLeastSq::OrdinaryLeastSquares Perform Squares.