/* Moving Extrema Copyright 2020 Ahmet Inan */ #pragma once #include "deque.hh" namespace DSP { template class MovExt { Deque window, dispenser, refill; EQUAL equal; COMP comp; public: TYPE operator () (TYPE input) { if (window.full()) { if (equal(window.front(), dispenser.front())) dispenser.pop_front(); window.pop_front(); } window.push_back(input); while (!refill.empty() && comp(input, refill.front())) refill.pop_front(); refill.push_front(input); if (dispenser.empty()) { while (!refill.empty()) { dispenser.push_front(refill.front()); refill.pop_front(); } return dispenser.front(); } return comp(dispenser.front(), refill.back()) ? dispenser.front() : refill.back(); } }; template class MovMin { MovExt, std::less, NUM> movmin; public: TYPE operator () (TYPE input) { return movmin(input); } }; template class MovMax { MovExt, std::greater, NUM> movmax; public: TYPE operator () (TYPE input) { return movmax(input); } }; }