|
@@ -4,6 +4,7 @@
|
|
|
#include "utility/dynamic_pool.hpp"
|
|
#include "utility/dynamic_pool.hpp"
|
|
|
|
|
|
|
|
#include <boost/core/noncopyable.hpp>
|
|
#include <boost/core/noncopyable.hpp>
|
|
|
|
|
+#include <boost/circular_buffer.hpp>
|
|
|
|
|
|
|
|
#include <cmath>
|
|
#include <cmath>
|
|
|
#include <deque>
|
|
#include <deque>
|
|
@@ -11,73 +12,55 @@
|
|
|
|
|
|
|
|
namespace sophiar {
|
|
namespace sophiar {
|
|
|
|
|
|
|
|
- class measure_window : private boost::noncopyable {
|
|
|
|
|
|
|
+ class measure_window: boost::noncopyable {
|
|
|
public:
|
|
public:
|
|
|
|
|
+ static constexpr auto max_length = 1024;
|
|
|
|
|
|
|
|
- static constexpr auto max_length = std::numeric_limits<size_t>::max();
|
|
|
|
|
|
|
+ explicit measure_window(size_t length = max_length)
|
|
|
|
|
+ : win(length) { }
|
|
|
|
|
|
|
|
- explicit measure_window(size_t _length = max_length)
|
|
|
|
|
- : win_length(_length) {}
|
|
|
|
|
-
|
|
|
|
|
- void reset() {
|
|
|
|
|
- while (!win.empty()) {
|
|
|
|
|
- win.pop();
|
|
|
|
|
- }
|
|
|
|
|
- cur_n = 0;
|
|
|
|
|
- sum_x = 0.0;
|
|
|
|
|
- sum_x2 = 0.0;
|
|
|
|
|
|
|
+ void reset() { //
|
|
|
|
|
+ win.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- void pop() {
|
|
|
|
|
- assert(!win.empty());
|
|
|
|
|
- auto val = win.front();
|
|
|
|
|
- win.pop();
|
|
|
|
|
- sum_x -= val;
|
|
|
|
|
- sum_x2 -= val * val;
|
|
|
|
|
- --cur_n;
|
|
|
|
|
|
|
+ void push(float val) { //
|
|
|
|
|
+ win.push_back(val);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- void push(double val) {
|
|
|
|
|
- if (cur_n == win_length) {
|
|
|
|
|
- pop();
|
|
|
|
|
- }
|
|
|
|
|
- win.push(val);
|
|
|
|
|
- sum_x += val;
|
|
|
|
|
- sum_x2 += val * val;
|
|
|
|
|
- ++cur_n;
|
|
|
|
|
|
|
+ void pop() { //
|
|
|
|
|
+ win.pop_front();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- double calc_mean() const {
|
|
|
|
|
- assert(cur_n >= 1);
|
|
|
|
|
- return sum_x / static_cast<double>(cur_n);
|
|
|
|
|
|
|
+ float calc_mean() const {
|
|
|
|
|
+ if ( win.empty() ) return NAN;
|
|
|
|
|
+ auto sum = std::reduce(win.begin(), win.end());
|
|
|
|
|
+ return sum / win.size();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- double calc_std() const {
|
|
|
|
|
- assert(cur_n >= 2);
|
|
|
|
|
- auto mean_val = calc_mean();
|
|
|
|
|
- return std::sqrt(sum_x2
|
|
|
|
|
- - 2 * mean_val * sum_x
|
|
|
|
|
- + static_cast<double>(cur_n) * mean_val * mean_val)
|
|
|
|
|
- / static_cast<double>(cur_n - 1);
|
|
|
|
|
|
|
+ float calc_std() const {
|
|
|
|
|
+ if ( win.size() < 2 ) return NAN;
|
|
|
|
|
+ auto mean = calc_mean();
|
|
|
|
|
+ auto sum_std2 = std::transform_reduce(
|
|
|
|
|
+ win.begin(), win.end(), //
|
|
|
|
|
+ 0.f, std::plus(),
|
|
|
|
|
+ [=](float x) {
|
|
|
|
|
+ return (x - mean) * (x - mean);
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+ auto std2 = sum_std2 / (win.size() - 1);
|
|
|
|
|
+ return std::sqrt(std2);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- bool is_full() const {
|
|
|
|
|
- return win.size() == win_length;
|
|
|
|
|
|
|
+ bool is_full() const { //
|
|
|
|
|
+ return win.full();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- size_t length() const {
|
|
|
|
|
|
|
+ size_t length() const { //
|
|
|
return win.size();
|
|
return win.size();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- size_t win_length;
|
|
|
|
|
- size_t cur_n = 0;
|
|
|
|
|
- double sum_x = 0, sum_x2 = 0;
|
|
|
|
|
-
|
|
|
|
|
- using dynamic_deque = std::deque<double, DYNAMIC_ALLOCATOR(double) >;
|
|
|
|
|
- using dynamic_queue = std::queue<double, dynamic_deque>;
|
|
|
|
|
- dynamic_queue win;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ boost::circular_buffer<float> win;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
}
|
|
}
|