/* Moving Extrema Copyright 2020 Ahmet Inan */ #pragma once #include "delay.hh" #include "stack.hh" namespace DSP { template class MovExt { Delay window; Stack dispenser, refill; EQUAL equal; COMP comp; public: MovExt(TYPE init) : window(init) { dispenser.push(init); } TYPE operator () (TYPE input) { if (window(input) == dispenser.top()) dispenser.pop(); while (!refill.empty() && comp(input, refill.top())) refill.pop(); refill.push(input); if (dispenser.empty()) { while (!refill.empty()) { dispenser.push(refill.top()); refill.pop(); } return dispenser.top(); } return comp(dispenser.top(), refill.first()) ? dispenser.top() : refill.first(); } }; template class MovMin { MovExt, std::less, NUM> movmin; public: MovMin() : movmin(std::numeric_limits::max()) { } TYPE operator () (TYPE input) { return movmin(input); } }; template class MovMax { MovExt, std::greater, NUM> movmax; public: MovMax() : movmax(std::numeric_limits::min()) { } TYPE operator () (TYPE input) { return movmax(input); } }; }