CorrelationFunctions.hh 7.12 KB
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   CorrelationFunctions.hh
 * Author: hacene
 *
 * Created on September 27, 2021, 3:35 PM
 */

#ifndef CORRELATIONFUNCTIONS_HH
#define CORRELATIONFUNCTIONS_HH

#include "DicError.hh"
#include "AMDA_exception.hh"
#include "Parameter.hh"
#include "ParamData.hh"
#include "DataTypeMath.hh"
#include "Operation.hh"
#include <vector>
#include <iostream>
#include <iterator>
#include <c++/4.8.2/bits/stl_vector.h>
#include <c++/4.8.2/bits/stl_pair.h>
#include <list>
#include "Toolbox.hh"
#include "AbstractFunc.hh"

namespace AMDA {
    namespace Parameters {
        namespace StatisticFunctions {

            enum COEFS {
                COVARIANCE = 1,
                PAERSON = 2,
                SPEARMAN = 3,
                KENDALL = 4,
            };
            static std::map<std::string, COEFS> coefsToStr = {
                {"covariance", COEFS::COVARIANCE},
                {"pearson", COEFS::PAERSON},
                {"spearman", COEFS::SPEARMAN},
                {"kendall", COEFS::KENDALL},
                {"1", COEFS::COVARIANCE},
                {"2", COEFS::PAERSON},
                {"3", COEFS::SPEARMAN},
                {"4", COEFS::KENDALL},
            };

            /**
             * 
             * @param pProcess
             * @param pTimeIntervalList
             * @param firstParamInput
             * @param secondParamInput
             * @param windowtime
             * @param type
             */
            template <typename InputElemType, typename OutputElemType>
            class Correlation : public Sm2ParamsAbstractFunc<InputElemType, OutputElemType> {
            public:

                Correlation(Process & pProcess, TimeIntervalListSPtr pTimeIntervalList, ParamDataSpec<InputElemType>& firstParamInput,
                        ParamDataSpec<InputElemType>& secondParamInput, double windowtime, std::string correlationType) :
                            Sm2ParamsAbstractFunc<InputElemType, OutputElemType> (pProcess, pTimeIntervalList, firstParamInput, 
                                secondParamInput, windowtime), _correlationType(correlationType) {

                }

                virtual ~Correlation() {
                }
                
                virtual OutputElemType compute() {
                    return computeCorrelation(Abstract2ParamsFunc<InputElemType, OutputElemType>::_paramOutput);
                }

                double computeCorrelation(ParamDataSpec<double>* /*out*/) {
                    double result = 0.;
                    result << NotANumber();
                    if (Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.empty()) {
                        return result;
                    }
                    std::list<std::pair<InputElemType, InputElemType>> list;
                    for (typename std::list<std::pair<double, std::pair < InputElemType, InputElemType>>>::iterator it = Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.begin(); it != Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.end(); ++it) {
                        if (isNAN(it->second.first) || isNAN(it->second.second))
                            continue;
                        list.push_back(it->second);
                    }
                    if (coefsToStr.find(_correlationType) == coefsToStr.end()) {
                        BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("StatisticFunctions::CorrelationFunction  unknown correlation type " + _correlationType));
                    }

                    switch (coefsToStr[_correlationType]) {
                        case COEFS::COVARIANCE:
                            getCovariance(list, result);
                            break;
                        case COEFS::PAERSON:
                            getPearson(list, result);
                            break;
                        case COEFS::SPEARMAN:
                            getSpearman(list, result);
                            break;
                        case COEFS::KENDALL:
                            getKendall(list, result);
                            break;
                        default:
                            BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("StatisticFunctions::CorrelationFunction  unknown correlation type :" + _correlationType));
                    }

                    return result;
                }

                std::vector<double> computeCorrelation(ParamDataSpec<std::vector<double> >* /*out*/) {
                    std::vector<double> result;
                    if (Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.empty()) {
                        return result;
                    }
                    int n_ = Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.begin()->second.first.size();
                    result.resize(n_);
                    result << NotANumber();
                    for(int i = 0; i < n_; ++i){
                        std::list<std::pair<double, double>> list;
                        for (typename std::list<std::pair<double, std::pair < InputElemType, InputElemType>>>::iterator it = Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.begin(); it != Sm2ParamsAbstractFunc<InputElemType, OutputElemType>::_mem.end(); ++it) {
                            list.push_back(std::make_pair((double)it->second.first[i], (double)it->second.second[i]));
                        }
                        if (coefsToStr.find(_correlationType) == coefsToStr.end()) {
                            BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("StatisticFunctions::CorrelationFunction  unknown correlation type " + _correlationType));
                        }

                        switch (coefsToStr[_correlationType]) {
                            case COEFS::COVARIANCE:
                                getCovariance(list, result[i]);
                                break;
                            case COEFS::PAERSON:
                                getPearson(list, result[i]);
                                break;
                            case COEFS::SPEARMAN:
                                getSpearman(list, result[i]);
                                break;
                            case COEFS::KENDALL:
                                getKendall(list, result[i]);
                                break;
                            default:
                                BOOST_THROW_EXCEPTION(AMDA::AMDA_exception() << AMDA::errno_code(AMDA_ERROR_UNKNOWN) << AMDA::ex_msg("StatisticFunctions::CorrelationFunction  unknown correlation type :" + _correlationType));
                        }
                        list.clear();
                    }

                    return result;
                }

            private:
                std::string _correlationType;

            };
            
        }
    }
}


#endif /* CORRELATIONFUNCTIONS_HH */