Krita Source Code Documentation
Loading...
Searching...
No Matches
KisFilteredRollingMean.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <algorithm>
10#include <numeric>
11#include <QtMath>
12#include "kis_assert.h"
13#include "kis_debug.h"
14
15
16KisFilteredRollingMean::KisFilteredRollingMean(int windowSize, qreal effectivePortion)
17 : m_values(windowSize),
18 m_rollingSum(0.0),
19 m_effectivePortion(effectivePortion),
20 m_cutOffBuffer(qCeil(0.5 * (qCeil(windowSize * (1.0 - effectivePortion)))))
21{
22}
23
25{
26 if (m_values.full()) {
27 m_rollingSum -= m_values.front();
28 }
29
30 m_values.push_back(value);
32}
33
35{
37
38 const int usefulElements = qMax(1, qRound(m_effectivePortion * m_values.size()));
39
40 qreal sum = 0.0;
41 int num = 0;
42
43 const int cutOffTotal = m_values.size() - usefulElements;
44
45 if (cutOffTotal > 0) {
46 const std::vector<double>::size_type cutMin = qRound(0.5 * cutOffTotal);
47 const std::vector<double>::size_type cutMax = cutOffTotal - cutMin;
48
49 KIS_SAFE_ASSERT_RECOVER(cutMin <= m_cutOffBuffer.size()) {
50 m_cutOffBuffer.resize(cutMin);
51 }
52 KIS_SAFE_ASSERT_RECOVER(cutMax <= m_cutOffBuffer.size()) {
53 m_cutOffBuffer.resize(cutMax);
54 }
55
56 sum = m_rollingSum;
57 num = usefulElements;
58
59 std::partial_sort_copy(m_values.begin(),
60 m_values.end(),
61 m_cutOffBuffer.begin(),
62 m_cutOffBuffer.begin() + cutMin);
63
64 sum -= std::accumulate(m_cutOffBuffer.begin(),
65 m_cutOffBuffer.begin() + cutMin,
66 0.0);
67
68 std::partial_sort_copy(m_values.begin(),
69 m_values.end(),
70 m_cutOffBuffer.begin(),
71 m_cutOffBuffer.begin() + cutMax,
72 std::greater<qreal>());
73
74 sum -= std::accumulate(m_cutOffBuffer.begin(),
75 m_cutOffBuffer.begin() + cutMax,
76 0.0);
77 } else {
78 sum = m_rollingSum;
79 num = m_values.size();
80 }
81
83
84 return sum / num;
85}
86
88{
89 return m_values.empty();
90}
float value(const T *src, size_t ch)
KisFilteredRollingMean(int windowSize, qreal effectivePortion)
boost::circular_buffer< qreal > m_values
std::vector< qreal > m_cutOffBuffer
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129