MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ accept()

template<typename T >
T MayaFlux::Kinesis::HampelFilter< T >::accept ( const T &  candidate)
inline

Test a candidate value and return the value to actually use.

Parameters
candidateNewly computed value, typically straight out of a Kinesis::Differential function
Returns
candidate if it looks consistent with recent history, or the last accepted value if candidate looks like an isolated spike

The first call and the next (window - 1) calls always accept, since MAD is not meaningful against a window that has not yet filled with real data; a held value from an uninitialized filter would be an arbitrary default, not a real prior reading.

Definition at line 98 of file HampelFilter.hpp.

99 {
100 if (!m_has_history) {
101 m_history.push(candidate);
102 m_last_good = candidate;
104 if (m_sample_count >= m_history.capacity())
105 m_has_history = true;
106 return candidate;
107 }
108
109 const auto view = m_history.linearized_view();
110
111 std::vector<double> magnitudes;
112 magnitudes.reserve(view.size());
113 for (const auto& v : view)
114 magnitudes.push_back(magnitude_of(v));
115
116 std::vector<double> sorted = magnitudes;
117 std::ranges::sort(sorted);
118 const double median_mag = sorted[sorted.size() / 2];
119
120 std::vector<double> deviations;
121 deviations.reserve(sorted.size());
122 for (double m : sorted)
123 deviations.push_back(std::abs(m - median_mag));
124 std::ranges::sort(deviations);
125 const double mad = deviations[deviations.size() / 2] * 1.4826;
126
127 const double candidate_mag = magnitude_of(candidate);
128 const bool looks_like_spike = (mad > 1e-12)
129 && (std::abs(candidate_mag - median_mag) / mad > m_threshold_mad);
130
131 if (looks_like_spike && m_consecutive_rejections < m_max_consecutive_rejections) {
133 return m_last_good;
134 }
135
136 if (looks_like_spike) {
137 m_history.reset();
138 m_sample_count = 0;
139 m_has_history = false;
140 }
141
143 m_history.push(candidate);
144 m_last_good = candidate;
146 if (m_sample_count >= m_history.capacity())
147 m_has_history = true;
148 return candidate;
149 }
Memory::HistoryBuffer< T > m_history
static double magnitude_of(const U &v) noexcept
Scalar reduction used for the MAD comparison.
std::vector< double > mad(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Median absolute deviation per window.
Definition Analysis.cpp:501

References MayaFlux::Kinesis::HampelFilter< T >::m_consecutive_rejections, MayaFlux::Kinesis::HampelFilter< T >::m_has_history, MayaFlux::Kinesis::HampelFilter< T >::m_history, MayaFlux::Kinesis::HampelFilter< T >::m_last_good, MayaFlux::Kinesis::HampelFilter< T >::m_max_consecutive_rejections, MayaFlux::Kinesis::HampelFilter< T >::m_sample_count, MayaFlux::Kinesis::HampelFilter< T >::m_threshold_mad, and MayaFlux::Kinesis::HampelFilter< T >::magnitude_of().

+ Here is the call graph for this function: