Program Listing for File GWCorrelation.h

Return to documentation for file (include/gwmodelpp/GWCorrelation.h)

#ifndef GWCORRELATION_H
#define GWCORRELATION_H

#include "SpatialMultiscaleAlgorithm.h"
#include "IMultivariableAnalysis.h"
#include "IParallelizable.h"
#include "IBandwidthSelectable.h"

namespace gwm
{
#define GWM_LOG_TAG_GWCORR_INITIAL_BW "#initial-bandwidth "

class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAnalysis, public IParallelizable, public IParallelOpenmpEnabled, public IBandwidthSelectable
{
public:

    enum BandwidthInitilizeType
    {
        Null,
        Initial,
        Specified
    };

    static std::unordered_map<BandwidthInitilizeType,std::string> BandwidthInitilizeTypeNameMapper;

    enum BandwidthSelectionCriterionType
    {
        CV,
        AIC
    };

    static std::unordered_map<BandwidthSelectionCriterionType,std::string> BandwidthSelectionCriterionTypeNameMapper;


    static double covwt(const arma::mat &x1, const arma::mat &x2, const arma::vec &w)
    {
        return sum((sqrt(w) % (x1 - sum(x1 % w))) % (sqrt(w) % (x2 - sum(x2 % w)))) / (1 - sum(w % w));
    }

    static double corwt(const arma::mat &x1, const arma::mat &x2, const arma::vec &w)
    {
        return covwt(x1,x2,w)/sqrt(covwt(x1,x1,w)*covwt(x2,x2,w));
    }

    static arma::vec rank(arma::vec x)
    {
        arma::vec n = arma::linspace(0.0, (double)x.n_rows - 1, x.n_rows);
        arma::vec res = n(sort_index(x));
        return n(sort_index(res)) + 1.0;
    }

    static arma::vec del(arma::vec x, arma::uword rowcount);

    GWCorrelation() {}

    ~GWCorrelation() {}

    typedef void (GWCorrelation::*SummaryCalculator)();


public: //calculating functions

    // bool isCorrWithFirstOnly() const { return mIsCorrWithFirstOnly; }
    // void setIsCorrWithFirstOnly(bool corrWithFirstOnly) { mIsCorrWithFirstOnly = corrWithFirstOnly; }

    const arma::mat& localMean() const { return mLocalMean; }

    const arma::mat& localSDev() const { return mStandardDev; }

    const arma::mat& localSkewness() const { return mLocalSkewness; }

    const arma::mat& localCV() const { return mLCV; }

    const arma::mat& localVar() const { return mLVar; }

    // const arma::mat& localMedian() const { return mLocalMedian; }



    const arma::mat& localCov() const { return mCovmat; }

    const arma::mat& localCorr() const { return mCorrmat; }

    const arma::mat& localSCorr() const { return mSCorrmat; }

public: //bandwidth selection

    typedef double (GWCorrelation::*BandwidthSizeCriterionFunction)(BandwidthWeight*);

    bool isAutoselectBandwidth() { return mIsAutoselectBandwidth; }

    const std::vector<BandwidthInitilizeType>& bandwidthInitilize() const { return GWCorrelation::mBandwidthInitilize; }

    void setBandwidthInitilize(const std::vector<BandwidthInitilizeType> &bandwidthInitilize);

    const std::vector<BandwidthSelectionCriterionType>& bandwidthSelectionApproach() const { return GWCorrelation::mBandwidthSelectionApproach; }

    void setBandwidthSelectionApproach(const std::vector<BandwidthSelectionCriterionType> &bandwidthSelectionApproach);


    typedef double (GWCorrelation::*BandwidthSelectionCriterionCalculator)(BandwidthWeight*);

    // bool isAutoselectBandwidth() const { return mIsAutoselectBandwidth; }
    // void setIsAutoselectBandwidth(bool isAutoSelect) { mIsAutoselectBandwidth = isAutoSelect; }

