#ifndef _LINEAR_FIT_STUB_ #define _LINEAR_FIT_STUB_ #include #include #include #include #include #include "base_data.h" struct linear_fit { private: const size_t count_; double a_,b_,t_[4]; std::deque x_,y_; //²»ÊÊÓà //linear_fit(const linear_fit&)=delete; //linear_fit(const linear_fit&); void start_fit() { for(auto ix=x_.begin(), iy=y_.begin(); ix!=x_.end(); ++ix,++iy) { t_[0] += *ix * *ix; t_[1] += *ix; t_[2] += *ix * *iy; t_[3] += *iy; } double t1=t_[0]*count_ - t_[1]*t_[1]; a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ; b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ; //debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_); } public: linear_fit(int count) :count_(count) { reset(); } void reset() { a_=b_=0; memset(&t_[0],0,sizeof(t_)); x_.resize(0); y_.resize(0); } template bool start(iteratorx xi,iteratory yi,size_t count) { reset(); std::copy_n(xi,count,std::back_inserter(x_)); std::copy_n(yi,count,std::back_inserter(y_)); if(count count_) { x_.pop_front(); y_.pop_front(); } start_fit(); return true; } bool push(double x,double y) { //debug_print_syslog(0,"[framework push]count:%d, x:%.2f,y:%.2f",count_,x,y); x_.push_back(x); y_.push_back(y); if(x_.size() < count_) { return false; //throw logic_exception(...) } else if(x_.size()==count_) { start_fit(); return true; } t_[0] += x * x - x_.front()*x_.front(); t_[1] += x - x_.front(); t_[2] += x * y - x_.front() * y_.front(); t_[3] += y - y_.front(); x_.pop_front(); y_.pop_front(); double t1=t_[0]*count_ - t_[1]*t_[1]; a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ; b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ; //debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_); return true; } double getY(double x)const { return a_ * x + b_; } double getY(uint64_t x) const { return a_ * x + b_; } double getK()const { return a_; } }; struct comp_linear_fit { std::map m_fit; comp_linear_fit(const int* begin,const int* end) { for(;begin!=end;++begin) { m_fit.insert(std::make_pair(*begin,new linear_fit(*begin))); } } ~comp_linear_fit() { for_each(m_fit.begin(),m_fit.end(),[&](std::pair it){delete it.second;}); } double getY(int num_point,uint64_t time)const { auto it=m_fit.find(num_point); if(it==m_fit.end()) { //throw return 0.0; } return it->second->getY(time); } double getK(int num_point)const { auto it=m_fit.find(num_point); if(it==m_fit.end()) { //throw return DBL_MAX; } return it->second->getK(); } void push(uint64_t time, double x) { for_each(m_fit.begin(),m_fit.end(),[&](std::pair it){it.second->push(time,x);}); } }; #endif