/** * MinMaxMeanStatistic.hh * * Created on: 04 nov. 2014 * Author: AKKA */ #ifndef MINMAXMEANSTATISTIC_HH_ #define MINMAXMEANSTATISTIC_HH_ #include "ParamData.hh" #include "DataTypeMath.hh" #include "VisitorOfParamData.hh" #include "StatisticData.hh" #include "StatisticOperation.hh" #include "StatisticProcess.hh" #include #include #include "TimeInterval.hh" namespace AMDA { namespace Statistic { namespace MinMaxMean { using namespace AMDA::Parameters; typedef enum { FT_MIN, FT_MAX, FT_MEAN, FT_RMS, FT_MEDIAN, FT_VARIANCE, FT_SKEWNESS, FT_KURTOSIS, FT_FIRST_VALUE, FT_MIDDLE_VALUE, FT_LAST_VALUE } FUNC_TYPE; template class MinMaxMeanStatisticOperation : public StatisticOperation { public: /** * @brief Element type of paramData */ typedef typename TParamData::ElementType ElementType; using TimeDataList = std::vector>; MinMaxMeanStatisticOperation(StatisticProcess& process, TimeIntervalListSPtr pTimeIntervalList, TParamData ¶m, FUNC_TYPE funcType) : StatisticOperation(process), _paramInput(param), _timeIntervalList(pTimeIntervalList), _currentTimeInterval(_timeIntervalList->begin()), _funcType(funcType), _dimDef("unknown") { ElementType fillValue; fillValue << NotANumber(); initDimSize(fillValue); resetData(StatisticOperation::_resultData); } virtual ~MinMaxMeanStatisticOperation(void) { } virtual void compute(ParamDataIndexInfo &pParamDataIndexInfo) { for (unsigned int index = pParamDataIndexInfo._startIndex; index < pParamDataIndexInfo._startIndex + pParamDataIndexInfo._nbDataToProcess; index++) { _val = _paramInput.get(index); double crtTime = _paramInput.getTime(index); switch (_funcType) { case FT_MIN: computeMin(_val); break; case FT_MAX: computeMax(_val); break; case FT_MEAN: addForMean(_val); break; case FT_RMS: addForRMS(_val); break; case FT_MEDIAN: addForMean(_val); generateVector(_val); break; case FT_VARIANCE: addForMean(_val); generateVector(_val); break; case FT_SKEWNESS: addForMean(_val); generateVector(_val); break; case FT_KURTOSIS: addForMean(_val); generateVector(_val); break; case FT_MIDDLE_VALUE: addForMean(_val); generateTimeDataVector(crtTime, _val); case FT_FIRST_VALUE: case FT_LAST_VALUE: addForMean(_val); generateVector(_val); break; } } } virtual void finalizeCompute(void) { if (_funcType == FT_MEAN) finalizeMeanResult(StatisticOperation::_resultData); if (_funcType == FT_RMS) finalizeRMSResult(StatisticOperation::_resultData); if (_funcType == FT_MEDIAN) finalizeMedianResult(StatisticOperation::_resultData); if (_funcType == FT_VARIANCE) { finalizeMeanResult(StatisticOperation::_resultData); finalizeVarianceResult(StatisticOperation::_resultData); } else if (_funcType == FT_SKEWNESS) { finalizeMeanResult(StatisticOperation::_resultData); finalizeVarianceResult(StatisticOperation::_resultData); finalizeSkewnessResult(StatisticOperation::_resultData); } else if (_funcType == FT_KURTOSIS) { finalizeMeanResult(StatisticOperation::_resultData); finalizeVarianceResult(StatisticOperation::_resultData); finalizeKurtosisResult(StatisticOperation::_resultData); } else if (_funcType == FT_FIRST_VALUE) { finalizeFirstValueResult(StatisticOperation::_resultData); }else if (_funcType == FT_MIDDLE_VALUE) { finalizeMiddleValueResult(StatisticOperation::_resultData); } else if (_funcType == FT_LAST_VALUE) { finalizeLastValueResult(StatisticOperation::_resultData); } } virtual void reset() { StatisticOperation::reset(); resetData(StatisticOperation::_resultData); _dataList.clear(); _timeDataList.clear(); ++_currentTimeInterval; } /** * @brief Get the result dimensiond efinition. */ virtual std::string getResultDimDefinition(bool /* forCoverage */) { return _dimDef.str(); } private: template void initDimSize(Type &/*a*/) { _dimDef.str("1"); } template void initDimSize(std::vector &/*a*/) { _dimDef.str("unknown"); } template void resetData(Type &a) { a._result << NotANumber(); a._nbDataProcessed = 0; } template void resetData(std::vector &a) { a.clear(); } template void computeMin(Type &a) { if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a; else if (a < StatisticOperation::_resultData._result) StatisticOperation::_resultData._result = a; ++StatisticOperation::_resultData._nbDataProcessed; } template void computeMin(std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } return; } for (unsigned int i = 0; i < StatisticOperation::_resultData.size(); ++i) { if (isNAN(a[i])) continue; if (isNAN(StatisticOperation::_resultData[i]._result)) StatisticOperation::_resultData[i]._result = a[i]; else if (a[i] < StatisticOperation::_resultData[i]._result) StatisticOperation::_resultData[i]._result = a[i]; ++StatisticOperation::_resultData[i]._nbDataProcessed; } } template void computeMax(Type &a) { if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a; else if (a > StatisticOperation::_resultData._result) StatisticOperation::_resultData._result = a; ++StatisticOperation::_resultData._nbDataProcessed; } template void computeMax(std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } return; } for (unsigned int i = 0; i < StatisticOperation::_resultData.size(); ++i) { if (isNAN(a[i])) continue; if (isNAN(StatisticOperation::_resultData[i]._result)) StatisticOperation::_resultData[i]._result = a[i]; else if (a[i] > StatisticOperation::_resultData[i]._result) StatisticOperation::_resultData[i]._result = a[i]; ++StatisticOperation::_resultData[i]._nbDataProcessed; } } template void addForMean(Type &a) { if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a; else StatisticOperation::_resultData._result = StatisticOperation::_resultData._result + a; ++StatisticOperation::_resultData._nbDataProcessed; } template void addForMean(std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } return; } for (unsigned int i = 0; i < StatisticOperation::_resultData.size(); ++i) { if (isNAN(a[i])) continue; if (isNAN(StatisticOperation::_resultData[i]._result)) StatisticOperation::_resultData[i]._result = a[i]; else StatisticOperation::_resultData[i]._result = StatisticOperation::_resultData[i]._result + a[i]; ++StatisticOperation::_resultData[i]._nbDataProcessed; } } template void addForRMS(Type &a) { if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a * a; else StatisticOperation::_resultData._result = StatisticOperation::_resultData._result + a*a; ++StatisticOperation::_resultData._nbDataProcessed; } template void addForRMS(std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i] * a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } return; } for (unsigned int i = 0; i < StatisticOperation::_resultData.size(); ++i) { if (isNAN(a[i])) continue; if (isNAN(StatisticOperation::_resultData[i]._result)) StatisticOperation::_resultData[i]._result = a[i] * a[i]; else StatisticOperation::_resultData[i]._result = StatisticOperation::_resultData[i]._result + a[i] * a[i]; ++StatisticOperation::_resultData[i]._nbDataProcessed; } } template void generateVector(Type &a) { if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a; _dataList.push_back(a); } template void generateVector(std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } } if (_dataList.empty()) { // init _dataList for (int i = 0; i < a.size(); i++) { std::vector vec; if (!isNAN(a)) vec.push_back(a[i]); _dataList.push_back(vec); vec.clear(); } } else { //remplir dataList for (int i = 0; i < a.size(); i++) { if (!isNAN(a[i])) _dataList[i].push_back(a[i]); } } } template void generateTimeDataVector(double time, Type &a) { _dimDef.str("1"); if (isNAN(a)) return; if (isNAN(StatisticOperation::_resultData._result)) StatisticOperation::_resultData._result = a; _timeDataList.push_back(std::make_pair(time, a)); } template void generateTimeDataVector(double time, std::vector &a) { if (StatisticOperation::_resultData.empty()) { _dimDef.str(""); _dimDef << a.size(); for (unsigned int i = 0; i < a.size(); ++i) { StatisticDataScalar data; resetData(data); data._result = a[i]; if (!isNAN(a)) ++data._nbDataProcessed; StatisticOperation::_resultData.push_back(data); } } // fill timeDataList std::vector vec; for (int i = 0; i < a.size(); i++) vec.push_back(a[i]); _timeDataList.push_back(std::make_pair(time, vec)); vec.clear(); } template void finalizeMeanResult(Type& a) { if (!isNAN(a._result) && a._nbDataProcessed > 0) a._result /= a._nbDataProcessed; _mean = a._result; } template void finalizeMeanResult(std::vector& a) { for (unsigned int i = 0; i < a.size(); ++i) { if (!isNAN(a[i]._result) && a[i]._nbDataProcessed > 0) { a[i]._result /= a[i]._nbDataProcessed; _mean.push_back(a[i]._result); } } } template void finalizeRMSResult(Type& a) { if (!isNAN(a._result) && a._nbDataProcessed > 0) a._result = sqrt(a._result / a._nbDataProcessed); } template void finalizeRMSResult(std::vector& a) { for (int i = 0; i < a.size(); i++) { if (!isNAN(a[i]._result) && a[i]._nbDataProcessed > 0) a[i]._result = sqrt(a[i]._result / a[i]._nbDataProcessed); } } template void finalizeMedianResult(Type & a) { std::size_t size = _dataList.size(); if (size == 0) return; std::sort(_dataList.begin(), _dataList.end()); if (size % 2 == 0) { a._result = (_dataList[size / 2 - 1] + _dataList[size / 2]) / 2; } else { a._result = _dataList[floor(size / 2)]; } } template void finalizeMedianResult(std::vector& a) { for (int i = 0; i < a.size(); i++) { std::size_t size = _dataList[i].size(); if (size == 0) return; std::sort(_dataList[i].begin(), _dataList[i].end()); if (size % 2 == 0) { a[i]._result = (_dataList[i][size / 2 - 1] + _dataList[i][size / 2]) / 2; } else { a[i]._result = _dataList[i][floor(size / 2)]; } } } template void finalizeFirstValueResult(Type & a) { if (_dataList.size() == 0) return; a._result = _dataList[0]; } template void finalizeFirstValueResult(std::vector& a) { for (int i = 0; i < a.size(); i++) { if (_dataList[i].size() == 0) return; a[i]._result = _dataList[i][0]; } } template void finalizeLastValueResult(Type & a) { if (_dataList.size() == 0) return; a._result = _dataList.back(); } template void finalizeLastValueResult(std::vector& a) { for (int i = 0; i < a.size(); i++) { if (_dataList[i].size() == 0) return; a[i]._result = _dataList[i].back(); } } template void finalizeMiddleValueResult(Type & a) { if (_timeDataList.size() == 0) return; if (_timeDataList.size() == 1) { a._result = _timeDataList[0].second; return; } else { double middeTime = (_currentTimeInterval->_startTime + _currentTimeInterval->_stopTime) / 2; for (int i = 0; i < _timeDataList.size(); i++) { if (_timeDataList[i].first == middeTime) { a._result = _timeDataList[i].second; return; } else if (_timeDataList[i].first > middeTime) { a._result = _timeDataList[i - 1].second + (_timeDataList[i].second - _timeDataList[i - 1].second)* ((middeTime - _timeDataList[i - 1].first) / (_timeDataList[i].first - _timeDataList[i - 1].first)); return; } } } } template void finalizeMiddleValueResult(std::vector & a) { //vector of pair