12 #ifndef ROC_CORE_MOV_STATS_H_
13 #define ROC_CORE_MOV_STATS_H_
43 , queue_max_(arena, win_len + 1)
45 , queue_min_(arena, win_len + 1)
49 roc_panic(
"mov stats: window length must be greater than 0");
52 if (!queue_max_.is_valid() || !queue_min_.is_valid()) {
56 if (!buffer_.resize(win_len)) {
59 if (!buffer2_.resize(win_len)) {
72 void add(
const T& x) {
74 const T x_old = buffer_[buffer_i_];
75 buffer_[buffer_i_] = x;
76 const T x2_old = buffer2_[buffer_i_];
77 buffer2_[buffer_i_] = x2;
80 movsum2_ += x2 - x2_old;
83 if (buffer_i_ == win_len_) {
97 }
else if (buffer_i_ == 0) {
110 }
else if (buffer_i_ == 0) {
115 return (T)sqrt((n * movsum2_ - movsum_ * movsum_) / (n * n));
139 if (new_win <= win_len_) {
140 roc_panic(
"mov stats: the window length can only grow");
142 if (!buffer_.resize(new_win)) {
145 if (!buffer2_.resize(new_win)) {
151 for (
size_t i = 0; i < buffer_i_; i++) {
152 movsum_ += buffer_[i];
153 movsum2_ += buffer2_[i];
165 void slide_max_(
const T& x,
const T x_old) {
166 if (queue_max_.is_empty()) {
167 queue_max_.push_back(x);
170 if (queue_max_.front() == x_old) {
171 queue_max_.pop_front();
172 curr_max_ = queue_max_.is_empty() ? x : queue_max_.front();
174 while (!queue_max_.is_empty() && queue_max_.back() < x) {
175 queue_max_.pop_back();
177 if (queue_max_.is_empty()) {
180 queue_max_.push_back(x);
189 void slide_min_(
const T& x,
const T x_old) {
190 if (queue_min_.is_empty()) {
191 queue_min_.push_back(x);
194 if (queue_min_.front() == x_old) {
195 queue_min_.pop_front();
196 curr_min_ = queue_min_.is_empty() ? x : queue_min_.front();
198 while (!queue_min_.is_empty() && queue_min_.back() > x) {
199 queue_min_.pop_back();
201 if (queue_min_.is_empty()) {
204 queue_min_.push_back(x);
211 const size_t win_len_;
217 size_t mov_max_cntr_;
222 RingQueue<T> queue_max_;
224 RingQueue<T> queue_min_;
#define ROC_ATTR_NODISCARD
Emit warning if function result is not checked.
Rolling window moving average and variance.
T mov_max() const
Max value in sliding window.
T mov_min() const
Min value in sliding window.
bool is_valid() const
Check that initial allocation succeeded.
T mov_avg() const
Get moving average value.
void add(const T &x)
Shift rolling window by one sample x.
MovStats(IArena &arena, const size_t win_len)
Initialize.
T mov_var() const
Get variance.
ROC_ATTR_NODISCARD bool extend_win(const size_t new_win)
Extend rolling window length.
#define roc_panic(...)
Print error message and terminate program gracefully.
Queue on continuous memory buffer.