/** * 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 "TimeInterval.hh" namespace AMDA { namespace Statistic { namespace MinMaxMean { using namespace AMDA::Parameters; typedef enum { FT_MIN, FT_MAX, FT_MEAN, FT_MEDIAN, FT_VARIANCE } FUNC_TYPE; template class MinMaxMeanStatisticOperation : public StatisticOperation { public: /** * @brief Element type of paramData */ typedef typename TParamData::ElementType ElementType; MinMaxMeanStatisticOperation(StatisticProcess& process, TimeIntervalListSPtr pTimeIntervalList, TParamData ¶m, FUNC_TYPE funcType) : StatisticOperation(process), _paramInput(param), _timeIntervalList(pTimeIntervalList), _currentTimeInterval(_timeIntervalList->begin()), _funcType(funcType), _dimDef("unknown") { 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); switch (_funcType) { case FT_MIN: computeMin(_val); break; case FT_MAX: computeMax(_val); break; case FT_MEAN: addForMean(_val); break; case FT_MEDIAN: generateVector(_val); break; case FT_VARIANCE: generateVector(_val); break; } } } virtual void finalizeCompute(void) { if (_funcType == FT_MEAN || _funcType == FT_MEAN) finalizeMeanResult(StatisticOperation::_resultData); if (_funcType == FT_MEDIAN) finalizeMedianResult(StatisticOperation::_resultData); if (_funcType == FT_VARIANCE) finalizeMeanResult(StatisticOperation::_resultData); finalizeVarianceResult(StatisticOperation::_resultData); } virtual void reset() { StatisticOperation::reset(); resetData(StatisticOperation::_resultData); } /** * @brief Get the result dimensiond efinition. */ virtual std::string getResultDimDefinition(bool /* forCoverage */) { return _dimDef.str(); } private: template void resetData(Type &a) { a._result << NotANumber(); a._nbDataProcessed = 0; } template void resetData(std::vector &a) { a.clear(); } template void computeMin(Type &a) { _dimDef.str("1"); 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) { _dimDef.str("1"); 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) { _dimDef.str("1"); 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 generateVector(Type &a) { _dimDef.str("1"); 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 finalizeMeanResult(Type& a) { if (a._nbDataProcessed > 0) if (!isNAN(a._result)) a._result /= a._nbDataProcessed; } template void finalizeMeanResult(std::vector& a) { for (unsigned int i = 0; i < a.size(); ++i) finalizeMeanResult(a[i]); } 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 finalizeVarianceResult(Type & a) { if (_dataList.size() == 0) return; double accum = 0.0; std::for_each(std::begin(_dataList), std::end(_dataList), [&](const double d) { accum += (d - a._result) * (d - a._result); }); a._result = accum/(_dataList.size()-1); } template void finalizeVarianceResult(std::vector & a) { for(int i = 0; i < a.size(); i++){ if (_dataList[i].size() == 0) return; double accum = 0.0; std::for_each(std::begin(_dataList[i]), std::end(_dataList[i]), [&](const double d) { accum += (d - a[i]._result) * (d - a[i]._result); }); a[i]._result = accum/(_dataList[i].size()-1); } } /** * @brief real ParamData Input */ TParamData& _paramInput; TimeIntervalListSPtr _timeIntervalList; TimeIntervalList::iterator _currentTimeInterval; ElementType _val; std::vector _dataList; FUNC_TYPE _funcType; std::stringstream _dimDef; }; class CreateMinMaxMeanStatistic : public VisitorOfParamData { public: /** * @brief constructor */ CreateMinMaxMeanStatistic(StatisticProcess& pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamData ¶mData, FUNC_TYPE type) : _process(pProcess), _timeIntervalList(pTimeIntervalList), _paramData(paramData), _operation(NULL), _type(type) { _paramData.accept(*this); } StatisticOperationBase* getStatisticOperation(void) { return _operation; } /** * @overload VisitorOfParamData::visit(ParamDataScalaireShort *) */ virtual void visit(ParamDataScalaireShort *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireFloat *) */ virtual void visit(ParamDataScalaireFloat *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireDouble *) */ virtual void visit(ParamDataScalaireDouble *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireLongDouble *) */ virtual void visit(ParamDataScalaireLongDouble *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataScalaireInt *) */ virtual void visit(ParamDataScalaireInt *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataLogicalData *) */ virtual void visit(ParamDataLogicalData *) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg( "CreateStatistic operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DShort *) */ virtual void visit(ParamDataTab1DShort *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DFloat *) */ virtual void visit(ParamDataTab1DFloat *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DDouble *) */ virtual void visit(ParamDataTab1DDouble *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLongDouble *) */ virtual void visit(ParamDataTab1DLongDouble *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DInt *) */ virtual void visit(ParamDataTab1DInt *) { _operation = new MinMaxMeanStatisticOperation>(_process, _timeIntervalList, dynamic_cast (_paramData), _type); } /** * @overload VisitorOfParamData::visit(ParamDataTab1DLogicalData *) */ virtual void visit(ParamDataTab1DLogicalData *) { BOOST_THROW_EXCEPTION( AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg( "CreateStatistic operation not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DShort *) */ virtual void visit(ParamDataTab2DShort *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DShort data not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DFloat *) */ virtual void visit(ParamDataTab2DFloat *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DFloat data not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DDouble *) */ virtual void visit(ParamDataTab2DDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DDouble data not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLongDouble *) */ virtual void visit(ParamDataTab2DLongDouble *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DLongDouble data not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DInt *) */ virtual void visit(ParamDataTab2DInt *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DInt data not supported")); } /** * @overload VisitorOfParamData::visit(ParamDataTab2DLogicalData *) */ virtual void visit(ParamDataTab2DLogicalData *) { BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("ParamDataTab2DLogicalData data not supported")); } private: StatisticProcess& _process; TimeIntervalListSPtr& _timeIntervalList; ParamData &_paramData; StatisticOperationBase *_operation; FUNC_TYPE _type; }; } /* namespace MinMaxMean */ } /* namespace Statistic */ } /* namespace AMDA */ #endif /* MINMAXMEANSTATISTIC_HH_ */