    BandwidthSizeCriterionFunction bandwidthSizeCriterionVar(BandwidthSelectionCriterionType type)
    {
#ifdef ENABLE_OPENMP
        if (mParallelType & ParallelType::OpenMP)
        {
            switch (type)
            {
            case BandwidthSelectionCriterionType::CV:
                return &GWCorrelation::bandwidthSizeCriterionCVOmp;
            case BandwidthSelectionCriterionType::AIC:
                return &GWCorrelation::bandwidthSizeCriterionAICOmp;
            default:
                return &GWCorrelation::bandwidthSizeCriterionAICOmp;
            }
        }
#endif // ENABLE_OPENMP
        switch (type)
        {
        case BandwidthSelectionCriterionType::CV:
            return &GWCorrelation::bandwidthSizeCriterionCVSerial;
        case BandwidthSelectionCriterionType::AIC:
            return &GWCorrelation::bandwidthSizeCriterionAICSerial;
        default:
            return &GWCorrelation::bandwidthSizeCriterionAICSerial;
        }
    }

private:

    double bandwidthSizeCriterionCVSerial(BandwidthWeight* bandwidthWeight);

    double bandwidthSizeCriterionAICSerial(BandwidthWeight* bandwidthWeight);

#ifdef ENABLE_OPENMP
    double bandwidthSizeCriterionCVOmp(BandwidthWeight* bandwidthWeight);

    double bandwidthSizeCriterionAICOmp(BandwidthWeight* bandwidthWeight);
#endif

public:     // Implement IBandwidthSelectable
    Status getCriterion(BandwidthWeight* weight, double& criterion) override
    {
        criterion = (this->*mBandwidthSizeCriterion)(weight);
        return mStatus;
    }


public:     // IParallelizable
    int parallelAbility() const override
    {
        return ParallelType::SerialOnly
#ifdef ENABLE_OPENMP
            | ParallelType::OpenMP
#endif
            ;
    }
    ParallelType parallelType() const override { return mParallelType; }

    void setParallelType(const ParallelType& type) override;

public:     // IParallelOpenmpEnabled

    void setOmpThreadNum(const int threadNum) override { mOmpThreadNum = threadNum; }

    // void updateCalculator();

private:
    void GWCorrelationSerial();

#ifdef ENABLE_OPENMP
    void GWCorrelationOmp();
#endif

public:     // SpatialAlgorithm interface
    bool isValid() override;

public:     // IMultivariateAnalysis
    const arma::mat& variables2() const override { return mX; }

    void setVariables2(const arma::mat& x) override { mX = x; }


    const arma::mat& variables1() const override { return mY; }

    void setVariables1(const arma::mat& y) override { mY = y; }

    void run() override;

    void calibration(const arma::mat& locations, const arma::mat& x);

protected:
    // std::vector<SpatialWeight> mSpatialWeights;   //!< Spatial weight configuration.

    BandwidthWeight* bandwidth(size_t i)
    {
        return mSpatialWeights[i].weight<BandwidthWeight>();
    }

private:
    // bool mIsCorrWithFirstOnly = false;  //是否仅为第一个变量计算与其他变量的相关系数

    bool mIsAutoselectBandwidth = false;
    SpatialWeight mInitSpatialWeight;
    BandwidthSelectionCriterionType mBandwidthSelectionCriterion = BandwidthSelectionCriterionType::AIC;
    BandwidthSizeCriterionFunction mBandwidthSizeCriterion = &GWCorrelation::bandwidthSizeCriterionCVSerial;
    BandwidthCriterionList mBandwidthSelectionCriterionList;
    double mBandwidthLastCriterion = DBL_MAX;
    size_t mBandwidthSelectionCurrentIndex = 0;
    std::vector<BandwidthInitilizeType> mBandwidthInitilize;
    std::vector<BandwidthSelectionCriterionType> mBandwidthSelectionApproach;

    arma::mat mX;
    arma::mat mY;
    arma::mat mXi;
    arma::mat mYi;

    arma::mat mLocalMean;
    arma::mat mStandardDev;
    arma::mat mLocalSkewness;
    arma::mat mLCV;
    arma::mat mLVar;
    // arma::mat mLocalMedian;   //!< \~english Local medians \~chinese 局部中位数
    arma::mat mCovmat;
    arma::mat mCorrmat;
    arma::mat mSCorrmat;

    SummaryCalculator mSummaryFunction = &GWCorrelation::GWCorrelationSerial;
    ParallelType mParallelType = ParallelType::SerialOnly;
    int mOmpThreadNum = 8;

};

}

#endif  // GWCORRELATION_H