/** * 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 "TimeInterval.hh" namespace AMDA { namespace Statistic { namespace MinMaxMean { using namespace AMDA::Parameters; typedef enum { FT_MIN, FT_MAX, FT_MEAN } 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; } } } virtual void finalizeCompute(void) { if (_funcType == FT_MEAN) finalizeMeanResult(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 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]); } /** * @brief real ParamData Input */ TParamData& _paramInput; TimeIntervalListSPtr _timeIntervalList; TimeIntervalList::iterator _currentTimeInterval; ElementType _val; 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_ */