linear_fit.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #ifndef _LINEAR_FIT_STUB_
  2. #define _LINEAR_FIT_STUB_
  3. #include <deque>
  4. #include <algorithm>
  5. #include <string.h>
  6. #include <map>
  7. #include "base_data.h"
  8. struct linear_fit
  9. {
  10. private:
  11. const size_t count_;
  12. double a_,b_,t_[4];
  13. std::deque<double> x_,y_;
  14. //²»ÊÊÓÃ
  15. //linear_fit(const linear_fit&)=delete;
  16. //linear_fit(const linear_fit&);
  17. void start_fit()
  18. {
  19. for(auto ix=x_.begin(), iy=y_.begin(); ix!=x_.end(); ++ix,++iy)
  20. {
  21. t_[0] += *ix * *ix;
  22. t_[1] += *ix;
  23. t_[2] += *ix * *iy;
  24. t_[3] += *iy;
  25. }
  26. double t1=t_[0]*count_ - t_[1]*t_[1];
  27. a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ;
  28. b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ;
  29. //debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_);
  30. }
  31. public:
  32. linear_fit(int count)
  33. :count_(count)
  34. {
  35. reset();
  36. }
  37. void reset()
  38. {
  39. a_=b_=0;
  40. memset(&t_[0],0,sizeof(t_));
  41. x_.resize(0);
  42. y_.resize(0);
  43. }
  44. template<typename iteratorx,typename iteratory>
  45. bool start(iteratorx xi,iteratory yi,size_t count)
  46. {
  47. reset();
  48. std::copy_n(xi,count,std::back_inserter(x_));
  49. std::copy_n(yi,count,std::back_inserter(y_));
  50. if(count<count_)
  51. return false;
  52. while(count-- > count_)
  53. {
  54. x_.pop_front();
  55. y_.pop_front();
  56. }
  57. start_fit();
  58. return true;
  59. }
  60. bool push(double x,double y)
  61. {
  62. //debug_print_syslog(0,"[framework push]count:%d, x:%.2f,y:%.2f",count_,x,y);
  63. x_.push_back(x);
  64. y_.push_back(y);
  65. if(x_.size() < count_)
  66. {
  67. return false; //throw logic_exception(...)
  68. }
  69. else if(x_.size()==count_)
  70. {
  71. start_fit();
  72. return true;
  73. }
  74. t_[0] += x * x - x_.front()*x_.front();
  75. t_[1] += x - x_.front();
  76. t_[2] += x * y - x_.front() * y_.front();
  77. t_[3] += y - y_.front();
  78. x_.pop_front();
  79. y_.pop_front();
  80. double t1=t_[0]*count_ - t_[1]*t_[1];
  81. a_ = (t_[2]*count_ - t_[1]*t_[3]) / t1 ;
  82. b_ = (t_[0]*t_[3] - t_[1]*t_[2]) / t1 ;
  83. //debug_print_syslog(0,"[framework push]count:%d,k:%f,b:%f",count_,a_,b_);
  84. return true;
  85. }
  86. double getY(double x)const
  87. {
  88. return a_ * x + b_;
  89. }
  90. double getY(uint64_t x) const
  91. {
  92. return a_ * x + b_;
  93. }
  94. double getK()const
  95. {
  96. return a_;
  97. }
  98. };
  99. struct comp_linear_fit
  100. {
  101. std::map<int,linear_fit*> m_fit;
  102. comp_linear_fit(const int* begin,const int* end)
  103. {
  104. for(;begin!=end;++begin)
  105. {
  106. m_fit.insert(std::make_pair(*begin,new linear_fit(*begin)));
  107. }
  108. }
  109. ~comp_linear_fit()
  110. {
  111. for_each(m_fit.begin(),m_fit.end(),[&](std::pair<int,linear_fit*> it){delete it.second;});
  112. }
  113. double getY(int num_point,uint64_t time)const
  114. {
  115. auto it=m_fit.find(num_point);
  116. if(it==m_fit.end())
  117. {
  118. //throw
  119. return 0.0;
  120. }
  121. return it->second->getY(time);
  122. }
  123. double getK(int num_point)const
  124. {
  125. auto it=m_fit.find(num_point);
  126. if(it==m_fit.end())
  127. {
  128. //throw
  129. return DBL_MAX;
  130. }
  131. return it->second->getK();
  132. }
  133. void push(uint64_t time, double x)
  134. {
  135. for_each(m_fit.begin(),m_fit.end(),[&](std::pair<int,linear_fit*> it){it.second->push(time,x);});
  136. }
  137. };
  138. #endif