/* * MedianFunc.hh * * Created on: Jun 23, 2018 * Author: benjamin */ #ifndef MEDIANFUNC_HH_ #define MEDIANFUNC_HH_ #include "AbstractFunc.hh" #include "Toolbox.hh" namespace AMDA { namespace Parameters { namespace StatisticFunctions { template bool getMedian(std::list& list, Type& result) { result << NotANumber(); if (list.empty()) { return false; } std::vector sorted_list; for (typename std::list::iterator it = list.begin(); it != list.end(); ++it) { if (isNAN(*it)) { continue; } sorted_list.push_back(*it); } std::sort(sorted_list.begin(), sorted_list.end()); if (sorted_list.empty()) { return false; } if (sorted_list.size() % 2 == 0) { //even int index = (sorted_list.size() / 2); result = sorted_list[index]; } else { //odd int index = (sorted_list.size() / 2); result = (sorted_list[index] + sorted_list[index+1]) / 2.; } return true; } template bool getMedian(std::list>& list, std::vector& result) { if (list.empty()) { return false; } result = list.front(); result << NotANumber(); int eltSize = result.size(); for (int i = 0; i < eltSize; ++i) { std::list compList; for (typename std::list>::iterator it = list.begin(); it != list.end(); ++it) { if ((int)it->size() != eltSize) { continue; } compList.push_back((*it)[i]); } Type compRes; getMedian(compList, compRes); result[i] = compRes; } return true; } template bool getMedian(std::list>& list, Tab2DData& result) { if (list.empty()) { return false; } Tab2DData nanVal(list.front()); nanVal << NotANumber(); result = nanVal; int eltDim1Size = result.getDim1Size(); int eltDim2Size = result.getDim2Size(); for (int i = 0; i < eltDim1Size; ++i) { for (int j = 0; j < eltDim2Size; ++j) { std::list compList; for (typename std::list>::iterator it = list.begin(); it != list.end(); ++it) { if (it->getDim1Size() != eltDim1Size || it->getDim2Size() != eltDim2Size) { continue; } compList.push_back((*it)[i][j]); } Type compRes; getMedian(compList, compRes); result[i][j] = compRes; } } return true; } template OutputElemType computeMedian(std::list>& mem, OutputElemType& nanVal) { OutputElemType result = nanVal; if (mem.empty()) { return result; } std::list list; for (typename std::list>::iterator it = mem.begin(); it != mem.end(); ++it) { list.push_back(it->second); } getMedian(list, result); return result; } /** * @class MedianFunc * @brief * @details This class implements AbstractFunc. */ template class MedianFunc : public ClassicAbstractFunc { public: /** * @brief Constructor. */ MedianFunc(Process& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec& paramInput, double windowtime) : ClassicAbstractFunc(pProcess, pTimeIntervalList, paramInput, windowtime) { } virtual ~MedianFunc() { } OutputElemType compute() { return computeMedian(ClassicAbstractFunc::_mem, ClassicAbstractFunc::_nanVal); } }; } /* namespace StatisticFunctions */ } /* namespace Parameters */ } /* namespace AMDA */ #endif /* MEDIANFUNC_HH_ */