From aa74de884305457ff98e4b1e49929d9f6ca3190b Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Tue, 23 Jan 2024 01:36:31 +0300 Subject: [PATCH] sns: moving average should be an average ref. #2543 --- code/espurna/filters/MovingAverageFilter.h | 30 ++++++++++++++-------- code/test/unit/src/filters/filters.cpp | 17 +++++++++++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/code/espurna/filters/MovingAverageFilter.h b/code/espurna/filters/MovingAverageFilter.h index f255745b..da0ab152 100644 --- a/code/espurna/filters/MovingAverageFilter.h +++ b/code/espurna/filters/MovingAverageFilter.h @@ -12,9 +12,9 @@ class MovingAverageFilter : public BaseFilter { public: void update(double value) override { - _sum = _sum + value - _values[_sample]; - _values[_sample] = value; - _sample = (_sample + 1) % _values.capacity(); + if (_values.size() < _values.capacity()) { + _values.push_back(value); + } } size_t capacity() const override { @@ -22,18 +22,28 @@ public: } double value() const override { - return _sum; + double out{ 0. }; + + for (const auto& value : _values) { + out += value; + } + + if (_values.size()) { + out /= _values.size(); + } + + return out; } void resize(size_t size) override { - _sum = 0.0; - _sample = 0; _values.clear(); - _values.resize(size, 0.0); + _values.reserve(size); + } + + void reset() override { + _values.clear(); } private: - std::vector _values {{0.0}}; - size_t _sample = 0; - double _sum = 0; + std::vector _values{}; }; diff --git a/code/test/unit/src/filters/filters.cpp b/code/test/unit/src/filters/filters.cpp index f0c8ed9a..82b77116 100644 --- a/code/test/unit/src/filters/filters.cpp +++ b/code/test/unit/src/filters/filters.cpp @@ -94,7 +94,22 @@ void test_median() { } void test_moving_average() { - // TODO + auto filter = MovingAverageFilter(); + + TEST_ASSERT_EQUAL(0, filter.capacity()); + TEST_ASSERT_EQUAL_DOUBLE(0.0, filter.value()); + + const double samples[] {22., 22.3, 22.1, 22.1, 22.1, 22.0, 22.5, 22.1}; + filter.resize(std::size(samples)); + + TEST_ASSERT_EQUAL(std::size(samples), filter.capacity()); + TEST_ASSERT_EQUAL_DOUBLE(0.0, filter.value()); + + for (const auto& sample : samples) { + filter.update(sample); + } + + TEST_ASSERT_EQUAL_DOUBLE(22.15, filter.value()); } void test_sum() {