All Classes Namespaces Files Functions Variables Enumerations Enumerator
libs/common/MovingMedian.h
Go to the documentation of this file.
00001 #ifndef MOVING_MEDIAN_H
00002 #define MOVING_MEDIAN_H
00003 
00015 #include <deque>
00016 #include <algorithm>
00017 
00018 
00019 namespace qrk
00020 {
00026     template<class T> class MovingMedian
00027     {
00028     public:
00035         MovingMedian(size_t size, T initial_value = 0)
00036             : buffer_size_(size), median_index_(size >> 1)
00037         {
00038             if (buffer_size_ == 0) {
00039                 buffer_size_ = 1;
00040             }
00041             buffer_set(buffer_size_, initial_value);
00042         }
00043 
00044 
00050         void setMedianValue(T value)
00051         {
00052             buffer_set(buffer_size_, value);
00053         }
00054 
00055 
00061         T median(void)
00062         {
00063             return median_;
00064         }
00065 
00066 
00074         T push_back(T value)
00075         {
00076             buffer_.pop_front();
00077             buffer_.push_back(value);
00078 
00079             // 中央値を求める
00080             // !!! 可能ならば、コピーを除去する
00081             std::deque<T> copied = buffer_;
00082             std::nth_element(copied.begin(),
00083                              copied.begin() + median_index_, copied.end());
00084             median_ = copied[median_index_];
00085 
00086             return median_;
00087         }
00088 
00089     private:
00090         MovingMedian(const MovingMedian& rhs);
00091         MovingMedian& operator = (const MovingMedian& rhs);
00092 
00093         std::deque<T> buffer_;
00094         size_t buffer_size_;
00095         T median_;
00096         int median_index_;
00097 
00098 
00099         void buffer_set(size_t size, T& value)
00100         {
00101             buffer_.clear();
00102             buffer_.assign(size, value);
00103             median_ = value;
00104         }
00105     };
00106 }
00107 
00108 #endif /* !MOVING_MEDIAN_H */