From fbe76102e941b9f1edaf236788e42678f05fdf9a Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:08:06 +0200 Subject: 3.9 --- shared/signal_processing.h | 166 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 shared/signal_processing.h (limited to 'shared/signal_processing.h') diff --git a/shared/signal_processing.h b/shared/signal_processing.h new file mode 100644 index 00000000..857d0b12 --- /dev/null +++ b/shared/signal_processing.h @@ -0,0 +1,166 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include +#include +#include + + +namespace util +{ +template +T abs(T value); + +int round(double d); //little rounding function + +template +bool isNull(T number); + +//---------------------------------------------------------------------------------- +// smoothen data ranges through a window around each data point | +//---------------------------------------------------------------------------------- +template +void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize); //default implementation: averaging + +template +void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc); +/* +DataProcessor is an abstraction for data evaluation. A valid implementation needs to support three properties: +- add data entry at window front: operator+=(ValueType value) +- remove data entry at window back: operator-=(ValueType value) +- evaluate smoothed middle value: ValueType operator()(size_t windowSize) +*/ +//---------------------------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + + +//################# inline implementation ######################### +template +inline +T abs(T value) +{ + return value < 0 ? -value : value; +} + + +template +inline +bool isNull(T value) +{ + return abs(number) <= std::numeric_limits::epsilon(); //epsilon == 0 for integer types, therefore less-equal(!) +} + + +inline +int round(double d) +{ + return static_cast(d < 0 ? d - .5 : d + .5); +} + + +template +inline +void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc) +{ + windowSize = std::min(windowSize, static_cast(last - first)); //std::distance() not used to enforce random access iterator requirement + + if (windowSize <= 1) + { + std::copy(first, last, result); + return; + } + + const size_t firstHalf = windowSize / 2; + const size_t secondHalf = windowSize - firstHalf; + + //preparation + for (InputIterator i = first; i != first + secondHalf; ++i) + proc += *i; + + //beginning + for (InputIterator i = first; i != first + firstHalf; ++i) + { + *result++ = proc(i - first + secondHalf); + proc += *(i + secondHalf); + } + + //main + for (InputIterator i = first + firstHalf; i != last - secondHalf; ++i) + { + *result++ = proc(windowSize); + proc += *(i + secondHalf); + proc -= *(i - firstHalf); + } + + //ending + for (InputIterator i = last - secondHalf; i != last; ++i) + { + *result++ = proc(windowSize - (i - last + secondHalf)); + proc -= *(i - firstHalf); + } +} + + +template +class ProcessorAverage +{ +public: + ProcessorAverage() : valueAcc() {} + + //add front data entry + ProcessorAverage& operator+=(ValueType value) + { + valueAcc += value; + return *this; + } + + //remove rear data entry + ProcessorAverage& operator-=(ValueType value) + { + valueAcc -= value; + return *this; + } + + //evaluate smoothed value + ValueType operator()(size_t windowSize) const + { + return valueAcc / windowSize; + } + +private: + ValueType valueAcc; //accumulated values +}; + + + +template +inline +void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize) +{ + typedef typename std::iterator_traits::value_type ValueType; + smoothen(first, last, result, windowSize, ProcessorAverage()); +} + +} \ No newline at end of file -- cgit