#include "LSM.h" namespace DAA { LSM::LSM(const vector& X, const vector& Y) : vX(X), vY(Y) {} LSM::~LSM() {} void LSM::reset(const vector& X, const vector& Y) { vX = arma::vec(X); vY = arma::vec(Y); polyfit_init(); } void LSM::polyfit_init() { int m = vY.size(); double Tss = m * arma::var(vY); double r2a_max = 0.4; for (int i = 0; i < max_orders; i++) { arma::vec res = arma::polyfit(vX, vY, i + 1); res.for_each([](arma::vec::elem_type& val) { val = limit_precision(val); }); pnn[i] = res; fY = arma::polyval(pnn[i], vX); double Rssi = arma::accu(pow((fY - vY), 2)); double r2i = 1 - (Rssi / Tss); r2a[i] = limit_precision(1 - (1 - r2i) * (m - 1) / (m - 2)); if (r2a[i] > r2a_max) { order_best = i + 1; r2a_max = 1; } } is_init = true; } vector LSM::polyfit(int orders) { if (order_now != orders) { pn = arma::polyfit(vX, vY, orders); order_now = orders; } return arma::conv_to>::from(pn); } vector> LSM::polyfit() { if (!is_init) { polyfit_init(); } vector> pnn_v; for (int i = 0; i < max_orders; i++) { pnn_v.push_back(arma::conv_to>::from(pnn[i])); } return pnn_v; } vector LSM::get_r2a() { if (!is_init) { polyfit_init(); } return vector(r2a.begin(), r2a.end()); } vector LSM::polyval(int orders) { if (order_now != orders) { pn = arma::polyfit(vX, vY, orders); order_now = orders; } fY = arma::polyval(pn, vX); return arma::conv_to>::from(fY); } double LSM::polyval(double x, int orders) { if (order_now != orders) { pn = arma::polyfit(vX, vY, orders); order_now = orders; } double res = 0; for (int i = 0; i < order_now + 1; i++) { res += std::pow(x, orders - i) * pn[i]; } return res; } bool LSM::is_legal() { return vX.size() == vX.size() && !vX.empty(); } double LSM::cor() { if (abs(cor_coef) > 1) { arma::vec res = arma::cor(vX, vY); cor_coef = res[0]; } return cor_coef; } int LSM::get_order_best() { if (!is_init) { polyfit_init(); } return this->order_best; } }; // namespace DAA