linear_fit.h 2.9 KB

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