180 lines
5.8 KiB
C++
180 lines
5.8 KiB
C++
|
|
#include <eqpalg/stat_tools/polyfit_stat.h>
|
||
|
|
#include <mix_cc/algorithm/polynomialfit_gsl.h>
|
||
|
|
#include <mix_cc/algorithm/polynomialfit_util.h>
|
||
|
|
|
||
|
|
#include <mix_cc/exception.h>
|
||
|
|
|
||
|
|
PolyfitStat::PolyfitStat(std::string ruleId, int max_fit_count)
|
||
|
|
: rule_id_(ruleId), max_fit_count_(max_fit_count) {
|
||
|
|
logger_ = std::make_unique<LOG>("PolyfitStat:" + rule_id_, AUTO_CATCH_PID);
|
||
|
|
}
|
||
|
|
|
||
|
|
PolyfitStat::~PolyfitStat() {}
|
||
|
|
|
||
|
|
int PolyfitStat::set_workingset_dim(int dim) {
|
||
|
|
if (dim == 2 || dim == 3) {
|
||
|
|
this->dims_ = dim;
|
||
|
|
} else {
|
||
|
|
throw runtime_error("polyfit_stat: dim not legal");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Saved value to DB2
|
||
|
|
int PolyfitStat::save_data(double x1, double x2, double y) {
|
||
|
|
logger_->Debug() << "x1:" << x1 << " x2:" << x2 << " y:" << y << std::endl;
|
||
|
|
try {
|
||
|
|
if (sample_3d_.size <= max_fit_count_) {
|
||
|
|
sample_3d_.x1_.emplace_back(x1);
|
||
|
|
sample_3d_.x2_.emplace_back(x2);
|
||
|
|
sample_3d_.y_.emplace_back(y);
|
||
|
|
db_com_.insert_value(
|
||
|
|
"T_STA_RULE_POLYFIT",
|
||
|
|
{{"RULEID", rule_id_},
|
||
|
|
{"SAMPLE_DATE", mix_cc::mix_time_t(time(0)).to_db2_str()},
|
||
|
|
{"X1", std::to_string(x1)},
|
||
|
|
{"X2", std::to_string(x2)},
|
||
|
|
{"y", std::to_string(y)}});
|
||
|
|
logger_->Debug() << "Insert Count " << sample_3d_.size << "/"
|
||
|
|
<< max_fit_count_ << std::endl;
|
||
|
|
}
|
||
|
|
} catch (const std::exception &e) {
|
||
|
|
logger_->Error() << mix_cc::get_nested_exception(e) << std::endl;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int PolyfitStat::save_data(double x, double y) {
|
||
|
|
logger_->Debug() << "x:" << x << " y:" << y << std::endl;
|
||
|
|
try {
|
||
|
|
if (sample_2d_.size <= max_fit_count_) {
|
||
|
|
sample_2d_.x_.emplace_back(x);
|
||
|
|
sample_2d_.y_.emplace_back(y);
|
||
|
|
db_com_.insert_value(
|
||
|
|
"T_STA_RULE_POLYFIT",
|
||
|
|
{{"RULEID", rule_id_},
|
||
|
|
{"SAMPLE_DATE", mix_cc::mix_time_t(time(0)).to_db2_str()},
|
||
|
|
{"X1", std::to_string(x)},
|
||
|
|
{"X2", std::to_string(0)},
|
||
|
|
{"y", std::to_string(y)}});
|
||
|
|
logger_->Debug() << "Insert Count " << sample_2d_.size << "/"
|
||
|
|
<< max_fit_count_ << std::endl;
|
||
|
|
}
|
||
|
|
} catch (const std::exception &e) {
|
||
|
|
logger_->Error() << mix_cc::get_nested_exception(e) << std::endl;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int PolyfitStat::load() {
|
||
|
|
LOG d("PolyfitStat::LoadXY");
|
||
|
|
logger_->Debug() << "Query Begin" << std::endl;
|
||
|
|
try {
|
||
|
|
auto data = db_com_.query_value("T_STA_RULE_POLYFIT", {},
|
||
|
|
{{"RULEID", "=", rule_id_}},
|
||
|
|
"ORDER BY SAMPLE_DATE");
|
||
|
|
if (!data.empty()) {
|
||
|
|
if (this->dims_ == 3) {
|
||
|
|
|
||
|
|
for (auto x : data) {
|
||
|
|
sample_3d_.x1_.emplace_back(x.at("X1").as_double());
|
||
|
|
sample_3d_.x2_.emplace_back(x.at("X2").as_double());
|
||
|
|
sample_3d_.y_.emplace_back(x.at("Y").as_double());
|
||
|
|
}
|
||
|
|
|
||
|
|
} else if (this->dims_ == 2) {
|
||
|
|
for (auto x : data) {
|
||
|
|
sample_2d_.x_.emplace_back(x.at("X1").as_double());
|
||
|
|
sample_2d_.y_.emplace_back(x.at("Y").as_double());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
logger_->Debug() << "No Data Loaded,Insert Complete " << std::endl;
|
||
|
|
}
|
||
|
|
} catch (std::exception &e) {
|
||
|
|
logger_->Debug() << mix_cc::get_nested_exception(e) << std::endl;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Calc Value if size is fullfilled
|
||
|
|
int PolyfitStat::fit() {
|
||
|
|
if (this->dims_ == 2) {
|
||
|
|
if (sample_2d_.size > 30) {
|
||
|
|
for (auto i = 0; i < sample_2d_.size; i++) {
|
||
|
|
sample_2d_.coeff_ = mix_cc::polynomialfit_gsl(
|
||
|
|
sample_2d_.size, power_index_, sample_2d_.x_, sample_2d_.y_);
|
||
|
|
}
|
||
|
|
sample_2d_.calculated_ = true;
|
||
|
|
}
|
||
|
|
} else if (this->dims_ == 3) {
|
||
|
|
if (sample_3d_.size > 30) {
|
||
|
|
for (auto i = 0; i < sample_3d_.size; i++) {
|
||
|
|
sample_3d_.coeff_ = mix_cc::polynomialfit_gsl(
|
||
|
|
sample_3d_.size, power_index_, sample_3d_.x1_, sample_3d_.x2_,
|
||
|
|
sample_3d_.y_);
|
||
|
|
}
|
||
|
|
sample_3d_.calculated_ = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int PolyfitStat::filter_data() {
|
||
|
|
// this->LoadXY();
|
||
|
|
// this->Fit();
|
||
|
|
// LOG d("PolyfitStat::FilterData");
|
||
|
|
// for (auto i = 0; i < level_count_; ++i) {
|
||
|
|
// if (loaded_sample_data_3d_[i].calculated_)
|
||
|
|
// for (auto j = 0; j < loaded_sample_data_3d_[i].x_.size(); j++) {
|
||
|
|
// auto data = GetY(loaded_sample_data_3d_[i].x_[j], i).value();
|
||
|
|
// if (data * 1.4 < loaded_sample_data_3d_[i].y_[j] ||
|
||
|
|
// data * 0.6 > loaded_sample_data_3d_[i].y_[j]) {
|
||
|
|
// db_com_.Cmd("DELETE FROM T_STA_RULE_POLYFIT WHERE RULEID = '" +
|
||
|
|
// rule_id_ + "' AND LEVEL = '" + std::to_string(i) +
|
||
|
|
// "' AND X = '" +
|
||
|
|
// to_string(loaded_sample_data_3d_[i].x_[j]) +
|
||
|
|
// "' AND Y = '" +
|
||
|
|
// to_string(loaded_sample_data_3d_[i].y_[j])
|
||
|
|
// +
|
||
|
|
// "';");
|
||
|
|
// logger_->Debug() << "Filtered Data X:" <<
|
||
|
|
// loaded_sample_data_3d_[i].x_[j]
|
||
|
|
// << "Y:" << loaded_sample_data_3d_[i].y_[j] <<
|
||
|
|
// std::endl;
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// if coeff is calculated, return dest y, else . return none
|
||
|
|
boost::optional<double> PolyfitStat::get_y(double x1, double x2) {
|
||
|
|
if (dims_ != 3) {
|
||
|
|
throw runtime_error("polyfit dims error");
|
||
|
|
}
|
||
|
|
if (sample_3d_.calculated_) {
|
||
|
|
return mix_cc::get_poly_regression(power_index_, sample_3d_.coeff_, x1, x2);
|
||
|
|
}
|
||
|
|
return boost::none;
|
||
|
|
}
|
||
|
|
|
||
|
|
boost::optional<double> PolyfitStat::get_y(double x) {
|
||
|
|
if (dims_ != 2) {
|
||
|
|
throw runtime_error("polyfit dims error");
|
||
|
|
}
|
||
|
|
if (sample_2d_.calculated_) {
|
||
|
|
return mix_cc::get_poly_regression(power_index_, sample_2d_.coeff_, x);
|
||
|
|
}
|
||
|
|
return boost::none;
|
||
|
|
}
|
||
|
|
|
||
|
|
std::string PolyfitStat::stringify_polyfit() {
|
||
|
|
std::string ret;
|
||
|
|
if (this->dims_ == 3) {
|
||
|
|
ret = mix_cc::get_poly_string3d(power_index_, sample_3d_.coeff_);
|
||
|
|
}
|
||
|
|
if (this->dims_ == 2) {
|
||
|
|
ret = mix_cc::get_poly_string3d(power_index_, sample_2d_.coeff_);
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|