From 1abcd7bcaaf89a928983057a4969f2ee04c347f5 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Mon, 13 Oct 2025 16:46:34 +0800 Subject: [PATCH 1/6] fixbasicgwr --- src/TaskThread/gwmbasicgwralgorithm.cpp | 73 +++++-------------- src/TaskThread/gwmbasicgwralgorithm.h | 38 +++++----- src/TaskThread/gwmgeneralizedgwralgorithm.cpp | 26 +++---- src/TaskThread/gwmgeneralizedgwralgorithm.h | 14 ++-- src/TaskThread/gwmrobustgwralgorithm.cpp | 6 +- src/TaskThread/gwmrobustgwralgorithm.h | 6 +- src/TaskThread/iparallelable.h | 2 +- src/gwmggwroptionsdialog.cpp | 10 +-- src/gwmgwroptionsdialog.cpp | 10 +-- src/gwmrobustgwroptionsdialog.cpp | 10 +-- 10 files changed, 81 insertions(+), 114 deletions(-) diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 4b1ceb2..2478557 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmbasicgwralgorithm.h" +#include "gwmbasicgwralgorithm.h" #include #include #include @@ -8,6 +8,7 @@ #include using namespace arma; +using namespace gwm; int GwmBasicGWRAlgorithm::treeChildCount = 0; @@ -35,7 +36,7 @@ GwmEnumValueNameMapper Gw GwmBasicGWRAlgorithm::GwmBasicGWRAlgorithm() : GwmGeographicalWeightedRegressionAlgorithm() { - + mGWRCore = std::make_unique(); } @@ -1131,14 +1132,15 @@ void GwmBasicGWRAlgorithm::fTest(GwmBasicGWRAlgorithm::FTestParameters params) } } -int GwmBasicGWRAlgorithm::groupSize() const +std::size_t GwmBasicGWRAlgorithm::groupSize() const { return mGroupSize; } -void GwmBasicGWRAlgorithm::setGroupSize(int groupSize) +void GwmBasicGWRAlgorithm::setGroupSize(const std::size_t groupSize) { - mGroupSize = groupSize; + Q_ASSERT(groupSize <= static_cast(std::numeric_limits::max())); + mGroupSize = static_cast(groupSize); } double GwmBasicGWRAlgorithm::calcTrQtQSerial() @@ -1463,65 +1465,26 @@ void GwmBasicGWRAlgorithm::initXY(mat &x, mat &y, const GwmVariable &depVar, con void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) { mBandwidthSelectionCriterionType = bandwidthSelectionCriterionType; - QMap, BandwidthSelectCriterionFunction> mapper = { + QMap, BandwidthSelectCriterionFunction> mapper = { #ifdef ENABLE_CUDA - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVCuda), - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVCuda), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda), #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp), #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp) + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp) #endif }; mBandwidthSelectCriterionFunction = mapper[qMakePair(bandwidthSelectionCriterionType, mParallelType)]; } -void GwmBasicGWRAlgorithm::setParallelType(const IParallelalbe::ParallelType &type) +void GwmBasicGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - if (type & parallelAbility()) - { - mParallelType = type; - switch (type) { - case IParallelalbe::ParallelType::SerialOnly: - mRegressionFunction = &GwmBasicGWRAlgorithm::regressionSerial; - mRegressionHatmatrixFunction = &GwmBasicGWRAlgorithm::regressionHatmatrixSerial; - mIndepVarsSelectCriterionFunction = &GwmBasicGWRAlgorithm::indepVarsSelectCriterionSerial; - mCalcTrQtQFunction = &GwmBasicGWRAlgorithm::calcTrQtQSerial; - mCalcDiagBFunction = &GwmBasicGWRAlgorithm::calcDiagBSerial; - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - break; -#ifdef ENABLE_OpenMP - case IParallelalbe::ParallelType::OpenMP: - mRegressionFunction = &GwmBasicGWRAlgorithm::regressionOmp; - mRegressionHatmatrixFunction = &GwmBasicGWRAlgorithm::regressionHatmatrixOmp; - mIndepVarsSelectCriterionFunction = &GwmBasicGWRAlgorithm::indepVarsSelectCriterionOmp; - mCalcTrQtQFunction = &GwmBasicGWRAlgorithm::calcTrQtQOmp; - mCalcDiagBFunction = &GwmBasicGWRAlgorithm::calcDiagBOmp; - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - break; -#endif -#ifdef ENABLE_CUDA - case IParallelalbe::ParallelType::CUDA: - mRegressionFunction = &GwmBasicGWRAlgorithm::regressionCuda; - mRegressionHatmatrixFunction = &GwmBasicGWRAlgorithm::regressionHatmatrixCuda; - mIndepVarsSelectCriterionFunction = &GwmBasicGWRAlgorithm::indepVarsSelectCriterionCuda; - mCalcTrQtQFunction = &GwmBasicGWRAlgorithm::calcTrQtQCuda; - mCalcDiagBFunction = &GwmBasicGWRAlgorithm::calcDiagBCuda; - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - break; -#endif - default: - mRegressionFunction = &GwmBasicGWRAlgorithm::regressionSerial; - mRegressionHatmatrixFunction = &GwmBasicGWRAlgorithm::regressionHatmatrixSerial; - mIndepVarsSelectCriterionFunction = &GwmBasicGWRAlgorithm::indepVarsSelectCriterionSerial; - mCalcTrQtQFunction = &GwmBasicGWRAlgorithm::calcTrQtQSerial; - mCalcDiagBFunction = &GwmBasicGWRAlgorithm::calcDiagBSerial; - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - break; - } - } + if (mGWRCore) + mGWRCore->setParallelType(type); + mParallelType = type; } diff --git a/src/TaskThread/gwmbasicgwralgorithm.h b/src/TaskThread/gwmbasicgwralgorithm.h index fda2be0..ae7d5be 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.h +++ b/src/TaskThread/gwmbasicgwralgorithm.h @@ -1,16 +1,16 @@ -#ifndef GWMBASICGWRALGORITHM_H +#ifndef GWMBASICGWRALGORITHM_H #define GWMBASICGWRALGORITHM_H #include "TaskThread/gwmgeographicalweightedregressionalgorithm.h" #include "TaskThread/gwmbandwidthsizeselector.h" #include "TaskThread/gwmindependentvariableselector.h" -#include "TaskThread/iparallelable.h" +//#include "TaskThread/iparallelable.h" #ifdef ENABLE_CUDA #include "GWmodelCUDA/IGWmodelCUDA.h" #endif -class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public IIndependentVariableSelectable, public IOpenmpParallelable, public ICudaParallelable +class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public IIndependentVariableSelectable, public gwm::IParallelizable, public gwm::IParallelOpenmpEnabled, public gwm::IParallelCudaEnabled { Q_OBJECT @@ -67,6 +67,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, private: GwmDiagnostic CalcDiagnostic(const mat& x, const vec& y, const mat& betas, const vec& shat); + std::unique_ptr mGWRCore; public: GwmBasicGWRAlgorithm(); @@ -91,8 +92,8 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, bool hasFTest() const; void setHasFTest(bool value); - int groupSize() const; - void setGroupSize(int groupSize); + std::size_t groupSize() const; + void setGroupSize(const std::size_t groupSize) override; BandwidthSelectionCriterionType bandwidthSelectionCriterionType() const; void setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType); @@ -145,9 +146,9 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, public: // IParallelalbe interface int parallelAbility() const override; - ParallelType parallelType() const override; + gwm::ParallelType parallelType() const override; - void setParallelType(const ParallelType &type) override; + void setParallelType(const gwm::ParallelType &type) override; public: // IOpenmpParallelable interface void setOmpThreadNum(const int threadNum) override; @@ -265,7 +266,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, CalcTrQtQFunction mCalcTrQtQFunction = &GwmBasicGWRAlgorithm::calcTrQtQSerial; CalcDiagBFunction mCalcDiagBFunction = &GwmBasicGWRAlgorithm::calcDiagBSerial; - IParallelalbe::ParallelType mParallelType = IParallelalbe::ParallelType::SerialOnly; + gwm::ParallelType mParallelType = gwm::ParallelType::SerialOnly; int mOmpThreadNum = 8; int mGpuId = 0; int mGroupSize = 64; @@ -351,17 +352,20 @@ inline IndepVarsCriterionList GwmBasicGWRAlgorithm::indepVarSelectorCriterions() inline int GwmBasicGWRAlgorithm::parallelAbility() const { - return IParallelalbe::SerialOnly - #ifdef ENABLE_OpenMP - | IParallelalbe::OpenMP - #endif - #ifdef ENABLE_CUDA - | IParallelalbe::CUDA - #endif - ; + int ability = gwm::SerialOnly; +#ifdef ENABLE_OpenMP + ability |= gwm::OpenMP; +#endif +#ifdef ENABLE_CUDA + ability |= gwm::CUDA; +#endif +#ifdef ENABLE_MPI + ability |= gwm::MPI; +#endif + return ability; } -inline IParallelalbe::ParallelType GwmBasicGWRAlgorithm::parallelType() const +inline gwm::ParallelType GwmBasicGWRAlgorithm::parallelType() const { return mParallelType; } diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index fec5a4c..b7da33d 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmgeneralizedgwralgorithm.h" +#include "gwmgeneralizedgwralgorithm.h" //#include "GWmodel/GWmodel.h" //#include "gwmggwrbandwidthselectionthread.h" @@ -952,22 +952,22 @@ void GwmGeneralizedGWRAlgorithm::createResultLayer(CreateResultLayerData data,QS void GwmGeneralizedGWRAlgorithm::setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) { mBandwidthSelectionCriterionType = bandwidthSelectionCriterionType; - QMap, BandwidthSelectCriterionFunction> mapper = { - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), + QMap, BandwidthSelectCriterionFunction> mapper = { + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp), #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp), #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial) + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial) }; mBandwidthSelectCriterionFunction = mapper[qMakePair(bandwidthSelectionCriterionType, mParallelType)]; } -void GwmGeneralizedGWRAlgorithm::setParallelType(const IParallelalbe::ParallelType &type) +void GwmGeneralizedGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { if (type & parallelAbility()) { @@ -1065,26 +1065,26 @@ mat GwmGeneralizedGWRAlgorithm::CiMat(const mat& x, const vec &w) bool GwmGeneralizedGWRAlgorithm::setFamily(Family family){ mFamily = family; - QMap, GGWRRegressionFunction> mapper = { - std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), + QMap, GGWRRegressionFunction> mapper = { + std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionPoissonOmp), #endif // std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), - std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial), + std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionBinomialOmp), #endif // std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial) }; mGGWRRegressionFunction = mapper[qMakePair(family, mParallelType)]; - QMap, CalWtFunction> mapper1 = { - std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), + QMap, CalWtFunction> mapper1 = { + std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::PoissonWtOmp), #endif // std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), - std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::BinomialWtSerial), + std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::BinomialWtSerial), #ifdef ENABLE_OpenMP std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::BinomialWtOmp), #endif diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.h b/src/TaskThread/gwmgeneralizedgwralgorithm.h index 24148fa..a03e516 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.h +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMGGWRALGORITHM_H +#ifndef GWMGGWRALGORITHM_H #define GWMGGWRALGORITHM_H #include "gwmbasicgwralgorithm.h" @@ -57,7 +57,7 @@ struct GwmGLMDiagnostic } }; -class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public IOpenmpParallelable +class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public gwm::IParallelizable, public gwm::IParallelOpenmpEnabled { public: enum Family @@ -108,8 +108,8 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor public: // IParallelalbe interface int parallelAbility() const override; - ParallelType parallelType() const override; - void setParallelType(const ParallelType &type) override; + gwm::ParallelType parallelType() const override; + void setParallelType(const gwm::ParallelType &type) override; public: // IOpenmpParallelable interface @@ -222,7 +222,7 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial; GwmGGWRBandwidthSizeSelector mBandwidthSizeSelector; - IParallelalbe::ParallelType mParallelType = IParallelalbe::ParallelType::SerialOnly; + gwm::ParallelType mParallelType = gwm::ParallelType::SerialOnly; int mOmpThreadNum = 8; GwmGeneralizedLinearModel* mGlm = nullptr; @@ -315,7 +315,7 @@ inline void GwmGeneralizedGWRAlgorithm::setIsAutoselectBandwidth(bool value) inline int GwmGeneralizedGWRAlgorithm::parallelAbility() const { - return IParallelalbe::SerialOnly + return gwm::SerialOnly #ifdef ENABLE_OpenMP | IParallelalbe::OpenMP #endif @@ -323,7 +323,7 @@ inline int GwmGeneralizedGWRAlgorithm::parallelAbility() const ; } -inline IParallelalbe::ParallelType GwmGeneralizedGWRAlgorithm::parallelType() const +inline gwm::ParallelType GwmGeneralizedGWRAlgorithm::parallelType() const { return mParallelType; } diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index a7752cf..a799c00 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.cpp +++ b/src/TaskThread/gwmrobustgwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmrobustgwralgorithm.h" +#include "gwmrobustgwralgorithm.h" #include @@ -233,14 +233,14 @@ void GwmRobustGWRAlgorithm::createResultLayer(CreateResultLayerData data) mResultLayer->commitChanges(); } -void GwmRobustGWRAlgorithm::setParallelType(const IParallelalbe::ParallelType &type) +void GwmRobustGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { GwmBasicGWRAlgorithm::setParallelType(type); if (type & parallelAbility()) { mParallelType = type; switch (type) { - case IParallelalbe::ParallelType::SerialOnly: + case gwm::ParallelType::SerialOnly: mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixSerial; break; #ifdef ENABLE_OpenMP diff --git a/src/TaskThread/gwmrobustgwralgorithm.h b/src/TaskThread/gwmrobustgwralgorithm.h index 02b4a69..1c7b31b 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.h +++ b/src/TaskThread/gwmrobustgwralgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMROBUSTGWRTASKTHREAD_H +#ifndef GWMROBUSTGWRTASKTHREAD_H #define GWMROBUSTGWRTASKTHREAD_H #include "TaskThread/gwmgeographicalweightedregressionalgorithm.h" @@ -27,7 +27,7 @@ class GwmRobustGWRAlgorithm: public GwmBasicGWRAlgorithm mat regression(const mat& x, const vec& y) override; public: - void setParallelType(const ParallelType &type) override; + void setParallelType(const gwm::ParallelType &type) override; int parallelAbility() const override; protected: @@ -88,7 +88,7 @@ inline void GwmRobustGWRAlgorithm::setFiltered(bool value) inline int GwmRobustGWRAlgorithm::parallelAbility() const { - return IParallelalbe::SerialOnly + return gwm::SerialOnly #ifdef ENABLE_OpenMP | IParallelalbe::OpenMP #endif diff --git a/src/TaskThread/iparallelable.h b/src/TaskThread/iparallelable.h index c0828d4..7ac3f10 100644 --- a/src/TaskThread/iparallelable.h +++ b/src/TaskThread/iparallelable.h @@ -1,4 +1,4 @@ -#ifndef IPARALLELABLE_H +#ifndef IPARALLELABLE_H #define IPARALLELABLE_H struct IParallelalbe diff --git a/src/gwmggwroptionsdialog.cpp b/src/gwmggwroptionsdialog.cpp index 6ee5c5e..d37efa6 100644 --- a/src/gwmggwroptionsdialog.cpp +++ b/src/gwmggwroptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmggwroptionsdialog.h" +#include "gwmggwroptionsdialog.h" #include "ui_gwmggwroptionsdialog.h" #include #include @@ -487,20 +487,20 @@ void GwmGGWROptionsDialog::updateFields() // 并行设置 if (ui->mCalcParallelNoneRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } else if (ui->mCalcParallelMultithreadRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::OpenMP); + mTaskThread->setParallelType(gwm::OpenMP); mTaskThread->setOmpThreadNum(ui->mThreadNum->value()); } else if (ui->mCalcParallelGPURadio->isChecked() && !ui->mDistTypeDmatRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::CUDA); + mTaskThread->setParallelType(gwm::CUDA); } else { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } // 其他设置 mTaskThread->setHasHatMatrix(ui->cbxHatmatrix->isChecked()); diff --git a/src/gwmgwroptionsdialog.cpp b/src/gwmgwroptionsdialog.cpp index b983264..83c11b4 100644 --- a/src/gwmgwroptionsdialog.cpp +++ b/src/gwmgwroptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmgwroptionsdialog.h" +#include "gwmgwroptionsdialog.h" #include "ui_gwmgwroptionsdialog.h" #include @@ -560,22 +560,22 @@ void GwmGWROptionsDialog::updateFields() // 并行设置 if (ui->mCalcParallelNoneRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } else if (ui->mCalcParallelMultithreadRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::OpenMP); + mTaskThread->setParallelType(gwm::OpenMP); mTaskThread->setOmpThreadNum(ui->mThreadNum->value()); } else if (ui->mCalcParallelGPURadio->isChecked() && !ui->mDistTypeDmatRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::CUDA); + mTaskThread->setParallelType(gwm::CUDA); mTaskThread->setGroupSize(ui->mSampleGroupSize->value()); mTaskThread->setGPUId(ui->mGPUSelection->currentIndex()); } else { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } // 其他设置 mTaskThread->setHasHatMatrix(ui->cbxHatmatrix->isChecked()); diff --git a/src/gwmrobustgwroptionsdialog.cpp b/src/gwmrobustgwroptionsdialog.cpp index 52af16d..ecfa65c 100644 --- a/src/gwmrobustgwroptionsdialog.cpp +++ b/src/gwmrobustgwroptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmrobustgwroptionsdialog.h" +#include "gwmrobustgwroptionsdialog.h" #include "ui_gwmrobustgwroptionsdialog.h" #include #include @@ -480,22 +480,22 @@ void GwmRobustGWROptionsDialog::updateFields() // 并行设置 if (ui->mCalcParallelNoneRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } else if (ui->mCalcParallelMultithreadRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::OpenMP); + mTaskThread->setParallelType(gwm::OpenMP); mTaskThread->setOmpThreadNum(ui->mThreadNum->value()); } else if (ui->mCalcParallelGPURadio->isChecked() && !ui->mDistTypeDmatRadio->isChecked()) { - mTaskThread->setParallelType(IParallelalbe::CUDA); + mTaskThread->setParallelType(gwm::CUDA); mTaskThread->setGroupSize(ui->mSampleGroupSize->value()); mTaskThread->setGPUId(ui->mGPUSelection->currentIndex()); } else { - mTaskThread->setParallelType(IParallelalbe::SerialOnly); + mTaskThread->setParallelType(gwm::SerialOnly); } // 其他设置 mTaskThread->setHasHatMatrix(ui->cbxHatmatrix->isChecked()); From f5a9e665f3c1f9b5ad4b70333be4ab2a8b00fa0f Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Wed, 12 Nov 2025 14:29:27 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20basicgwr=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=9A=E6=96=B0=E5=A2=9E=20spatialweight=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=B8=8E=E7=BB=93=E6=9E=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/gwmlayerbasicgwritem.cpp | 26 +++-- src/Model/gwmlayerbasicgwritem.h | 10 +- src/Model/gwmlayercollinearitygwritem.cpp | 25 +++-- src/Model/gwmlayercollinearitygwritem.h | 10 +- src/Model/gwmlayerggwritem.cpp | 4 +- src/Model/gwmlayergtwritem.cpp | 6 +- src/Model/gwmlayergtwritem.h | 6 +- src/Model/gwmlayergwpcaitem.cpp | 6 +- src/Model/gwmlayergwpcaitem.h | 6 +- src/Model/gwmlayergwssitem.cpp | 25 +++-- src/Model/gwmlayergwssitem.h | 6 +- src/Model/gwmlayerscalablegwritem.cpp | 23 +++-- src/Model/gwmlayerscalablegwritem.h | 10 +- .../gwmpropertycollinearitygwrtab.cpp | 8 +- src/PropertyPanelTabs/gwmpropertyggwrtab.cpp | 8 +- src/PropertyPanelTabs/gwmpropertygwrtab.cpp | 8 +- src/PropertyPanelTabs/gwmpropertygwsstab.cpp | 8 +- .../gwmpropertyscalablegwrtab.cpp | 13 ++- src/TaskThread/gwmbandwidthsizeselector.cpp | 23 ++--- src/TaskThread/gwmbandwidthsizeselector.h | 4 +- src/TaskThread/gwmbasicgwralgorithm.cpp | 94 +++++++++++-------- src/TaskThread/gwmbasicgwralgorithm.h | 8 +- src/TaskThread/gwmgeneralizedgwralgorithm.cpp | 79 +++++++++------- src/TaskThread/gwmgeneralizedgwralgorithm.h | 8 +- ...eographicalweightedregressionalgorithm.cpp | 9 +- src/TaskThread/gwmgtwralgorithm.cpp | 4 +- src/TaskThread/gwmgwaveragetaskthread.cpp | 11 +-- src/TaskThread/gwmgwaveragetaskthread.h | 12 +-- src/TaskThread/gwmgwcorrelationtaskthread.cpp | 3 +- src/TaskThread/gwmgwpcataskthread.cpp | 27 ++++-- src/TaskThread/gwmgwpcataskthread.h | 5 +- .../gwmlocalcollinearitygwralgorithm.cpp | 25 +++-- .../gwmlocalcollinearitygwralgorithm.h | 6 +- src/TaskThread/gwmrobustgwralgorithm.cpp | 7 +- src/TaskThread/gwmrobustgwralgorithm.h | 6 +- src/TaskThread/gwmscalablegwralgorithm.cpp | 23 +++-- src/TaskThread/gwmscalablegwralgorithm.h | 6 +- src/TaskThread/gwmspatialmonoscalealgorithm.h | 12 +-- src/gwmapp.cpp | 8 +- src/gwmggwroptionsdialog.cpp | 14 +-- src/gwmggwroptionsdialog.h | 4 +- src/gwmgwaverageoptionsdialog.cpp | 18 ++-- src/gwmgwaverageoptionsdialog.h | 4 +- src/gwmgwpcaoptionsdialog.cpp | 16 ++-- src/gwmgwpcaoptionsdialog.h | 4 +- src/gwmgwroptionsdialog.cpp | 14 +-- src/gwmgwroptionsdialog.h | 4 +- src/gwmlcrgwroptionsdialog.cpp | 16 ++-- src/gwmlcrgwroptionsdialog.h | 4 +- src/gwmrobustgwroptionsdialog.cpp | 14 +-- src/gwmrobustgwroptionsdialog.h | 4 +- src/gwmscalablegwroptionsdialog.cpp | 16 ++-- src/gwmscalablegwroptionsdialog.h | 4 +- 53 files changed, 408 insertions(+), 316 deletions(-) diff --git a/src/Model/gwmlayerbasicgwritem.cpp b/src/Model/gwmlayerbasicgwritem.cpp index 6c0ea29..8cc96e7 100644 --- a/src/Model/gwmlayerbasicgwritem.cpp +++ b/src/Model/gwmlayerbasicgwritem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayerbasicgwritem.h" +#include "gwmlayerbasicgwritem.h" #include "gwmlayergroupitem.h" #include "TaskThread/gwmbasicgwralgorithm.h" @@ -10,7 +10,7 @@ GwmLayerBasicGWRItem::GwmLayerBasicGWRItem(GwmLayerItem* parent, QgsVectorLayer* mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = GwmBandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); mDiagnostic = taskThread->diagnostic(); mBetas = mat(taskThread->betas()); mModelSelModels = taskThread->indepVarSelectorCriterions(); @@ -88,8 +88,15 @@ bool GwmLayerBasicGWRItem::readXml(QDomNode &node) { double bandwidth = weightNode.attribute("bandwidth").toDouble(); bool adaptive = weightNode.attribute("adaptive").toInt(); - GwmBandwidthWeight::KernelFunctionType kernel = GwmBandwidthWeight::KernelFunctionTypeNameMapper.value(weightNode.attribute("kernel")); - mWeight = GwmBandwidthWeight(bandwidth, adaptive, kernel); + auto it = std::find_if( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.begin(), + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end(), + [&](const auto& kv){ return kv.second == weightNode.attribute("kernel").toStdString(); } + ); + gwm::BandwidthWeight::KernelFunctionType kernel = + it != gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end() ? it->first : gwm::BandwidthWeight::Gaussian; + + mWeight = gwm::BandwidthWeight(bandwidth, adaptive, kernel); } else return false; @@ -214,7 +221,7 @@ bool GwmLayerBasicGWRItem::readXml(QDomNode &node) { double size = bandwidthNode.attribute("size").toDouble(); double criterion = bandwidthNode.attribute("criterion").toDouble(); - mBandwidthSelScores.append(qMakePair(size, criterion)); + mBandwidthSelScores.push_back(std::make_pair(size, criterion)); } bandwidthNode = bandwidthNode.nextSiblingElement("bandwidth"); } @@ -331,7 +338,10 @@ bool GwmLayerBasicGWRItem::writeXml(QDomNode &node, QDomDocument &doc) nodeAnalyse.appendChild(nodeIndepVarList); QDomElement nodeBandwidth = doc.createElement("weight"); - nodeBandwidth.setAttribute("kernel", GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(mWeight.kernel())); + nodeBandwidth.setAttribute( + "kernel", + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(mWeight.kernel())) + ); nodeBandwidth.setAttribute("bandwidth", mWeight.bandwidth()); nodeBandwidth.setAttribute("adaptive", mWeight.adaptive()); nodeAnalyse.appendChild(nodeBandwidth); @@ -523,12 +533,12 @@ QList, double> > GwmLayerBasicGWRItem::modelSelModels() return mModelSelModels; } -QList > GwmLayerBasicGWRItem::bandwidthSelScores() const +BandwidthCriterionList GwmLayerBasicGWRItem::bandwidthSelScores() const { return mBandwidthSelScores; } -GwmBandwidthWeight GwmLayerBasicGWRItem::weight() const +gwm::BandwidthWeight GwmLayerBasicGWRItem::weight() const { return mWeight; } diff --git a/src/Model/gwmlayerbasicgwritem.h b/src/Model/gwmlayerbasicgwritem.h index 4004ec6..09a4dbb 100644 --- a/src/Model/gwmlayerbasicgwritem.h +++ b/src/Model/gwmlayerbasicgwritem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERBASICGWRITEM_H +#ifndef GWMLAYERBASICGWRITEM_H #define GWMLAYERBASICGWRITEM_H #include "prefix.h" @@ -49,9 +49,9 @@ class GwmLayerBasicGWRItem : public GwmLayerVectorItem QList, double> > modelSelModels() const; - QList > bandwidthSelScores() const; + BandwidthCriterionList bandwidthSelScores() const; - GwmBandwidthWeight weight() const; + gwm::BandwidthWeight weight() const; GwmBasicGWRAlgorithm::OLSVar OLSResults() const; @@ -59,11 +59,11 @@ class GwmLayerBasicGWRItem : public GwmLayerVectorItem int mDataPointsSize; GwmVariable mDepVar; QList mIndepVars; - GwmBandwidthWeight mWeight; + gwm::BandwidthWeight mWeight; GwmDiagnostic mDiagnostic; arma::mat mBetas; QList, double> > mModelSelModels; - QList > mBandwidthSelScores; + BandwidthCriterionList mBandwidthSelScores; GwmBasicGWRAlgorithm::FTestResultPack mFTestResults; GwmBasicGWRAlgorithm::OLSVar mOLSVar; bool isRegressionPointGiven; diff --git a/src/Model/gwmlayercollinearitygwritem.cpp b/src/Model/gwmlayercollinearitygwritem.cpp index b5562de..f6cba79 100644 --- a/src/Model/gwmlayercollinearitygwritem.cpp +++ b/src/Model/gwmlayercollinearitygwritem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayercollinearitygwritem.h" +#include "gwmlayercollinearitygwritem.h" #include "gwmlayergroupitem.h" GwmLayerCollinearityGWRItem::GwmLayerCollinearityGWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, const GwmLocalCollinearityGWRAlgorithm* taskThread) @@ -9,7 +9,7 @@ GwmLayerCollinearityGWRItem::GwmLayerCollinearityGWRItem(GwmLayerItem* parent, Q mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = GwmBandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); mDiagnostic = taskThread->dialnostic(); mBetas = mat(taskThread->betas()); //mModelSelModels = taskThread->indepVarSelectorCriterions(); @@ -88,8 +88,14 @@ bool GwmLayerCollinearityGWRItem::readXml(QDomNode &node) { double bandwidth = weightNode.attribute("bandwidth").toDouble(); bool adaptive = weightNode.attribute("adaptive").toInt(); - GwmBandwidthWeight::KernelFunctionType kernel = GwmBandwidthWeight::KernelFunctionTypeNameMapper.value(weightNode.attribute("kernel")); - mWeight = GwmBandwidthWeight(bandwidth, adaptive, kernel); + auto it = std::find_if( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.begin(), + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end(), + [&](const auto& kv){ return kv.second == weightNode.attribute("kernel").toStdString(); } + ); + gwm::BandwidthWeight::KernelFunctionType kernel = + it != gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end() ? it->first : gwm::BandwidthWeight::Gaussian; + mWeight = gwm::BandwidthWeight(bandwidth, adaptive, kernel); } else return false; @@ -142,7 +148,7 @@ bool GwmLayerCollinearityGWRItem::readXml(QDomNode &node) { double size = bandwidthNode.attribute("size").toDouble(); double criterion = bandwidthNode.attribute("criterion").toDouble(); - mBandwidthSelScores.append(qMakePair(size, criterion)); + mBandwidthSelScores.push_back(std::make_pair(size, criterion)); } bandwidthNode = bandwidthNode.nextSiblingElement("bandwidth"); } @@ -190,7 +196,10 @@ bool GwmLayerCollinearityGWRItem::writeXml(QDomNode &node, QDomDocument &doc) nodeAnalyse.appendChild(nodeIndepVarList); QDomElement nodeBandwidth = doc.createElement("weight"); - nodeBandwidth.setAttribute("kernel", GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(mWeight.kernel())); + nodeBandwidth.setAttribute( + "kernel", + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(mWeight.kernel())) + ); nodeBandwidth.setAttribute("bandwidth", mWeight.bandwidth()); nodeBandwidth.setAttribute("adaptive", mWeight.adaptive()); nodeAnalyse.appendChild(nodeBandwidth); @@ -241,7 +250,7 @@ QList GwmLayerCollinearityGWRItem::indepVars() const return mIndepVars; } -GwmBandwidthWeight GwmLayerCollinearityGWRItem::weight() const +gwm::BandwidthWeight GwmLayerCollinearityGWRItem::weight() const { return mWeight; } @@ -256,7 +265,7 @@ arma::mat GwmLayerCollinearityGWRItem::betas() const return mBetas; } -QList > GwmLayerCollinearityGWRItem::bandwidthSelScores() const +BandwidthCriterionList GwmLayerCollinearityGWRItem::bandwidthSelScores() const { return mBandwidthSelScores; } diff --git a/src/Model/gwmlayercollinearitygwritem.h b/src/Model/gwmlayercollinearitygwritem.h index a6b4b0a..34b3026 100644 --- a/src/Model/gwmlayercollinearitygwritem.h +++ b/src/Model/gwmlayercollinearitygwritem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERCOLLINEARUTYGWRITEM_H +#ifndef GWMLAYERCOLLINEARUTYGWRITEM_H #define GWMLAYERCOLLINEARUTYGWRITEM_H #include "prefix.h" @@ -30,13 +30,13 @@ class GwmLayerCollinearityGWRItem : public GwmLayerVectorItem QList indepVars() const; - GwmBandwidthWeight weight() const; + gwm::BandwidthWeight weight() const; GwmDiagnostic diagnostic() const; arma::mat betas() const; - QList > bandwidthSelScores() const; + BandwidthCriterionList bandwidthSelScores() const; bool getIsRegressionPointGiven() const; @@ -54,11 +54,11 @@ class GwmLayerCollinearityGWRItem : public GwmLayerVectorItem int mDataPointsSize; GwmVariable mDepVar; QList mIndepVars; - GwmBandwidthWeight mWeight; + gwm::BandwidthWeight mWeight; GwmDiagnostic mDiagnostic; arma::mat mBetas; //QList, double> > mModelSelModels; - QList > mBandwidthSelScores; + BandwidthCriterionList mBandwidthSelScores; //GwmBasicGWRAlgorithm::FTestResultPack mFTestResults; bool isRegressionPointGiven; diff --git a/src/Model/gwmlayerggwritem.cpp b/src/Model/gwmlayerggwritem.cpp index 0291810..d71d5be 100644 --- a/src/Model/gwmlayerggwritem.cpp +++ b/src/Model/gwmlayerggwritem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayerggwritem.h" +#include "gwmlayerggwritem.h" GwmLayerGGWRItem::GwmLayerGGWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, const GwmGeneralizedGWRAlgorithm* taskThread) :GwmLayerBasicGWRItem(parent,vector) @@ -8,7 +8,7 @@ GwmLayerGGWRItem::GwmLayerGGWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = GwmBandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); mBetas = mat(taskThread->betas()); isBandwidthOptimized = taskThread->autoselectBandwidth(); mBandwidthSelScores = taskThread->bandwidthSelectorCriterions(); diff --git a/src/Model/gwmlayergtwritem.cpp b/src/Model/gwmlayergtwritem.cpp index 879af66..70e0562 100644 --- a/src/Model/gwmlayergtwritem.cpp +++ b/src/Model/gwmlayergtwritem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayergtwritem.h" +#include "gwmlayergtwritem.h" #include "gwmlayergroupitem.h" GwmLayerGTWRItem::GwmLayerGTWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, const GwmGTWRAlgorithm *taskThread) @@ -129,7 +129,7 @@ bool GwmLayerGTWRItem::readXml(QDomNode &node) { double size = bandwidthNode.attribute("size").toDouble(); double criterion = bandwidthNode.attribute("criterion").toDouble(); - mBandwidthSelScores.append(qMakePair(size, criterion)); + mBandwidthSelScores.push_back(std::make_pair(size, criterion)); } bandwidthNode = bandwidthNode.nextSiblingElement("bandwidth"); } @@ -251,7 +251,7 @@ QList GwmLayerGTWRItem::indepVars() const return mIndepVars; } -QList > GwmLayerGTWRItem::bandwidthSelScores() const +BandwidthCriterionList GwmLayerGTWRItem::bandwidthSelScores() const { return mBandwidthSelScores; } diff --git a/src/Model/gwmlayergtwritem.h b/src/Model/gwmlayergtwritem.h index 0ed97a6..082ba5d 100644 --- a/src/Model/gwmlayergtwritem.h +++ b/src/Model/gwmlayergtwritem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERGTWRITEM_H +#ifndef GWMLAYERGTWRITEM_H #define GWMLAYERGTWRITEM_H #include "prefix.h" @@ -39,7 +39,7 @@ class GwmLayerGTWRItem : public GwmLayerVectorItem QList indepVars() const; - QList > bandwidthSelScores() const; + BandwidthCriterionList bandwidthSelScores() const; GwmBandwidthWeight weight() const; @@ -50,7 +50,7 @@ class GwmLayerGTWRItem : public GwmLayerVectorItem GwmBandwidthWeight mWeight; GwmDiagnostic mDiagnostic; arma::mat mBetas; - QList > mBandwidthSelScores; + BandwidthCriterionList mBandwidthSelScores; bool isRegressionPointGiven; bool isBandwidthOptimized; diff --git a/src/Model/gwmlayergwpcaitem.cpp b/src/Model/gwmlayergwpcaitem.cpp index d08e1d8..704ba52 100644 --- a/src/Model/gwmlayergwpcaitem.cpp +++ b/src/Model/gwmlayergwpcaitem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayergwpcaitem.h" +#include "gwmlayergwpcaitem.h" #include "gwmlayergroupitem.h" #include @@ -52,7 +52,7 @@ bool GwmLayerGWPCAItem::readXml(QDomNode &node) { double size = bandwidthNode.attribute("size").toDouble(); double criterion = bandwidthNode.attribute("criterion").toDouble(); - mBandwidthSelScores.append(qMakePair(size, criterion)); + mBandwidthSelScores.push_back(std::make_pair(size, criterion)); } } } @@ -168,7 +168,7 @@ GwmBandwidthWeight GwmLayerGWPCAItem::weight() const return mWeight; } -QList > GwmLayerGWPCAItem::bandwidthSelScores() const +BandwidthCriterionList GwmLayerGWPCAItem::bandwidthSelScores() const { return mBandwidthSelScores; } diff --git a/src/Model/gwmlayergwpcaitem.h b/src/Model/gwmlayergwpcaitem.h index 4ed53c2..578b106 100644 --- a/src/Model/gwmlayergwpcaitem.h +++ b/src/Model/gwmlayergwpcaitem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERGWPCAITEM_H +#ifndef GWMLAYERGWPCAITEM_H #define GWMLAYERGWPCAITEM_H #include "prefix.h" @@ -35,7 +35,7 @@ class GwmLayerGWPCAItem : public GwmLayerVectorItem return isBandwidthOptimized; } - QList > bandwidthSelScores() const; + BandwidthCriterionList bandwidthSelScores() const; public: int mK = 0; @@ -46,7 +46,7 @@ class GwmLayerGWPCAItem : public GwmLayerVectorItem cube mScores; mat mVariance; GwmBandwidthWeight mWeight; - QList > mBandwidthSelScores; + BandwidthCriterionList mBandwidthSelScores; }; diff --git a/src/Model/gwmlayergwssitem.cpp b/src/Model/gwmlayergwssitem.cpp index bed8de7..76f174f 100644 --- a/src/Model/gwmlayergwssitem.cpp +++ b/src/Model/gwmlayergwssitem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayergwssitem.h" +#include "gwmlayergwssitem.h" #include "gwmlayergroupitem.h" @@ -10,7 +10,7 @@ GwmLayerGWSSItem::GwmLayerGWSSItem(GwmLayerItem* parentItem, QgsVectorLayer* vec auto taskMeta = taskThread->meta(); mDataPointsSize = taskMeta.layer->featureCount(); mVariables = taskMeta.variables; - mBandwidth = new GwmBandwidthWeight(taskMeta.weightBandwidthSize, taskMeta.weightBandwidthAdaptive, GwmBandwidthWeight::KernelFunctionType(taskMeta.weightBandwidthKernel)); + mBandwidth = new gwm::BandwidthWeight(taskMeta.weightBandwidthSize, taskMeta.weightBandwidthAdaptive, gwm::BandwidthWeight::KernelFunctionType(taskMeta.weightBandwidthKernel)); mQuantile = taskThread->quantile(); mResultList = taskThread->resultlist(); @@ -34,7 +34,7 @@ GwmLayerGWSSItem::GwmLayerGWSSItem(GwmLayerItem* parentItem, QgsVectorLayer* vec } else { - mBandwidth = new GwmBandwidthWeight(); + mBandwidth = new gwm::BandwidthWeight(); } } @@ -91,7 +91,7 @@ GwmLayerGWSSItem::GwmLayerGWSSItem(GwmLayerItem* parentItem, QgsVectorLayer* vec } else { - mBandwidth = new GwmBandwidthWeight(); + mBandwidth = new gwm::BandwidthWeight(); } } @@ -145,8 +145,14 @@ bool GwmLayerGWSSItem::readXml(QDomNode &node) { double bandwidth = weightNode.attribute("bandwidth").toDouble(); bool adaptive = weightNode.attribute("adaptive").toInt(); - GwmBandwidthWeight::KernelFunctionType kernel = GwmBandwidthWeight::KernelFunctionTypeNameMapper.value(weightNode.attribute("kernel")); - mBandwidth = new GwmBandwidthWeight(bandwidth, adaptive, kernel); + auto it = std::find_if( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.begin(), + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end(), + [&](const auto& kv){ return kv.second == weightNode.attribute("kernel").toStdString(); } + ); + gwm::BandwidthWeight::KernelFunctionType kernel = + it != gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end() ? it->first : gwm::BandwidthWeight::Gaussian; + mBandwidth = new gwm::BandwidthWeight(bandwidth, adaptive, kernel); } else return false; @@ -261,7 +267,12 @@ bool GwmLayerGWSSItem::writeXml(QDomNode &node, QDomDocument &doc) nodeAnalyse.appendChild(nodeVariableList); QDomElement nodeBandwidth = doc.createElement("weight"); - nodeBandwidth.setAttribute("kernel", GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(mBandwidth->kernel())); + nodeBandwidth.setAttribute( + "kernel", + QString::fromStdString( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(mBandwidth->kernel()) + ) + ); nodeBandwidth.setAttribute("bandwidth", mBandwidth->bandwidth()); nodeBandwidth.setAttribute("adaptive", mBandwidth->adaptive()); nodeAnalyse.appendChild(nodeBandwidth); diff --git a/src/Model/gwmlayergwssitem.h b/src/Model/gwmlayergwssitem.h index f02a294..5ef565d 100644 --- a/src/Model/gwmlayergwssitem.h +++ b/src/Model/gwmlayergwssitem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERGWSSITEM_H +#ifndef GWMLAYERGWSSITEM_H #define GWMLAYERGWSSITEM_H #include "gwmlayervectoritem.h" @@ -55,7 +55,7 @@ class GwmLayerGWSSItem : public GwmLayerVectorItem return mVariablesY; } - GwmBandwidthWeight* bandwidth() const + gwm::BandwidthWeight* bandwidth() const { return mBandwidth; } @@ -90,7 +90,7 @@ class GwmLayerGWSSItem : public GwmLayerVectorItem int mDataPointsSize; QList mVariables; QList mVariablesY; - GwmBandwidthWeight* mBandwidth; + gwm::BandwidthWeight* mBandwidth; bool mQuantile; // correlation带宽信息 QList mBandwidthWeights; diff --git a/src/Model/gwmlayerscalablegwritem.cpp b/src/Model/gwmlayerscalablegwritem.cpp index e20cb3d..1b2c5c3 100644 --- a/src/Model/gwmlayerscalablegwritem.cpp +++ b/src/Model/gwmlayerscalablegwritem.cpp @@ -1,4 +1,4 @@ -#include "gwmlayerscalablegwritem.h" +#include "gwmlayerscalablegwritem.h" GwmLayerScalableGWRItem::GwmLayerScalableGWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, const GwmScalableGWRAlgorithm* taskThread) : GwmLayerVectorItem(parent, vector) @@ -8,7 +8,7 @@ GwmLayerScalableGWRItem::GwmLayerScalableGWRItem(GwmLayerItem* parent, QgsVector mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = GwmBandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); mDistanceType = taskThread->spatialWeight().distance()->type(); mDiagnostic = taskThread->diagnostic(); mBetas = mat(taskThread->betas()); @@ -80,8 +80,14 @@ bool GwmLayerScalableGWRItem::readXml(QDomNode &node) { double bandwidth = weightNode.attribute("bandwidth").toDouble(); bool adaptive = weightNode.attribute("adaptive").toInt(); - GwmBandwidthWeight::KernelFunctionType kernel = GwmBandwidthWeight::KernelFunctionTypeNameMapper.value(weightNode.attribute("kernel")); - mWeight = GwmBandwidthWeight(bandwidth, adaptive, kernel); + auto it = std::find_if( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.begin(), + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end(), + [&](const auto& kv){ return kv.second == weightNode.attribute("kernel").toStdString(); } + ); + gwm::BandwidthWeight::KernelFunctionType kernel = + it != gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end() ? it->first : gwm::BandwidthWeight::Gaussian; + mWeight = gwm::BandwidthWeight(bandwidth, adaptive, kernel); } else return false; @@ -153,7 +159,10 @@ bool GwmLayerScalableGWRItem::writeXml(QDomNode &node, QDomDocument &doc) nodeAnalyse.appendChild(nodeIndepVarList); QDomElement nodeBandwidth = doc.createElement("weight"); - nodeBandwidth.setAttribute("kernel", GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(mWeight.kernel())); + nodeBandwidth.setAttribute( + "kernel", + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(mWeight.kernel())) + ); nodeBandwidth.setAttribute("bandwidth", mWeight.bandwidth()); nodeBandwidth.setAttribute("adaptive", mWeight.adaptive()); nodeAnalyse.appendChild(nodeBandwidth); @@ -208,7 +217,7 @@ QList GwmLayerScalableGWRItem::indepVars() const return mIndepVars; } -GwmBandwidthWeight GwmLayerScalableGWRItem::weight() const +gwm::BandwidthWeight GwmLayerScalableGWRItem::weight() const { return mWeight; } @@ -223,7 +232,7 @@ arma::mat GwmLayerScalableGWRItem::betas() const return mBetas; } -GwmDistance::DistanceType GwmLayerScalableGWRItem::distanceType() const +gwm::Distance::DistanceType GwmLayerScalableGWRItem::distanceType() const { return mDistanceType; } diff --git a/src/Model/gwmlayerscalablegwritem.h b/src/Model/gwmlayerscalablegwritem.h index 131e2b9..026fee9 100644 --- a/src/Model/gwmlayerscalablegwritem.h +++ b/src/Model/gwmlayerscalablegwritem.h @@ -1,4 +1,4 @@ -#ifndef GWMLAYERSCALABLEGWRITEM_H +#ifndef GWMLAYERSCALABLEGWRITEM_H #define GWMLAYERSCALABLEGWRITEM_H #include "Model/gwmlayerbasicgwritem.h" @@ -31,13 +31,13 @@ class GwmLayerScalableGWRItem : public GwmLayerVectorItem QList indepVars() const; - GwmBandwidthWeight weight() const; + gwm::BandwidthWeight weight() const; GwmDiagnostic diagnostic() const; arma::mat betas() const; - GwmDistance::DistanceType distanceType() const; + gwm::Distance::DistanceType distanceType() const; GwmScalableGWRAlgorithm::ParameterOptimizeCriterionType parameterOptimizeCriterionType() const; @@ -49,8 +49,8 @@ class GwmLayerScalableGWRItem : public GwmLayerVectorItem int mDataPointsSize; GwmVariable mDepVar; QList mIndepVars; - GwmBandwidthWeight mWeight; - GwmDistance::DistanceType mDistanceType; + gwm::BandwidthWeight mWeight; + gwm::Distance::DistanceType mDistanceType; GwmDiagnostic mDiagnostic; arma::mat mBetas; GwmScalableGWRAlgorithm::ParameterOptimizeCriterionType mParameterOptimizeCriterionType; diff --git a/src/PropertyPanelTabs/gwmpropertycollinearitygwrtab.cpp b/src/PropertyPanelTabs/gwmpropertycollinearitygwrtab.cpp index 71eb171..b045f0e 100644 --- a/src/PropertyPanelTabs/gwmpropertycollinearitygwrtab.cpp +++ b/src/PropertyPanelTabs/gwmpropertycollinearitygwrtab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertycollinearitygwrtab.h" +#include "gwmpropertycollinearitygwrtab.h" #include "ui_gwmpropertycollinearitygwrtab.h" @@ -59,8 +59,10 @@ void GwmPropertyCollinearityGWRTab::updateUI() if (!mLayerItem) return; - GwmBandwidthWeight weight = mLayerItem->weight(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->weight(); + ui->lblKernelFunction->setText( + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel())) + ); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { diff --git a/src/PropertyPanelTabs/gwmpropertyggwrtab.cpp b/src/PropertyPanelTabs/gwmpropertyggwrtab.cpp index 2599e99..d423868 100644 --- a/src/PropertyPanelTabs/gwmpropertyggwrtab.cpp +++ b/src/PropertyPanelTabs/gwmpropertyggwrtab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertyggwrtab.h" +#include "gwmpropertyggwrtab.h" #include "ui_gwmpropertyggwrtab.h" #include @@ -58,8 +58,10 @@ void GwmPropertyGGWRTab::updateUI() if (!mLayerItem) return; - GwmBandwidthWeight weight = mLayerItem->weight(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->weight(); + ui->lblKernelFunction->setText( + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel())) + ); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { diff --git a/src/PropertyPanelTabs/gwmpropertygwrtab.cpp b/src/PropertyPanelTabs/gwmpropertygwrtab.cpp index 9933b34..3e92baa 100644 --- a/src/PropertyPanelTabs/gwmpropertygwrtab.cpp +++ b/src/PropertyPanelTabs/gwmpropertygwrtab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertygwrtab.h" +#include "gwmpropertygwrtab.h" #include "ui_gwmpropertygwrtab.h" #include @@ -77,8 +77,10 @@ void GwmPropertyGWRTab::updateUI() if (!mLayerItem) return; - GwmBandwidthWeight weight = mLayerItem->weight(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->weight(); + ui->lblKernelFunction->setText( + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel())) + ); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { diff --git a/src/PropertyPanelTabs/gwmpropertygwsstab.cpp b/src/PropertyPanelTabs/gwmpropertygwsstab.cpp index 4e287e2..9f1fb4c 100644 --- a/src/PropertyPanelTabs/gwmpropertygwsstab.cpp +++ b/src/PropertyPanelTabs/gwmpropertygwsstab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertygwsstab.h" +#include "gwmpropertygwsstab.h" #include "ui_gwmpropertygwsstab.h" #include @@ -43,8 +43,10 @@ void GwmPropertyGWSSTab::updateUI() { if (!mLayerItem) return; - GwmBandwidthWeight weight = mLayerItem->bandwidth(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->bandwidth(); + ui->lblKernelFunction->setText( + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel())) + ); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { diff --git a/src/PropertyPanelTabs/gwmpropertyscalablegwrtab.cpp b/src/PropertyPanelTabs/gwmpropertyscalablegwrtab.cpp index 4c00fa8..5c303c5 100644 --- a/src/PropertyPanelTabs/gwmpropertyscalablegwrtab.cpp +++ b/src/PropertyPanelTabs/gwmpropertyscalablegwrtab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertyscalablegwrtab.h" +#include "gwmpropertyscalablegwrtab.h" #include "ui_gwmpropertyscalablegwrtab.h" #include @@ -37,8 +37,10 @@ void GwmPropertyScalableGWRTab::updateUI() if (!mLayerItem) return; - GwmBandwidthWeight weight = mLayerItem->weight(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->weight(); + ui->lblKernelFunction->setText( + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel())) + ); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { @@ -53,7 +55,10 @@ void GwmPropertyScalableGWRTab::updateUI() ui->lblBandwidthSize->setText(bwSizeString); } ui->lblRegressionPoints->setText(tr("The same location as observations are used.")); - ui->lblDistanceMetric->setText(tr("%1 distance metric is used.").arg(GwmDistance::TypeNameMapper[mLayerItem->distanceType()])); + ui->lblDistanceMetric->setText( + tr("%1 distance metric is used.") + .arg(QString::fromStdString(gwm::Distance::TypeNameMapper[mLayerItem->distanceType()])) + ); ui->lblNumberDataPoints->setText(QString("%1").arg(mLayerItem->dataPointsSize())); if (!mLayerItem->hasRegressionLayer()) diff --git a/src/TaskThread/gwmbandwidthsizeselector.cpp b/src/TaskThread/gwmbandwidthsizeselector.cpp index 4865b27..9f51944 100644 --- a/src/TaskThread/gwmbandwidthsizeselector.cpp +++ b/src/TaskThread/gwmbandwidthsizeselector.cpp @@ -1,4 +1,4 @@ -#include "gwmbandwidthsizeselector.h" +#include "gwmbandwidthsizeselector.h" #include #include @@ -31,9 +31,9 @@ void GwmBandwidthSizeSelector::PlotBandwidthResult(QVariant data, QwtPlot *plot) //输入数据 QVector xData; QVector yData; - for(auto i = result.constBegin();i!=result.constEnd();++i){ - xData.push_back(i->first); - yData.push_back(i->second); + for (const auto& p : result) { + xData.push_back(p.first); + yData.push_back(p.second); } //设置X与Y坐标范围 //返回xData与yData最大最小值 @@ -58,16 +58,17 @@ GwmBandwidthSizeSelector::GwmBandwidthSizeSelector() } -QList > GwmBandwidthSizeSelector::bandwidthCriterion() const +BandwidthCriterionList GwmBandwidthSizeSelector::bandwidthCriterion() const { - QList > criterions; - for (double key : mBandwidthCriterion.keys()) + BandwidthCriterionList criterions; + for (auto it = mBandwidthCriterion.constBegin(); it != mBandwidthCriterion.constEnd(); ++it) { - criterions.append(qMakePair(key, mBandwidthCriterion[key])); + criterions.push_back(std::make_pair(it.key(), it.value())); } - std::sort(criterions.begin(), criterions.end(), [](const QPair& a, const QPair& b){ - return a.first < b.first; - }); + std::sort(criterions.begin(), criterions.end(), + [](const std::pair& a, const std::pair& b){ + return a.first < b.first; + }); return criterions; } diff --git a/src/TaskThread/gwmbandwidthsizeselector.h b/src/TaskThread/gwmbandwidthsizeselector.h index cff8995..bee494b 100644 --- a/src/TaskThread/gwmbandwidthsizeselector.h +++ b/src/TaskThread/gwmbandwidthsizeselector.h @@ -1,4 +1,4 @@ -#ifndef GWMBANDWIDTHSIZESELECTOR_H +#ifndef GWMBANDWIDTHSIZESELECTOR_H #define GWMBANDWIDTHSIZESELECTOR_H #include @@ -6,7 +6,7 @@ #include "SpatialWeight/gwmspatialweight.h" #include "SpatialWeight/gwmbandwidthweight.h" -typedef QList > BandwidthCriterionList; +typedef std::vector > BandwidthCriterionList; Q_DECLARE_METATYPE(BandwidthCriterionList) struct IBandwidthSizeSelectable diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 2478557..9c50dec 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -34,17 +34,17 @@ GwmEnumValueNameMapper Gw }; -GwmBasicGWRAlgorithm::GwmBasicGWRAlgorithm() : GwmGeographicalWeightedRegressionAlgorithm() +GwmBasicGWRAlgorithm::GwmBasicGWRAlgorithm() : GwmGeographicalWeightedRegressionAlgorithm(), + mGWRCore(std::make_unique()) { - mGWRCore = std::make_unique(); } void GwmBasicGWRAlgorithm::setCanceled(bool canceled) { - mBandwidthSizeSelector.setCanceled(canceled); - mSpatialWeight.distance()->setCanceled(canceled); + // mBandwidthSizeSelector.setCanceled(canceled); + // mSpatialWeight.distance()->setCanceled(canceled); return GwmTaskThread::setCanceled(canceled); } @@ -126,18 +126,23 @@ void GwmBasicGWRAlgorithm::run() - // 优选带宽 + // 优选带宽 if (!checkCanceled() && !hasRegressionLayer() && mIsAutoselectBandwidth) { emit message(QString(tr("Automatically selecting bandwidth ..."))); //emit tick(0, 0); - GwmBandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); + gwm::BandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); mBandwidthSizeSelector.setBandwidth(bandwidthWeight0); double lower = bandwidthWeight0->adaptive() ? 20 : 0.0; double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : mSpatialWeight.distance()->maxDistance(); mBandwidthSizeSelector.setLower(lower); mBandwidthSizeSelector.setUpper(upper); - GwmBandwidthWeight* bandwidthWeight = mBandwidthSizeSelector.optimize(this); + mGWRCore->setCoords(mDataPoints); + mGWRCore->setDependentVariable(mY); + mGWRCore->setIndependentVariables(mX); + mGWRCore->setSpatialWeight(mSpatialWeight); + qDebug()<<"BandwidthWeight"; + gwm::BandwidthWeight* bandwidthWeight = mBandwidthSizeSelector.optimize(mGWRCore.get()); if (bandwidthWeight && !checkCanceled()) { mSpatialWeight.setWeight(bandwidthWeight); @@ -149,7 +154,9 @@ void GwmBasicGWRAlgorithm::run() if (!checkCanceled()) { + qDebug()<<"regression"; mBetas = regression(mX, mY); + qDebug()<<"regressionend"; } if (checkCanceled()) @@ -187,7 +194,7 @@ void GwmBasicGWRAlgorithm::run() } CreateResultLayerData resultLayerData = { -// qMakePair(QString("%1"), mX), + // qMakePair(QString("%1"), mX), qMakePair(QString("%1"), mBetas), qMakePair(QString("y"), mY), qMakePair(QString("yhat"), yhat), @@ -235,7 +242,7 @@ void GwmBasicGWRAlgorithm::run() vec residual = mRegressionLayerY - yhat; resultLayerData = { qMakePair(QString(mDepVar.name), mRegressionLayerY), -// qMakePair(QString("%1"), mRegressionLayerX), + // qMakePair(QString("%1"), mRegressionLayerX), qMakePair(QString("%1"), mBetas), qMakePair(QString("yhat"), yhat), qMakePair(QString("residual"), residual) @@ -245,10 +252,11 @@ void GwmBasicGWRAlgorithm::run() { resultLayerData = { qMakePair(QString("%1"), mBetas) - }; - } - createResultLayer(resultLayerData); + }; } + createResultLayer(resultLayerData); + qDebug()<<"end"; +} if(!checkCanceled()) { @@ -278,7 +286,7 @@ void GwmBasicGWRAlgorithm::initCuda(IGWmodelCUDA* cuda, const mat& x, const vec& cuda->SetRp(r, mRegressionPoints(r, 0), mRegressionPoints(r, 1)); } } - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; if (hasDmat) { for (arma::uword r = 0; r < nRp; r++) @@ -396,19 +404,19 @@ double GwmBasicGWRAlgorithm::indepVarsSelectCriterionCuda(const QListtype() == GwmDistance::DMatDistance; + bool hasDp = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp, nVar, hasRegressionLayer(), nRp, hasDp); initCuda(cuda, x, y); // 计算参数 double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -503,18 +511,18 @@ mat GwmBasicGWRAlgorithm::regressionOmp(const mat &x, const vec &y) mat GwmBasicGWRAlgorithm::regressionCuda(const mat &x, const vec &y) { int nDp = mDataPoints.n_rows, nVar = x.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, x, y); double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -633,18 +641,18 @@ mat GwmBasicGWRAlgorithm::regressionHatmatrixOmp(const mat &x, const vec &y, mat mat GwmBasicGWRAlgorithm::regressionHatmatrixCuda(const mat &x, const vec &y, mat &betasSE, vec &shat, vec &qDiag, mat &S) { int nDp = mDataPoints.n_rows, nVar = x.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, x, y); double p = 2.0, theta = 0.0; bool longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -754,6 +762,7 @@ void GwmBasicGWRAlgorithm::createResultLayer(CreateResultLayerData data,QString double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial(GwmBandwidthWeight* bandwidthWeight) { + int mBandwidthCounter = 0; uword nDp = mDataPoints.n_rows, nVar = mIndepVars.size() + 1; mat betas(nVar, nDp, fill::zeros); vec shat(2, fill::zeros); @@ -777,8 +786,9 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial(GwmBandwidthWeight* { return DBL_MAX; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 10 / nDp, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / nDp, 100); } if(!checkCanceled()) { @@ -857,18 +867,18 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp(GwmBandwidthWeight *ba double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda(GwmBandwidthWeight *bandwidthWeight) { int nDp = mDataPoints.n_rows, nVar = mX.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, mX, mY); double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -904,6 +914,7 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda(GwmBandwidthWeight *b double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial(GwmBandwidthWeight *bandwidthWeight) { + int mBandwidthCounter = 0; uword nDp = mDataPoints.n_rows; vec shat(2, fill::zeros); double cv = 0.0; @@ -926,8 +937,9 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial(GwmBandwidthWeight * { return DBL_MAX; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 10 / nDp, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / nDp, 100); } if(!checkCanceled()) { @@ -1002,18 +1014,18 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *ban double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVCuda(GwmBandwidthWeight *bandwidthWeight) { int nDp = mDataPoints.n_rows, nVar = mX.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, mX, mY); double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -1245,18 +1257,18 @@ double GwmBasicGWRAlgorithm::calcTrQtQOmp() double GwmBasicGWRAlgorithm::calcTrQtQCuda() { int nDp = mDataPoints.n_rows, nVar = mX.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, mX, mY); double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -1357,18 +1369,18 @@ vec GwmBasicGWRAlgorithm::calcDiagBOmp(int i) vec GwmBasicGWRAlgorithm::calcDiagBCuda(int i) { int nDp = mDataPoints.n_rows, nVar = mX.n_cols, nRp = hasRegressionLayer() ? mRegressionPoints.n_rows : mDataPoints.n_rows; - bool hasDmat = mSpatialWeight.distance()->type() == GwmDistance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance; IGWmodelCUDA* cuda = GWCUDA_Create(nDp ,nVar, hasRegressionLayer(), nRp, hasDmat); initCuda(cuda, mX, mY); double p = 2.0, theta = 0.0; double longlat = false; - if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmMinkwoskiDistance* d = mSpatialWeight.distance(); p = d->poly(); theta = d->theta(); } - else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); longlat = d->geographic(); @@ -1414,7 +1426,7 @@ void GwmBasicGWRAlgorithm::initPoints() if (!hasRegressionLayer() && !mHasHatMatrix) { mRegressionPoints = mDataPoints; - if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); d->setFocusPoints(&mRegressionPoints); @@ -1484,7 +1496,7 @@ void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const BandwidthSel void GwmBasicGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - if (mGWRCore) - mGWRCore->setParallelType(type); mParallelType = type; + qDebug()<<"setParallelType"; + mGWRCore->setParallelType(type); } diff --git a/src/TaskThread/gwmbasicgwralgorithm.h b/src/TaskThread/gwmbasicgwralgorithm.h index ae7d5be..47b37a9 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.h +++ b/src/TaskThread/gwmbasicgwralgorithm.h @@ -103,7 +103,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, return { mF1TestResult, mF2TestResult, mF3TestResult, mF4TestResult }; } - BandwidthCriterionList bandwidthSelectorCriterions() const; + gwm::BandwidthCriterionList bandwidthSelectorCriterions() const; IndepVarsCriterionList indepVarSelectorCriterions() const; @@ -165,7 +165,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, rowvec distanceParam1(int i) { - return (mSpatialWeight.distance()->type() == GwmDistance::DMatDistance ? vec(1).fill(i) : mDataPoints.row(i)); + return (mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance ? vec(1).fill(i) : mDataPoints.row(i)); } protected: void OLS(); @@ -248,7 +248,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, vec mRegressionLayerY; mat mRegressionLayerX; - GwmBandwidthSizeSelector mBandwidthSizeSelector; + gwm::BandwidthSelector mBandwidthSizeSelector; bool mIsAutoselectBandwidth = false; BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::AIC; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial; @@ -380,7 +380,7 @@ inline void GwmBasicGWRAlgorithm::setGPUId(const int gpuId) mGpuId = gpuId; } -inline BandwidthCriterionList GwmBasicGWRAlgorithm::bandwidthSelectorCriterions() const +inline gwm::BandwidthCriterionList GwmBasicGWRAlgorithm::bandwidthSelectorCriterions() const { return mBandwidthSizeSelector.bandwidthCriterion(); } diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index b7da33d..43e1a63 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -26,7 +26,8 @@ QMap GwmGeneralizedGWRAlgorithm::TolUnitDict = { }; -GwmGeneralizedGWRAlgorithm::GwmGeneralizedGWRAlgorithm() : GwmGeographicalWeightedRegressionAlgorithm() +GwmGeneralizedGWRAlgorithm::GwmGeneralizedGWRAlgorithm() : GwmGeographicalWeightedRegressionAlgorithm(), + mGWRCore(std::make_unique()) { } @@ -34,8 +35,8 @@ GwmGeneralizedGWRAlgorithm::GwmGeneralizedGWRAlgorithm() : GwmGeographicalWeight void GwmGeneralizedGWRAlgorithm::setCanceled(bool canceled) { if (mGlm) mGlm->setCanceled(canceled); - mBandwidthSizeSelector.setCanceled(canceled); - mSpatialWeight.distance()->setCanceled(canceled); + // mBandwidthSizeSelector.setCanceled(canceled); + // mSpatialWeight.distance()->setCanceled(canceled); return GwmTaskThread::setCanceled(canceled); } @@ -58,19 +59,22 @@ void GwmGeneralizedGWRAlgorithm::run() { emit message(QString(tr("Automatically selecting bandwidth ..."))); //emit tick(0, 0); - if ((mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) && !checkCanceled()) + if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) { - GwmCRSDistance* d = static_cast(mSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mDataPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); } - GwmBandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); + gwm::BandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); mBandwidthSizeSelector.setBandwidth(bandwidthWeight0); double lower = bandwidthWeight0->adaptive() ? 20 : 0.0; double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : mSpatialWeight.distance()->maxDistance(); mBandwidthSizeSelector.setLower(lower); mBandwidthSizeSelector.setUpper(upper); - GwmBandwidthWeight* bandwidthWeight = !checkCanceled() ? mBandwidthSizeSelector.optimize(this) : nullptr; + mGWRCore->setCoords(mDataPoints); + mGWRCore->setDependentVariable(mY); + mGWRCore->setIndependentVariables(mX); + mGWRCore->setSpatialWeight(mSpatialWeight); + gwm::BandwidthWeight* bandwidthWeight = !checkCanceled() ? mBandwidthSizeSelector.optimize(mGWRCore.get()) : nullptr; if (bandwidthWeight && !checkCanceled()) { mSpatialWeight.setWeight(bandwidthWeight); @@ -78,11 +82,11 @@ void GwmGeneralizedGWRAlgorithm::run() QVariant data = QVariant::fromValue(mBandwidthSizeSelector.bandwidthCriterion()); emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); } - if ((mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) && !checkCanceled()) + if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) { - GwmCRSDistance* d = static_cast(mSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mRegressionPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); + } } @@ -106,11 +110,10 @@ void GwmGeneralizedGWRAlgorithm::run() mWtMat2.col(i) = weight; emit tick(i, nRp); } - if ((mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) && !checkCanceled()) + if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) { - GwmCRSDistance* d = static_cast(mSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mDataPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); } for(int i = 0; i < nDp && !checkCanceled(); i++){ vec weight = mSpatialWeight.weightVector(i); @@ -528,6 +531,7 @@ mat GwmGeneralizedGWRAlgorithm::regressionBinomialSerial(const mat &x, const vec double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial(GwmBandwidthWeight *bandwidthWeight) { + int mBandwidthCounter = 0; int n = mDataPoints.n_rows; vec cv = vec(n); mat wt = mat(n,n); @@ -537,8 +541,9 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial(GwmBandwid vec w = bandwidthWeight->weight(d); w.row(i) = 0; wt.col(i) = w; - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 5 / n, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); } if (!checkCanceled()) (this->*mCalWtFunction)(mX,mY,wt); for (int i = 0; i < n && !checkCanceled(); i++){ @@ -551,8 +556,9 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial(GwmBandwid else{ cv.row(i) = mY.row(i) - exp(yhatnoi)/(1+exp(yhatnoi)); } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 5 / n + 5, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); } vec cvsquare = trans(cv) * cv ; double res = sum(cvsquare); @@ -626,6 +632,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthW #endif double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial(GwmBandwidthWeight *bandwidthWeight) { + int mBandwidthCounter = 0; int n = mDataPoints.n_rows; vec cv = vec(n); mat S = mat(n,n); @@ -635,8 +642,9 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial(GwmBandwi vec d = mSpatialWeight.distance()->distance(i); vec w = bandwidthWeight->weight(d); wt.col(i) = w; - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 5 / n, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); } if(!checkCanceled()) (this->*mCalWtFunction)(mX,mY,wt); vec trS = vec(1,fill::zeros); @@ -645,8 +653,9 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial(GwmBandwi mat Ci = CiMat(mX,wi); S.row(i) = mX.row(i) * Ci; trS(0) += S(i,i); - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + i * 5 / n + 5, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); } double AICc; if(!checkCanceled()) @@ -955,12 +964,12 @@ void GwmGeneralizedGWRAlgorithm::setBandwidthSelectionCriterionType(const Bandwi QMap, BandwidthSelectCriterionFunction> mapper = { std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp), #endif std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial), std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp), + std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp), #endif std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial) }; @@ -1068,27 +1077,27 @@ bool GwmGeneralizedGWRAlgorithm::setFamily(Family family){ QMap, GGWRRegressionFunction> mapper = { std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionPoissonOmp), + std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionPoissonOmp), #endif -// std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), +// std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionPoissonSerial), std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionBinomialOmp), + std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::regressionBinomialOmp), #endif -// std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial) +// std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::regressionBinomialSerial) }; mGGWRRegressionFunction = mapper[qMakePair(family, mParallelType)]; QMap, CalWtFunction> mapper1 = { std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::PoissonWtOmp), + std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::PoissonWtOmp), #endif -// std::make_pair(qMakePair(Family::Poisson, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), +// std::make_pair(qMakePair(Family::Poisson, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::PoissonWtSerial), std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::SerialOnly), &GwmGeneralizedGWRAlgorithm::BinomialWtSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::BinomialWtOmp), + std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::OpenMP), &GwmGeneralizedGWRAlgorithm::BinomialWtOmp), #endif -// std::make_pair(qMakePair(Family::Binomial, IParallelalbe::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::BinomialWtSerial) +// std::make_pair(qMakePair(Family::Binomial, gwm::ParallelType::CUDA), &GwmGeneralizedGWRAlgorithm::BinomialWtSerial) }; mCalWtFunction = mapper1[qMakePair(family, mParallelType)]; return true; diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.h b/src/TaskThread/gwmgeneralizedgwralgorithm.h index a03e516..b7b5035 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.h +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.h @@ -152,6 +152,8 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor double bandwidthSizeGGWRCriterionCVSerial(GwmBandwidthWeight* bandwidthWeight); double bandwidthSizeGGWRCriterionAICSerial(GwmBandwidthWeight* bandwidthWeight); + std::unique_ptr mGWRCore; + #ifdef ENABLE_OpenMP double bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthWeight* bandwidthWeight); double bandwidthSizeGGWRCriterionAICOmp(GwmBandwidthWeight* bandwidthWeight); @@ -220,7 +222,7 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor bool mIsAutoselectBandwidth = false; BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::AIC; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial; - GwmGGWRBandwidthSizeSelector mBandwidthSizeSelector; + gwm::BandwidthSelector mBandwidthSizeSelector; gwm::ParallelType mParallelType = gwm::ParallelType::SerialOnly; int mOmpThreadNum = 8; @@ -317,9 +319,9 @@ inline int GwmGeneralizedGWRAlgorithm::parallelAbility() const { return gwm::SerialOnly #ifdef ENABLE_OpenMP - | IParallelalbe::OpenMP + | gwm::OpenMP #endif -// | IParallelalbe::CUDA +// | gwm::CUDA ; } diff --git a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp index 3539ccb..f8791e8 100644 --- a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp +++ b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmgeographicalweightedregressionalgorithm.h" +#include "gwmgeographicalweightedregressionalgorithm.h" #include #include using namespace arma; @@ -49,11 +49,10 @@ void GwmGeographicalWeightedRegressionAlgorithm::initPoints() } else mRegressionPoints = mDataPoints; // 设置空间距离中的数据指针 - if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { - GwmCRSDistance* d = static_cast(mSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mRegressionPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); } } diff --git a/src/TaskThread/gwmgtwralgorithm.cpp b/src/TaskThread/gwmgtwralgorithm.cpp index 3d5c57e..35654b7 100644 --- a/src/TaskThread/gwmgtwralgorithm.cpp +++ b/src/TaskThread/gwmgtwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmgtwralgorithm.h" +#include "gwmgtwralgorithm.h" #ifdef ENABLE_OpenMP #include #endif @@ -27,7 +27,7 @@ GwmGTWRAlgorithm::GwmGTWRAlgorithm() : GwmSpatialTemporalMonoscaleAlgorithm() void GwmGTWRAlgorithm::setCanceled(bool canceled) { - mBandwidthSizeSelector.setCanceled(canceled); + // mBandwidthSizeSelector.setCanceled(canceled); mSTWeight.distance()->setCanceled(canceled); return GwmTaskThread::setCanceled(canceled); } diff --git a/src/TaskThread/gwmgwaveragetaskthread.cpp b/src/TaskThread/gwmgwaveragetaskthread.cpp index bee53f2..4214972 100644 --- a/src/TaskThread/gwmgwaveragetaskthread.cpp +++ b/src/TaskThread/gwmgwaveragetaskthread.cpp @@ -1,4 +1,4 @@ -#include "gwmgwaveragetaskthread.h" +#include "gwmgwaveragetaskthread.h" #include "gwmgwaveragetaskthread.h" #include "SpatialWeight/gwmcrsdistance.h" #ifdef ENABLE_OpenMP @@ -31,7 +31,7 @@ bool GwmGWaverageTaskThread::isValid() if (mVariables.size() < 1) return false; - if (static_cast(mSpatialWeight.weight())->bandwidth() == 0) + if (static_cast(mSpatialWeight.weight())->bandwidth() == 0) return false; return true; @@ -214,11 +214,10 @@ void GwmGWaverageTaskThread::initPoints() mDataPoints(i, 1) = centroPoint.y(); } - if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { - GwmCRSDistance* d = static_cast(mSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mDataPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); } } diff --git a/src/TaskThread/gwmgwaveragetaskthread.h b/src/TaskThread/gwmgwaveragetaskthread.h index 9ca2f5e..4699385 100644 --- a/src/TaskThread/gwmgwaveragetaskthread.h +++ b/src/TaskThread/gwmgwaveragetaskthread.h @@ -1,4 +1,4 @@ - #ifndef GWMGWAVERAGETASKTHREAD_H + #ifndef GWMGWAVERAGETASKTHREAD_H #define GWMGWAVERAGETASKTHREAD_H #include @@ -93,8 +93,8 @@ class GwmGWaverageTaskThread :public GwmSpatialMonoscaleAlgorithm, public IMulti public: - GwmBandwidthWeight* bandwidth() const; - void setBandwidth(GwmBandwidthWeight* bandwidth); + gwm::BandwidthWeight* bandwidth() const; + void setBandwidth(gwm::BandwidthWeight* bandwidth); mat localmean() const{return mLocalMean;} @@ -189,12 +189,12 @@ inline void GwmGWaverageTaskThread::setVariables(const QList &&vari mVariables = variables; } -inline GwmBandwidthWeight *GwmGWaverageTaskThread::bandwidth() const +inline gwm::BandwidthWeight *GwmGWaverageTaskThread::bandwidth() const { - return static_cast(mSpatialWeight.weight()); + return static_cast(mSpatialWeight.weight()); } -inline void GwmGWaverageTaskThread::setBandwidth(GwmBandwidthWeight *bandwidth) +inline void GwmGWaverageTaskThread::setBandwidth(gwm::BandwidthWeight *bandwidth) { mSpatialWeight.setWeight(bandwidth); } diff --git a/src/TaskThread/gwmgwcorrelationtaskthread.cpp b/src/TaskThread/gwmgwcorrelationtaskthread.cpp index a6db1c6..7fde0a8 100644 --- a/src/TaskThread/gwmgwcorrelationtaskthread.cpp +++ b/src/TaskThread/gwmgwcorrelationtaskthread.cpp @@ -1,5 +1,4 @@ -#include "gwmgwcorrelationtaskthread.h" -#include "gwmgwcorrelationtaskthread.h" +#include "gwmgwcorrelationtaskthread.h" #include "SpatialWeight/gwmcrsdistance.h" #ifdef ENABLE_OpenMP #include diff --git a/src/TaskThread/gwmgwpcataskthread.cpp b/src/TaskThread/gwmgwpcataskthread.cpp index e0bcccf..21ee1d2 100644 --- a/src/TaskThread/gwmgwpcataskthread.cpp +++ b/src/TaskThread/gwmgwpcataskthread.cpp @@ -1,4 +1,4 @@ -#include "gwmgwpcataskthread.h" +#include "gwmgwpcataskthread.h" #include #include "TaskThread/gwmgeographicalweightedregressionalgorithm.h" #include "gwmtaskthread.h" @@ -12,15 +12,16 @@ int GwmGWPCATaskThread::treeChildCount = 0; -GwmGWPCATaskThread::GwmGWPCATaskThread() : GwmSpatialMonoscaleAlgorithm() +GwmGWPCATaskThread::GwmGWPCATaskThread() : GwmSpatialMonoscaleAlgorithm(), + mGWRCore(std::make_unique()) { } void GwmGWPCATaskThread::setCanceled(bool canceled) { - mSelector.setCanceled(canceled); - mSpatialWeight.distance()->setCanceled(canceled); + // mSelector.setCanceled(canceled); + // mSpatialWeight.distance()->setCanceled(canceled); return GwmTaskThread::setCanceled(canceled); } @@ -46,14 +47,18 @@ void GwmGWPCATaskThread::run() { emit message(QString(tr("Automatically selecting bandwidth ..."))); emit tick(0, 0); - GwmBandwidthWeight* bandwidthWeight0 = static_cast(mSpatialWeight.weight()); + gwm::BandwidthWeight* bandwidthWeight0 = static_cast(mSpatialWeight.weight()); mSelector.setBandwidth(bandwidthWeight0); double tmpMaxD = mSpatialWeight.distance()->maxDistance(); double lower = bandwidthWeight0->adaptive() ? 2 : tmpMaxD / 5000; double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : tmpMaxD; mSelector.setLower(lower); mSelector.setUpper(upper); - GwmBandwidthWeight* bandwidthWeight = mSelector.optimize(this); + mGWRCore->setCoords(mDataPoints); + // mGWRCore->setDependentVariable(mY); + mGWRCore->setIndependentVariables(mX); + mGWRCore->setSpatialWeight(mSpatialWeight); + gwm::BandwidthWeight* bandwidthWeight = mSelector.optimize(mGWRCore.get()); if(bandwidthWeight && !checkCanceled()) { mSpatialWeight.setWeight(bandwidthWeight); @@ -131,7 +136,7 @@ void GwmGWPCATaskThread::run() bool GwmGWPCATaskThread::isValid() { - GwmBandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); + gwm::BandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); if(bandwidth){ if(!mIsAutoselectBandwidth) { @@ -165,7 +170,7 @@ void GwmGWPCATaskThread::initPoints() mDataPoints(i, 0) = centroPoint.x(); mDataPoints(i, 1) = centroPoint.y(); } - if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { GwmCRSDistance* d = mSpatialWeight.distance(); d->setDataPoints(&mDataPoints); @@ -473,6 +478,7 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QList @@ -108,6 +108,7 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt void rwpca(const mat &x, const vec &wt, mat &coeff, vec &latent, double nu, double nv); void createResultLayer(CreateResultLayerData data,QList winvar); void createPlotLayer(CreatePlotLayerData data, QList varpc); + std::unique_ptr mGWRCore; mat pca(const mat& x, cube& loadings, mat& sdev, cube& scores) { @@ -147,7 +148,7 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt mat mX; vec mLatestWt; - GwmBandwidthSizeSelector mSelector; + gwm::BandwidthSelector mSelector; BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::CV; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmGWPCATaskThread::bandwidthSizeCriterionCVSerial; bool mIsAutoselectBandwidth = false; diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index bce4899..da9a6a5 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmlocalcollinearitygwralgorithm.h" +#include "gwmlocalcollinearitygwralgorithm.h" #include @@ -10,7 +10,8 @@ int GwmLocalCollinearityGWRAlgorithm::treeChildCount = 0; using namespace arma; -GwmLocalCollinearityGWRAlgorithm::GwmLocalCollinearityGWRAlgorithm():GwmGeographicalWeightedRegressionAlgorithm() +GwmLocalCollinearityGWRAlgorithm::GwmLocalCollinearityGWRAlgorithm():GwmGeographicalWeightedRegressionAlgorithm(), + mGWRCore(std::make_unique()) { } @@ -37,8 +38,8 @@ double GwmLocalCollinearityGWRAlgorithm::cnThresh() const void GwmLocalCollinearityGWRAlgorithm::setCanceled(bool canceled) { - selector.setCanceled(canceled); - mSpatialWeight.distance()->setCanceled(canceled); + // selector.setCanceled(canceled); + // mSpatialWeight.distance()->setCanceled(canceled); return GwmTaskThread::setCanceled(canceled); } @@ -58,13 +59,17 @@ void GwmLocalCollinearityGWRAlgorithm::run() if(mIsAutoselectBandwidth && !checkCanceled()) { emit message(QString(tr("Automatically selecting bandwidth ..."))); - GwmBandwidthWeight* bandwidthWeight0 = static_cast(mSpatialWeight.weight()); + gwm::BandwidthWeight* bandwidthWeight0 = static_cast(mSpatialWeight.weight()); selector.setBandwidth(bandwidthWeight0); double lower = bandwidthWeight0->adaptive() ? 20 : 0.0; double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : mSpatialWeight.distance()->maxDistance(); selector.setLower(lower); selector.setUpper(upper); - GwmBandwidthWeight* bandwidthWeight = selector.optimize(this); + mGWRCore->setCoords(mDataPoints); + mGWRCore->setDependentVariable(mY); + mGWRCore->setIndependentVariables(mX); + mGWRCore->setSpatialWeight(mSpatialWeight); + gwm::BandwidthWeight* bandwidthWeight = selector.optimize(mGWRCore.get()); if(bandwidthWeight) { mSpatialWeight.setWeight(bandwidthWeight); @@ -234,6 +239,7 @@ void GwmLocalCollinearityGWRAlgorithm::createResultLayer(CreateResultLayerData d double GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVSerial(GwmBandwidthWeight *weight) { + int mBandwidthCounter = 0; //行数 double n = mX.n_rows; //列数 @@ -278,8 +284,9 @@ double GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVSerial(GwmBandw } } betas.row(i) = trans( ridgelm(wgt,locallambda(i)) ); - if(selector.counter<10) - emit tick(selector.counter*10 + i * 10 / n, 100); + mBandwidthCounter++; + if (mBandwidthCounter < 10) + emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); } //yhat赋值 //vec mYHat = fitted(mX,betas); @@ -546,7 +553,7 @@ bool GwmLocalCollinearityGWRAlgorithm::isValid() { if (GwmGeographicalWeightedRegressionAlgorithm::isValid()) { - GwmBandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); + gwm::BandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); if(!mIsAutoselectBandwidth) { diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h index e19c39a..2a2c35b 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMLCRGWRTASKTHREAD_H +#ifndef GWMLCRGWRTASKTHREAD_H #define GWMLCRGWRTASKTHREAD_H #include @@ -101,7 +101,7 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA double mCnThresh; - GwmBandwidthSizeSelector selector; + gwm::BandwidthSelector selector; bool mHasHatmatix = false; @@ -113,6 +113,8 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA double bandwidthSizeCriterionCVSerial(GwmBandwidthWeight* weight); + std::unique_ptr mGWRCore; + public: static int treeChildCount; #ifdef ENABLE_OpenMP diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index a799c00..16fcef2 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.cpp +++ b/src/TaskThread/gwmrobustgwralgorithm.cpp @@ -8,7 +8,8 @@ int GwmRobustGWRAlgorithm::treeChildCount = 0; -GwmRobustGWRAlgorithm::GwmRobustGWRAlgorithm(): GwmBasicGWRAlgorithm() +GwmRobustGWRAlgorithm::GwmRobustGWRAlgorithm(): GwmBasicGWRAlgorithm(), + mGWRCore(std::make_unique()) { } @@ -244,12 +245,12 @@ void GwmRobustGWRAlgorithm::setParallelType(const gwm::ParallelType &type) mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixSerial; break; #ifdef ENABLE_OpenMP - case IParallelalbe::ParallelType::OpenMP: + case gwm::ParallelType::OpenMP: mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixOmp; break; #endif #ifdef ENABLE_CUDA - case IParallelalbe::ParallelType::CUDA: + case gwm::ParallelType::CUDA: mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixCuda; break; #endif diff --git a/src/TaskThread/gwmrobustgwralgorithm.h b/src/TaskThread/gwmrobustgwralgorithm.h index 1c7b31b..c4607f1 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.h +++ b/src/TaskThread/gwmrobustgwralgorithm.h @@ -66,6 +66,8 @@ class GwmRobustGWRAlgorithm: public GwmBasicGWRAlgorithm RegressionHatmatrix mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixSerial; + std::unique_ptr mGWRCore; + public: static int treeChildCount; }; @@ -90,10 +92,10 @@ inline int GwmRobustGWRAlgorithm::parallelAbility() const { return gwm::SerialOnly #ifdef ENABLE_OpenMP - | IParallelalbe::OpenMP + | gwm::OpenMP #endif #ifdef ENABLE_CUDA - | IParallelalbe::CUDA + | gwm::CUDA #endif ; } diff --git a/src/TaskThread/gwmscalablegwralgorithm.cpp b/src/TaskThread/gwmscalablegwralgorithm.cpp index f2cd479..ab7ac81 100644 --- a/src/TaskThread/gwmscalablegwralgorithm.cpp +++ b/src/TaskThread/gwmscalablegwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmscalablegwralgorithm.h" +#include "gwmscalablegwralgorithm.h" #include #include "gsl/gsl_multimin.h" @@ -283,11 +283,11 @@ void GwmScalableGWRAlgorithm::findDataPointNeighbours() mDpNNDists.submat(0, 0, 2, 2).print(std::cout, "nn"); } -mat GwmScalableGWRAlgorithm::findNeighbours(const GwmSpatialWeight &spatialWeight, umat &nnIndex) +mat GwmScalableGWRAlgorithm::findNeighbours(const gwm::SpatialWeight &spatialWeight, umat &nnIndex) { - GwmBandwidthWeight* bandwidth = spatialWeight.weight(); - uword nDp = mDpSpatialWeight.distance()->total(); - uword nRp = spatialWeight.distance()->total(); + gwm::BandwidthWeight* bandwidth = spatialWeight.weight(); + uword nRp = spatialWeight.distance()->distance(0).n_elem; + uword nDp = mDpSpatialWeight.distance()->distance(0).n_elem; uword nBw = bandwidth->bandwidth() < nDp ? bandwidth->bandwidth() : nDp; umat index(nBw, nRp, fill::zeros); mat dists(nBw, nRp, fill::zeros); @@ -412,7 +412,7 @@ void GwmScalableGWRAlgorithm::prepare() mat GwmScalableGWRAlgorithm::regressionSerial(const arma::mat &x, const arma::vec &y) { - GwmBandwidthWeight* bandwidth = mSpatialWeight.weight(); + gwm::BandwidthWeight* bandwidth = mSpatialWeight.weight(); arma::uword nDp = mDataPoints.n_rows, nRp = mRegressionPoints.n_rows, nVar = mX.n_cols, nBw = bandwidth->bandwidth(); double band0 = 0.0; mat G0; @@ -420,11 +420,11 @@ mat GwmScalableGWRAlgorithm::regressionSerial(const arma::mat &x, const arma::ve mat rpNNDists = findNeighbours(mSpatialWeight, rpNNIndex); switch (bandwidth->kernel()) { - case GwmBandwidthWeight::KernelFunctionType::Gaussian: + case gwm::BandwidthWeight::KernelFunctionType::Gaussian: band0 = median(rpNNDists.col(qMin(50, nBw) - 1)) / sqrt(3); G0 = exp(-pow(rpNNDists / band0, 2)); break; - case GwmBandwidthWeight::KernelFunctionType::Exponential: + case gwm::BandwidthWeight::KernelFunctionType::Exponential: band0 = median(rpNNDists.col(qMin(50, nBw) - 1)) / 3; G0 = exp(-pow(rpNNDists / band0, 2)); break; @@ -635,11 +635,10 @@ arma::mat GwmScalableGWRAlgorithm::regressionHatmatrixSerial(const arma::mat &x, void GwmScalableGWRAlgorithm::initPoints() { GwmGeographicalWeightedRegressionAlgorithm::initPoints(); - if (mDpSpatialWeight.distance()->type() == GwmDistance::CRSDistance || mDpSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) + if (mDpSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mDpSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { - GwmCRSDistance* d = static_cast(mDpSpatialWeight.distance()); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mDataPoints); + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + d->makeParameter({ mDataPoints, mDataPoints }); } } diff --git a/src/TaskThread/gwmscalablegwralgorithm.h b/src/TaskThread/gwmscalablegwralgorithm.h index b37208c..08aa040 100644 --- a/src/TaskThread/gwmscalablegwralgorithm.h +++ b/src/TaskThread/gwmscalablegwralgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMSCALABLEGWRTASKTHREAD_H +#ifndef GWMSCALABLEGWRTASKTHREAD_H #define GWMSCALABLEGWRTASKTHREAD_H #include "TaskThread/gwmgeographicalweightedregressionalgorithm.h" @@ -71,7 +71,7 @@ class GwmScalableGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorith private: void findDataPointNeighbours(); - mat findNeighbours(const GwmSpatialWeight& spatialWeight, umat &nnIndex); + mat findNeighbours(const gwm::SpatialWeight& spatialWeight, umat &nnIndex); double optimize(const mat& Mx0, const mat& My0, double& b_tilde, double& alpha); void prepare(); @@ -95,7 +95,7 @@ class GwmScalableGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorith bool mHasHatMatrix = true; - GwmSpatialWeight mDpSpatialWeight; + gwm::SpatialWeight mDpSpatialWeight; ParameterOptimizeCriterionType mParameterOptimizeCriterion = ParameterOptimizeCriterionType::CV; diff --git a/src/TaskThread/gwmspatialmonoscalealgorithm.h b/src/TaskThread/gwmspatialmonoscalealgorithm.h index f6351ba..5f09d05 100644 --- a/src/TaskThread/gwmspatialmonoscalealgorithm.h +++ b/src/TaskThread/gwmspatialmonoscalealgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMSPATIALMONOSCALEALGORITHM_H +#ifndef GWMSPATIALMONOSCALEALGORITHM_H #define GWMSPATIALMONOSCALEALGORITHM_H #include @@ -12,20 +12,20 @@ class GwmSpatialMonoscaleAlgorithm : public GwmSpatialAlgorithm public: GwmSpatialMonoscaleAlgorithm(); - GwmSpatialWeight spatialWeight() const; - void setSpatialWeight(const GwmSpatialWeight &spatialWeight); + gwm::SpatialWeight spatialWeight() const; + void setSpatialWeight(const gwm::SpatialWeight &spatialWeight); protected: - GwmSpatialWeight mSpatialWeight; + gwm::SpatialWeight mSpatialWeight; }; -inline GwmSpatialWeight GwmSpatialMonoscaleAlgorithm::spatialWeight() const +inline gwm::SpatialWeight GwmSpatialMonoscaleAlgorithm::spatialWeight() const { return mSpatialWeight; } -inline void GwmSpatialMonoscaleAlgorithm::setSpatialWeight(const GwmSpatialWeight &spatialWeight) +inline void GwmSpatialMonoscaleAlgorithm::setSpatialWeight(const gwm::SpatialWeight &spatialWeight) { mSpatialWeight = spatialWeight; } diff --git a/src/gwmapp.cpp b/src/gwmapp.cpp index 5e84073..77eaafb 100644 --- a/src/gwmapp.cpp +++ b/src/gwmapp.cpp @@ -1,4 +1,4 @@ -#include "gwmapp.h" +#include "gwmapp.h" #include "ui_gwmapp.h" #include @@ -1316,9 +1316,9 @@ void GwmApp::onGWRNewBtnClicked() algorithm->setIndependentVariables(indepVars); algorithm->setIsAutoselectIndepVars(true); algorithm->setIndepVarSelectionThreshold(150.0); - GwmSpatialWeight spatialWeight; - spatialWeight.setDistance(GwmCRSDistance(dataLayer->featureCount(), false)); - spatialWeight.setWeight(GwmBandwidthWeight(36, true, GwmBandwidthWeight::Gaussian)); + gwm::SpatialWeight spatialWeight; + spatialWeight.setDistance(gwm::CRSDistance()); + spatialWeight.setWeight(gwm::BandwidthWeight(36, true, gwm::BandwidthWeight::Gaussian)); algorithm->setSpatialWeight(spatialWeight); algorithm->setIsAutoselectBandwidth(true); algorithm->setBandwidthSelectionCriterionType(GwmBasicGWRAlgorithm::CV); diff --git a/src/gwmggwroptionsdialog.cpp b/src/gwmggwroptionsdialog.cpp index d37efa6..0b7f6e8 100644 --- a/src/gwmggwroptionsdialog.cpp +++ b/src/gwmggwroptionsdialog.cpp @@ -325,10 +325,10 @@ QString GwmGGWROptionsDialog::bandWidthUnit(){ } } -GwmBandwidthWeight::KernelFunctionType GwmGGWROptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmGGWROptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmGGWROptionsDialog::distanceSourceParameters() @@ -460,27 +460,27 @@ void GwmGGWROptionsDialog::updateFields() { mTaskThread->setIsAutoselectBandwidth(false); } - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmggwroptionsdialog.h b/src/gwmggwroptionsdialog.h index 609662d..9a72c2b 100644 --- a/src/gwmggwroptionsdialog.h +++ b/src/gwmggwroptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMGGWROPTIONSDIALOG_H +#ifndef GWMGGWROPTIONSDIALOG_H #define GWMGGWROPTIONSDIALOG_H #include @@ -52,7 +52,7 @@ public slots: double bandwidthSize(); GwmGeneralizedGWRAlgorithm::BandwidthSelectionCriterionType bandwidthSelectionApproach(); QString bandWidthUnit(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); QVariant distanceSourceParameters(); QVariant parallelParameters(); double epsilonSize(); diff --git a/src/gwmgwaverageoptionsdialog.cpp b/src/gwmgwaverageoptionsdialog.cpp index d0c63d6..da459b3 100644 --- a/src/gwmgwaverageoptionsdialog.cpp +++ b/src/gwmgwaverageoptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmgwaverageoptionsdialog.h" +#include "gwmgwaverageoptionsdialog.h" #include "ui_gwmgwaverageoptionsdialog.h" #ifdef ENABLE_OpenMP #include @@ -272,10 +272,10 @@ double GwmGWaverageOptionsDialog::bandwidthSize(){ } -GwmBandwidthWeight::KernelFunctionType GwmGWaverageOptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmGWaverageOptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmGWaverageOptionsDialog::parallelParameters() @@ -336,28 +336,28 @@ void GwmGWaverageOptionsDialog::updateFields() } } - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); - mTaskThread->setBandwidth(new GwmBandwidthWeight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction())); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + mTaskThread->setBandwidth(new gwm::BandwidthWeight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction())); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmgwaverageoptionsdialog.h b/src/gwmgwaverageoptionsdialog.h index 7d40e76..7432702 100644 --- a/src/gwmgwaverageoptionsdialog.h +++ b/src/gwmgwaverageoptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMGWAVERAGEOPTIONSDIALOG_H +#ifndef GWMGWAVERAGEOPTIONSDIALOG_H #define GWMGWAVERAGEOPTIONSDIALOG_H #include @@ -53,7 +53,7 @@ public slots: double bandwidthSize(); // GwmGWRTaskThread::BandwidthSelectionApproach bandwidthSelectionApproach(); // QString bandWidthUnit(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); GwmDistance::DistanceType distanceSourceType(); QVariant distanceSourceParameters(); QVariant parallelParameters(); diff --git a/src/gwmgwpcaoptionsdialog.cpp b/src/gwmgwpcaoptionsdialog.cpp index f539300..911cf6e 100644 --- a/src/gwmgwpcaoptionsdialog.cpp +++ b/src/gwmgwpcaoptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmgwpcaoptionsdialog.h" +#include "gwmgwpcaoptionsdialog.h" #include "ui_gwmgwpcaoptionsdialog.h" #ifdef ENABLE_OpenMP #include @@ -340,10 +340,10 @@ QString GwmGWPCAOptionsDialog::bandWidthUnit(){ } } -GwmBandwidthWeight::KernelFunctionType GwmGWPCAOptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmGWPCAOptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmGWPCAOptionsDialog::distanceSourceParameters() @@ -459,27 +459,27 @@ void GwmGWPCAOptionsDialog::updateFields() { mTaskThread->setIsAutoselectBandwidth(false); } - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmgwpcaoptionsdialog.h b/src/gwmgwpcaoptionsdialog.h index ad18984..0079d35 100644 --- a/src/gwmgwpcaoptionsdialog.h +++ b/src/gwmgwpcaoptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMGWPCAOPTIONSDIALOG_H +#ifndef GWMGWPCAOPTIONSDIALOG_H #define GWMGWPCAOPTIONSDIALOG_H #include @@ -56,7 +56,7 @@ public slots: double bandwidthSize(); //GwmGWPCATaskThread::BandwidthSelectionCriterionType bandwidthSelectionApproach(); QString bandWidthUnit(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); //GwmGWRTaskThread::DistanceSourceType distanceSourceType(); QVariant distanceSourceParameters(); //GwmGWRTaskThread::ParallelMethod parallelMethod(); diff --git a/src/gwmgwroptionsdialog.cpp b/src/gwmgwroptionsdialog.cpp index 83c11b4..6873ed7 100644 --- a/src/gwmgwroptionsdialog.cpp +++ b/src/gwmgwroptionsdialog.cpp @@ -408,10 +408,10 @@ QString GwmGWROptionsDialog::bandWidthUnit(){ } } -GwmBandwidthWeight::KernelFunctionType GwmGWROptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmGWROptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmGWROptionsDialog::distanceSourceParameters() @@ -533,27 +533,27 @@ void GwmGWROptionsDialog::updateFields() { mTaskThread->setIsAutoselectBandwidth(false); } - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmgwroptionsdialog.h b/src/gwmgwroptionsdialog.h index 7ebe785..2c02909 100644 --- a/src/gwmgwroptionsdialog.h +++ b/src/gwmgwroptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMGWROPTIONSDIALOG_H +#ifndef GWMGWROPTIONSDIALOG_H #define GWMGWROPTIONSDIALOG_H #include @@ -53,7 +53,7 @@ public slots: double bandwidthSize(); GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType bandwidthSelectionApproach(); QString bandWidthUnit(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); QVariant distanceSourceParameters(); QVariant parallelParameters(); diff --git a/src/gwmlcrgwroptionsdialog.cpp b/src/gwmlcrgwroptionsdialog.cpp index 56ed6d0..e4e91b1 100644 --- a/src/gwmlcrgwroptionsdialog.cpp +++ b/src/gwmlcrgwroptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmlcrgwroptionsdialog.h" +#include "gwmlcrgwroptionsdialog.h" #include "ui_gwmlcrgwroptionsdialog.h" #include #include @@ -340,10 +340,10 @@ QString GwmLcrGWROptionsDialog::bandWidthUnit(){ return ui->mBwSizeFixedUnit->currentText(); } } -GwmBandwidthWeight::KernelFunctionType GwmLcrGWROptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmLcrGWROptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmLcrGWROptionsDialog::distanceSourceParameters() @@ -471,27 +471,27 @@ void GwmLcrGWROptionsDialog::updateFields() { mTaskThread->setIsAutoselectBandwidth(false); } - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmlcrgwroptionsdialog.h b/src/gwmlcrgwroptionsdialog.h index 7b3c683..0f93618 100644 --- a/src/gwmlcrgwroptionsdialog.h +++ b/src/gwmlcrgwroptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GwmLcrGWROptionsDialog_H +#ifndef GwmLcrGWROptionsDialog_H #define GwmLcrGWROptionsDialog_H #include @@ -61,7 +61,7 @@ public slots: QVariant distanceSourceParameters(); //GwmLcrGWRTaskThread::ParallelMethod parallelMethod(); QVariant parallelParameters(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); void setTaskThread(GwmLocalCollinearityGWRAlgorithm* taskThread); void updateFieldsAndEnable(); diff --git a/src/gwmrobustgwroptionsdialog.cpp b/src/gwmrobustgwroptionsdialog.cpp index ecfa65c..a670293 100644 --- a/src/gwmrobustgwroptionsdialog.cpp +++ b/src/gwmrobustgwroptionsdialog.cpp @@ -345,10 +345,10 @@ QString GwmRobustGWROptionsDialog::bandWidthUnit(){ } } -GwmBandwidthWeight::KernelFunctionType GwmRobustGWROptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmRobustGWROptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmRobustGWROptionsDialog::distanceSourceParameters() @@ -453,27 +453,27 @@ void GwmRobustGWROptionsDialog::updateFields() // } } // 带宽设置 - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); if (ui->mDistTypeDmatRadio->isChecked()) { QString filename = ui->mDistMatrixFileNameEdit->text(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmrobustgwroptionsdialog.h b/src/gwmrobustgwroptionsdialog.h index 8eaf352..fc3b192 100644 --- a/src/gwmrobustgwroptionsdialog.h +++ b/src/gwmrobustgwroptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMROBUSTGWROPTIONSDIALOG_H +#ifndef GWMROBUSTGWROPTIONSDIALOG_H #define GWMROBUSTGWROPTIONSDIALOG_H #include @@ -70,7 +70,7 @@ public slots: void setSelectedLayer(GwmLayerGroupItem *selectedLayer); bool bandwidthType(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); private slots: void on_cbxHatmatrix_toggled(bool checked); void on_cbkRegressionPoints_toggled(bool checked); diff --git a/src/gwmscalablegwroptionsdialog.cpp b/src/gwmscalablegwroptionsdialog.cpp index 38165b8..55d0c02 100644 --- a/src/gwmscalablegwroptionsdialog.cpp +++ b/src/gwmscalablegwroptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmscalablegwroptionsdialog.h" +#include "gwmscalablegwroptionsdialog.h" #include "ui_gwmscalablegwroptionsdialog.h" #include #include @@ -252,10 +252,10 @@ QString GwmScalableGWROptionsDialog::bandWidthUnit(){ } } -GwmBandwidthWeight::KernelFunctionType GwmScalableGWROptionsDialog::bandwidthKernelFunction() +gwm::BandwidthWeight::KernelFunctionType GwmScalableGWROptionsDialog::bandwidthKernelFunction() { int kernelSelected = ui->mBwKernelFunctionCombo->currentIndex(); - return GwmBandwidthWeight::KernelFunctionType(kernelSelected); + return gwm::BandwidthWeight::KernelFunctionType(kernelSelected); } QVariant GwmScalableGWROptionsDialog::distanceSourceParameters() @@ -336,8 +336,8 @@ void GwmScalableGWROptionsDialog::updateFields() } } // 带宽设置 - GwmSpatialWeight spatialWeight; - GwmBandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); + gwm::SpatialWeight spatialWeight; + gwm::BandwidthWeight weight(bandwidthSize(), bandwidthType(), bandwidthKernelFunction()); spatialWeight.setWeight(weight); // 距离设置 int featureCount = dataLayer->featureCount(); @@ -345,19 +345,19 @@ void GwmScalableGWROptionsDialog::updateFields() { QString filename = ui->mDistMatrixFileNameEdit->text(); int featureCount = dataLayer->featureCount(); - GwmDMatDistance distance(featureCount, filename); + gwm::DMatDistance distance(filename.toStdString()); spatialWeight.setDistance(distance); } else if (ui->mDistTypeMinkowskiRadio->isChecked()) { double theta = ui->mThetaValue->value(); double p = ui->mPValue->value(); - GwmMinkwoskiDistance distance(featureCount, p, theta); + gwm::MinkwoskiDistance distance(p, theta); spatialWeight.setDistance(distance); } else { - GwmCRSDistance distance(featureCount, dataLayer->crs().isGeographic()); + gwm::CRSDistance distance; spatialWeight.setDistance(distance); } mTaskThread->setSpatialWeight(spatialWeight); diff --git a/src/gwmscalablegwroptionsdialog.h b/src/gwmscalablegwroptionsdialog.h index 1e8583a..0598fa3 100644 --- a/src/gwmscalablegwroptionsdialog.h +++ b/src/gwmscalablegwroptionsdialog.h @@ -1,4 +1,4 @@ -#ifndef GWMSCALABLEGWROPTIONSDIALOG_H +#ifndef GWMSCALABLEGWROPTIONSDIALOG_H #define GWMSCALABLEGWROPTIONSDIALOG_H #include @@ -50,7 +50,7 @@ public slots: bool bandwidthType(); double bandwidthSize(); QString bandWidthUnit(); - GwmBandwidthWeight::KernelFunctionType bandwidthKernelFunction(); + gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); QVariant distanceSourceParameters(); void setTaskThread(GwmScalableGWRAlgorithm* taskThread); From 759ea0c5524765ebe5ffecd656405edab1021918 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Mon, 24 Nov 2025 15:25:40 +0800 Subject: [PATCH 3/6] =?UTF-8?q?Update:=20=E4=BF=AE=E6=94=B9=20basicgwr=20?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/gwmlayerbasicgwritem.cpp | 8 +- src/Model/gwmlayerbasicgwritem.h | 5 +- src/PropertyPanelTabs/gwmpropertygwrtab.cpp | 12 +- src/TaskThread/gwmbandwidthsizeselector.cpp | 73 +++++---- src/TaskThread/gwmbasicgwralgorithm.cpp | 138 +++++++++++------- src/TaskThread/gwmbasicgwralgorithm.h | 11 +- ...eographicalweightedregressionalgorithm.cpp | 18 ++- ...mgeographicalweightedregressionalgorithm.h | 7 +- src/gwmapp.cpp | 2 +- src/gwmgwroptionsdialog.cpp | 6 +- src/gwmgwroptionsdialog.h | 2 +- 11 files changed, 183 insertions(+), 99 deletions(-) diff --git a/src/Model/gwmlayerbasicgwritem.cpp b/src/Model/gwmlayerbasicgwritem.cpp index 8cc96e7..50900af 100644 --- a/src/Model/gwmlayerbasicgwritem.cpp +++ b/src/Model/gwmlayerbasicgwritem.cpp @@ -12,6 +12,7 @@ GwmLayerBasicGWRItem::GwmLayerBasicGWRItem(GwmLayerItem* parent, QgsVectorLayer* mIndepVars = taskThread->independentVariables(); mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); mDiagnostic = taskThread->diagnostic(); + mDiagnostic0 = taskThread->diagnostic0(); mBetas = mat(taskThread->betas()); mModelSelModels = taskThread->indepVarSelectorCriterions(); isBandwidthOptimized = taskThread->autoselectBandwidth(); @@ -473,6 +474,11 @@ GwmDiagnostic GwmLayerBasicGWRItem::diagnostic() const return mDiagnostic; } +gwm::RegressionDiagnostic GwmLayerBasicGWRItem::diagnostic0() const +{ + return mDiagnostic0; +} + arma::mat GwmLayerBasicGWRItem::betas() const { return mBetas; @@ -533,7 +539,7 @@ QList, double> > GwmLayerBasicGWRItem::modelSelModels() return mModelSelModels; } -BandwidthCriterionList GwmLayerBasicGWRItem::bandwidthSelScores() const +gwm::BandwidthCriterionList GwmLayerBasicGWRItem::bandwidthSelScores() const { return mBandwidthSelScores; } diff --git a/src/Model/gwmlayerbasicgwritem.h b/src/Model/gwmlayerbasicgwritem.h index 09a4dbb..d17a733 100644 --- a/src/Model/gwmlayerbasicgwritem.h +++ b/src/Model/gwmlayerbasicgwritem.h @@ -27,6 +27,8 @@ class GwmLayerBasicGWRItem : public GwmLayerVectorItem GwmDiagnostic diagnostic() const; + gwm::RegressionDiagnostic diagnostic0() const; + arma::mat betas() const; bool modelOptimized() const; @@ -49,7 +51,7 @@ class GwmLayerBasicGWRItem : public GwmLayerVectorItem QList, double> > modelSelModels() const; - BandwidthCriterionList bandwidthSelScores() const; + gwm::BandwidthCriterionList bandwidthSelScores() const; gwm::BandwidthWeight weight() const; @@ -61,6 +63,7 @@ class GwmLayerBasicGWRItem : public GwmLayerVectorItem QList mIndepVars; gwm::BandwidthWeight mWeight; GwmDiagnostic mDiagnostic; + gwm::RegressionDiagnostic mDiagnostic0; arma::mat mBetas; QList, double> > mModelSelModels; BandwidthCriterionList mBandwidthSelScores; diff --git a/src/PropertyPanelTabs/gwmpropertygwrtab.cpp b/src/PropertyPanelTabs/gwmpropertygwrtab.cpp index 3e92baa..09a9cb1 100644 --- a/src/PropertyPanelTabs/gwmpropertygwrtab.cpp +++ b/src/PropertyPanelTabs/gwmpropertygwrtab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertygwrtab.h" +#include "gwmpropertygwrtab.h" #include "ui_gwmpropertygwrtab.h" #include @@ -113,7 +113,7 @@ void GwmPropertyGWRTab::updateUI() if (mLayerItem->hatmatrix()) { - GwmDiagnostic diagnostic = mLayerItem->diagnostic(); + gwm::RegressionDiagnostic diagnostic = mLayerItem->diagnostic0(); ui->lblENP->setText(QString("%1").arg(diagnostic.ENP, 0, 'f', 6)); ui->lblEDF->setText(QString("%1").arg(diagnostic.EDF, 0, 'f', 6)); ui->lblAIC->setText(QString("%1").arg(diagnostic.AIC, 0, 'f', 6)); @@ -191,8 +191,12 @@ void GwmPropertyGWRTab::updateUI() if(mLayerItem->bandwidthOptimized()) { - BandwidthCriterionList bwScores = mLayerItem->bandwidthSelScores(); - QVariant data = QVariant::fromValue(bwScores); + gwm::BandwidthCriterionList bwScores = mLayerItem->bandwidthSelScores(); + qDebug() << "bwScores size:" << bwScores.size(); + QVector> qlist; + for (const auto &item : bwScores) + qlist.append(qMakePair(item.first, item.second)); + QVariant data = QVariant::fromValue(qlist); GwmBandwidthSizeSelector::PlotBandwidthResult(data, mBandwidthSelPlot); } diff --git a/src/TaskThread/gwmbandwidthsizeselector.cpp b/src/TaskThread/gwmbandwidthsizeselector.cpp index 9f51944..b02c66a 100644 --- a/src/TaskThread/gwmbandwidthsizeselector.cpp +++ b/src/TaskThread/gwmbandwidthsizeselector.cpp @@ -12,47 +12,58 @@ #include #include #include +#include void GwmBandwidthSizeSelector::PlotBandwidthResult(QVariant data, QwtPlot *plot) { - BandwidthCriterionList result = data.value(); - //设置窗口属性 + if (!data.canConvert>>()) { + qDebug() << "Data cannot convert to QVector>!"; + return; + } + + QVector> result = data.value>>(); + qDebug() << "PlotBandwidthResult received size:" << result.size(); + + QVector xData, yData; + for (int i = 0; i < result.size(); ++i) { + qDebug() << "Bandwidth:" << result[i].first << ", Criterion:" << result[i].second; + xData.push_back(result[i].first); + yData.push_back(result[i].second); + } + + if (xData.isEmpty() || yData.isEmpty()) { + qDebug() << "xData or yData is empty!"; + return; + } + plot->plotLayout()->setAlignCanvasToScales(true); - //新建一个曲线对象 + QwtPlotCurve *curve = new QwtPlotCurve("curve"); - //设置曲线颜色 粗细 - curve->setPen(Qt::blue,1.0,Qt::DashLine); - //线条光滑化 - curve->setRenderHint(QwtPlotItem::RenderAntialiased,true); - //设置样本点的颜色、大小 - QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse, QBrush( Qt::yellow ), QPen( Qt::red, 0.5 ), QSize( 5, 5) ); - //添加样本点形状 - curve->setSymbol( symbol ); - //输入数据 - QVector xData; - QVector yData; - for (const auto& p : result) { - xData.push_back(p.first); - yData.push_back(p.second); - } - //设置X与Y坐标范围 - //返回xData与yData最大最小值 - //拷贝xData与yData并返回sort - QVector xData_2(xData); - QVector yData_2(yData); - //从小到大排序 - std::sort(xData_2.begin(),xData_2.end()); - std::sort(yData_2.begin(),yData_2.end()); - plot->setAxisScale(QwtPlot::xBottom,xData_2[0],xData_2[xData.length()-1]); - plot->setAxisScale(QwtPlot::yLeft, yData_2[0], yData_2[yData.length()-1]); - //设置数据 - curve->setSamples(xData,yData); + curve->setPen(Qt::blue, 1.0, Qt::DashLine); + curve->setRenderHint(QwtPlotItem::RenderAntialiased, true); + QwtSymbol *symbol = new QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::yellow), QPen(Qt::red, 0.5), QSize(5, 5)); + curve->setSymbol(symbol); + + curve->setSamples(xData, yData); curve->attach(plot); - curve->setLegendAttribute(curve->LegendShowLine); + // 设置坐标轴范围 + auto [xMinIt, xMaxIt] = std::minmax_element(xData.begin(), xData.end()); + auto [yMinIt, yMaxIt] = std::minmax_element(yData.begin(), yData.end()); + plot->setAxisScale(QwtPlot::xBottom, *xMinIt, *xMaxIt); + plot->setAxisScale(QwtPlot::yLeft, *yMinIt, *yMaxIt); + + qDebug() << "x range:" << *xMinIt << "-" << *xMaxIt; + qDebug() << "y range:" << *yMinIt << "-" << *yMaxIt; + + curve->setLegendAttribute(QwtPlotCurve::LegendShowLine); plot->replot(); + qDebug() << "Plot replot done"; + } + + GwmBandwidthSizeSelector::GwmBandwidthSizeSelector() { diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 9c50dec..b25727f 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -96,6 +96,7 @@ void GwmBasicGWRAlgorithm::run() // 点位初始化 emit message(QString(tr("Setting data points")) + (hasRegressionLayer() ? tr(" and regression points") : "") + "."); initPoints(); + mGWRCore->setCoords(mDataPoints); } // 优选模型 @@ -122,41 +123,54 @@ void GwmBasicGWRAlgorithm::run() // 初始化 emit message(QString(tr("Setting X and Y."))); initXY(mX, mY, mDepVar, mIndepVars); + mGWRCore->setDependentVariable(mY); + mGWRCore->setIndependentVariables(mX); + mGWRCore->setSpatialWeight(mSpatialWeight); + mGWRCore->setHasHatMatrix(mHasHatMatrix); + mGWRCore->setBandwidthSelectionCriterion(mBandwidthSelectionCriterionType); + mGWRCore->setIsAutoselectBandwidth(mIsAutoselectBandwidth); + mGWRCore->setTelegram(std::make_unique(this)); } - // 优选带宽 - if (!checkCanceled() && !hasRegressionLayer() && mIsAutoselectBandwidth) - { - emit message(QString(tr("Automatically selecting bandwidth ..."))); - //emit tick(0, 0); - gwm::BandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); - mBandwidthSizeSelector.setBandwidth(bandwidthWeight0); - double lower = bandwidthWeight0->adaptive() ? 20 : 0.0; - double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : mSpatialWeight.distance()->maxDistance(); - mBandwidthSizeSelector.setLower(lower); - mBandwidthSizeSelector.setUpper(upper); - mGWRCore->setCoords(mDataPoints); - mGWRCore->setDependentVariable(mY); - mGWRCore->setIndependentVariables(mX); - mGWRCore->setSpatialWeight(mSpatialWeight); - qDebug()<<"BandwidthWeight"; - gwm::BandwidthWeight* bandwidthWeight = mBandwidthSizeSelector.optimize(mGWRCore.get()); - if (bandwidthWeight && !checkCanceled()) + if (!checkCanceled() && !hasRegressionLayer()) + { + if (mIsAutoselectBandwidth) { - mSpatialWeight.setWeight(bandwidthWeight); - // 绘图 - QVariant data = QVariant::fromValue(mBandwidthSizeSelector.bandwidthCriterion()); - emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); + emit message(QString(tr("Automatically selecting bandwidth ..."))); + + mGWRCore->setParallelType(mParallelType); + + mGWRCore->setTelegram(std::make_unique(this)); + mBetas = mGWRCore->fit(); + + gwm::BandwidthWeight* bw = mGWRCore->spatialWeight().weight(); + + if (bw && !checkCanceled()) + { + mSpatialWeight.setWeight(bw); + + criterionList = mGWRCore->bandwidthSelectionCriterionList(); + // mBandwidthSizeSelector.bandwidthCriterion() = criterionList; + // QVariant data = QVariant::fromValue(criterionList); + QVector> qlist; + for (const auto &item : criterionList) + qlist.append(qMakePair(item.first, item.second)); + QVariant data = QVariant::fromValue(qlist); + emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); + // QVariant data = QVariant::fromValue(mBandwidthSizeSelector.bandwidthCriterion()); + } + std::cout << "mBetas = \n" << mBetas << std::endl; } - } + else + { + mGWRCore->setParallelType(mParallelType); + mBetas = mGWRCore->fit(); - if (!checkCanceled()) - { - qDebug()<<"regression"; - mBetas = regression(mX, mY); - qDebug()<<"regressionend"; + } + + qDebug() << "regression end"; } if (checkCanceled()) @@ -174,12 +188,16 @@ void GwmBasicGWRAlgorithm::run() { uword nDp = mDataPoints.n_rows; // 诊断 - mDiagnostic = CalcDiagnostic(mX, mY, mBetas, mShat); + // mDiagnostic = CalcDiagnostic(mX, mY, mBetas, mShat); + mDiagnostic0 = mGWRCore->diagnostic(); + mShat = mGWRCore->sHat(); + mBetasSE = mGWRCore->betasSE(); double trS = mShat(0), trStS = mShat(1); - double sigmaHat = mDiagnostic.RSS / (nDp - 2 * trS + trStS); + double sigmaHat = mDiagnostic0.RSS / (nDp - 2 * trS + trStS); mBetasSE = sqrt(sigmaHat * mBetasSE); vec yhat = Fitted(mX, mBetas); vec res = mY - yhat; + mQDiag = mGWRCore->qDiag(); vec stu_res = res / sqrt(sigmaHat * mQDiag); mat betasTV = mBetas / mBetasSE; vec dybar2 = (mY - mean(mY)) % (mY - mean(mY)); @@ -1428,8 +1446,22 @@ void GwmBasicGWRAlgorithm::initPoints() mRegressionPoints = mDataPoints; if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - d->setFocusPoints(&mRegressionPoints); + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + { + auto *d = mSpatialWeight.distance(); + if (d) + { + d->makeParameter({ mRegressionPoints, mDataPoints }); + } + } + else if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + { + auto *d2 = mSpatialWeight.distance(); + if (d2) + { + d2->makeParameter({ mRegressionPoints, mDataPoints }); + } + } } } } @@ -1474,29 +1506,37 @@ void GwmBasicGWRAlgorithm::initXY(mat &x, mat &y, const GwmVariable &depVar, con } } -void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) +void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const gwm::GWRBasic::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) { mBandwidthSelectionCriterionType = bandwidthSelectionCriterionType; - QMap, BandwidthSelectCriterionFunction> mapper = { - #ifdef ENABLE_CUDA - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVCuda), - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda), - #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial), - #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp), - #endif - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial), - #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp) - #endif - }; - mBandwidthSelectCriterionFunction = mapper[qMakePair(bandwidthSelectionCriterionType, mParallelType)]; + QMap< + QPair, + BandwidthSelectCriterionFunction + > mapper = { +#ifdef ENABLE_CUDA + { qMakePair(gwm::GWRBasic::CV, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVCuda }, + { qMakePair(gwm::GWRBasic::AIC, gwm::ParallelType::CUDA), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICCuda }, +#endif + { qMakePair(gwm::GWRBasic::CV, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial }, +#ifdef ENABLE_OpenMP + { qMakePair(gwm::GWRBasic::CV, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp }, +#endif + { qMakePair(gwm::GWRBasic::AIC, gwm::ParallelType::SerialOnly), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial }, +#ifdef ENABLE_OpenMP + { qMakePair(gwm::GWRBasic::AIC, gwm::ParallelType::OpenMP), &GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp } +#endif + }; + mBandwidthSelectCriterionFunction = mapper[ + qMakePair(bandwidthSelectionCriterionType, mParallelType) + ]; } void GwmBasicGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { + emit message("setParallelType1"); + qDebug()<<"setParallelType1"; mParallelType = type; - qDebug()<<"setParallelType"; mGWRCore->setParallelType(type); + emit message("setParallelType2"); + qDebug()<<"setParallelType2"; } diff --git a/src/TaskThread/gwmbasicgwralgorithm.h b/src/TaskThread/gwmbasicgwralgorithm.h index 47b37a9..2e23c71 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.h +++ b/src/TaskThread/gwmbasicgwralgorithm.h @@ -95,8 +95,8 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, std::size_t groupSize() const; void setGroupSize(const std::size_t groupSize) override; - BandwidthSelectionCriterionType bandwidthSelectionCriterionType() const; - void setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType); + gwm::GWRBasic::BandwidthSelectionCriterionType bandwidthSelectionCriterionType() const; + void setBandwidthSelectionCriterionType(const gwm::GWRBasic::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType); FTestResultPack fTestResult() const { @@ -249,8 +249,9 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, mat mRegressionLayerX; gwm::BandwidthSelector mBandwidthSizeSelector; + gwm::BandwidthCriterionList criterionList; bool mIsAutoselectBandwidth = false; - BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::AIC; + gwm::GWRBasic::BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = gwm::GWRBasic::BandwidthSelectionCriterionType::AIC; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial; GwmIndependentVariableSelector mIndepVarSelector; @@ -320,7 +321,7 @@ inline void GwmBasicGWRAlgorithm::setIndepVarSelectionThreshold(double indepVarS mIndepVarSelectionThreshold = indepVarSelectionThreshold; } -inline GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType GwmBasicGWRAlgorithm::bandwidthSelectionCriterionType() const +inline gwm::GWRBasic::BandwidthSelectionCriterionType GwmBasicGWRAlgorithm::bandwidthSelectionCriterionType() const { return mBandwidthSelectionCriterionType; } @@ -382,7 +383,7 @@ inline void GwmBasicGWRAlgorithm::setGPUId(const int gpuId) inline gwm::BandwidthCriterionList GwmBasicGWRAlgorithm::bandwidthSelectorCriterions() const { - return mBandwidthSizeSelector.bandwidthCriterion(); + return criterionList; } inline bool GwmBasicGWRAlgorithm::hasPredict() const diff --git a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp index f8791e8..4cc63d1 100644 --- a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp +++ b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp @@ -51,8 +51,22 @@ void GwmGeographicalWeightedRegressionAlgorithm::initPoints() // 设置空间距离中的数据指针 if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) { - gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); - d->makeParameter({ mDataPoints, mDataPoints }); + if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + { + auto *d = mSpatialWeight.distance(); + if (d) + { + d->makeParameter({ mRegressionPoints, mDataPoints }); + } + } + else if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + { + auto *d2 = mSpatialWeight.distance(); + if (d2) + { + d2->makeParameter({ mRegressionPoints, mDataPoints }); + } + } } } diff --git a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.h b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.h index c876fbc..3f0aeed 100644 --- a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.h +++ b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.h @@ -1,4 +1,4 @@ -#ifndef GWMGEOGRAPHICALWEIGHTEDREGRESSIONALGORITHM_H +#ifndef GWMGEOGRAPHICALWEIGHTEDREGRESSIONALGORITHM_H #define GWMGEOGRAPHICALWEIGHTEDREGRESSIONALGORITHM_H #include @@ -102,6 +102,10 @@ class GwmGeographicalWeightedRegressionAlgorithm : public GwmSpatialMonoscaleAlg return mDiagnostic; } + gwm::RegressionDiagnostic diagnostic0() const + { + return mDiagnostic0; + } public: bool hasRegressionLayer() { @@ -125,6 +129,7 @@ class GwmGeographicalWeightedRegressionAlgorithm : public GwmSpatialMonoscaleAlg mat mBetas; GwmDiagnostic mDiagnostic; + gwm::RegressionDiagnostic mDiagnostic0; }; inline QgsVectorLayer *GwmGeographicalWeightedRegressionAlgorithm::regressionLayer() const diff --git a/src/gwmapp.cpp b/src/gwmapp.cpp index 77eaafb..3f920ee 100644 --- a/src/gwmapp.cpp +++ b/src/gwmapp.cpp @@ -1321,7 +1321,7 @@ void GwmApp::onGWRNewBtnClicked() spatialWeight.setWeight(gwm::BandwidthWeight(36, true, gwm::BandwidthWeight::Gaussian)); algorithm->setSpatialWeight(spatialWeight); algorithm->setIsAutoselectBandwidth(true); - algorithm->setBandwidthSelectionCriterionType(GwmBasicGWRAlgorithm::CV); + algorithm->setBandwidthSelectionCriterionType(gwm::GWRBasic::CV); algorithm->setHasHatMatrix(true); algorithm->setHasFTest(true); diff --git a/src/gwmgwroptionsdialog.cpp b/src/gwmgwroptionsdialog.cpp index 6873ed7..2e81693 100644 --- a/src/gwmgwroptionsdialog.cpp +++ b/src/gwmgwroptionsdialog.cpp @@ -386,14 +386,14 @@ double GwmGWROptionsDialog::bandwidthSize(){ } } -GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType GwmGWROptionsDialog::bandwidthSelectionApproach() +gwm::GWRBasic::BandwidthSelectionCriterionType GwmGWROptionsDialog::bandwidthSelectionApproach() { switch (ui->mBwSizeAutomaticApprochCombo->currentIndex()) { case 0: - return GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType::CV; + return gwm::GWRBasic::BandwidthSelectionCriterionType::CV; default: - return GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType::AIC; + return gwm::GWRBasic::BandwidthSelectionCriterionType::AIC; } } diff --git a/src/gwmgwroptionsdialog.h b/src/gwmgwroptionsdialog.h index 2c02909..6a96eff 100644 --- a/src/gwmgwroptionsdialog.h +++ b/src/gwmgwroptionsdialog.h @@ -51,7 +51,7 @@ public slots: QString crsRotateP(); bool bandwidthType(); double bandwidthSize(); - GwmBasicGWRAlgorithm::BandwidthSelectionCriterionType bandwidthSelectionApproach(); + gwm::GWRBasic::BandwidthSelectionCriterionType bandwidthSelectionApproach(); QString bandWidthUnit(); gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); QVariant distanceSourceParameters(); From 053185bb3a8016e4867029e8add6f0e92434d9d1 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Tue, 25 Nov 2025 17:09:16 +0800 Subject: [PATCH 4/6] =?UTF-8?q?Update:=20=E5=90=8E=E7=BB=AD=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/TaskThread/gwmbasicgwralgorithm.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index b25727f..54217f9 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -45,6 +45,7 @@ void GwmBasicGWRAlgorithm::setCanceled(bool canceled) { // mBandwidthSizeSelector.setCanceled(canceled); // mSpatialWeight.distance()->setCanceled(canceled); + qDebug() << "bandwidthauto2"; return GwmTaskThread::setCanceled(canceled); } @@ -96,7 +97,6 @@ void GwmBasicGWRAlgorithm::run() // 点位初始化 emit message(QString(tr("Setting data points")) + (hasRegressionLayer() ? tr(" and regression points") : "") + "."); initPoints(); - mGWRCore->setCoords(mDataPoints); } // 优选模型 @@ -123,43 +123,37 @@ void GwmBasicGWRAlgorithm::run() // 初始化 emit message(QString(tr("Setting X and Y."))); initXY(mX, mY, mDepVar, mIndepVars); + mGWRCore->setCoords(mDataPoints); mGWRCore->setDependentVariable(mY); mGWRCore->setIndependentVariables(mX); mGWRCore->setSpatialWeight(mSpatialWeight); mGWRCore->setHasHatMatrix(mHasHatMatrix); mGWRCore->setBandwidthSelectionCriterion(mBandwidthSelectionCriterionType); mGWRCore->setIsAutoselectBandwidth(mIsAutoselectBandwidth); - mGWRCore->setTelegram(std::make_unique(this)); } - // 优选带宽 if (!checkCanceled() && !hasRegressionLayer()) { if (mIsAutoselectBandwidth) { emit message(QString(tr("Automatically selecting bandwidth ..."))); - mGWRCore->setParallelType(mParallelType); mGWRCore->setTelegram(std::make_unique(this)); mBetas = mGWRCore->fit(); gwm::BandwidthWeight* bw = mGWRCore->spatialWeight().weight(); - if (bw && !checkCanceled()) { mSpatialWeight.setWeight(bw); criterionList = mGWRCore->bandwidthSelectionCriterionList(); - // mBandwidthSizeSelector.bandwidthCriterion() = criterionList; - // QVariant data = QVariant::fromValue(criterionList); QVector> qlist; for (const auto &item : criterionList) qlist.append(qMakePair(item.first, item.second)); QVariant data = QVariant::fromValue(qlist); emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); - // QVariant data = QVariant::fromValue(mBandwidthSizeSelector.bandwidthCriterion()); } std::cout << "mBetas = \n" << mBetas << std::endl; } @@ -167,7 +161,6 @@ void GwmBasicGWRAlgorithm::run() { mGWRCore->setParallelType(mParallelType); mBetas = mGWRCore->fit(); - } qDebug() << "regression end"; @@ -229,6 +222,9 @@ void GwmBasicGWRAlgorithm::run() double trQtQ = DBL_MAX; if (isStoreS()) { + mS = mGWRCore->s(); + qDebug() << "nDp=" << nDp; + qDebug() << "mS.n_rows=" << mS.n_rows << " mS.n_cols=" << mS.n_cols; mat EmS = eye(nDp, nDp) - mS; mat Q = trans(EmS) * EmS; trQtQ = sum(diagvec(trans(Q) * Q)); @@ -249,6 +245,7 @@ void GwmBasicGWRAlgorithm::run() fTestParams.gwrRSS = sum(res % res); fTest(fTestParams); } + qDebug() << "step3"; } } else @@ -1429,7 +1426,7 @@ bool GwmBasicGWRAlgorithm::isValid() if (!mIsAutoselectBandwidth) { - GwmBandwidthWeight* bw = mSpatialWeight.weight(); + gwm::BandwidthWeight* bw = mSpatialWeight.weight(); if (bw->adaptive() && bw->bandwidth() <= mIndepVars.size()) return false; } @@ -1533,10 +1530,6 @@ void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const gwm::GWRBasi void GwmBasicGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - emit message("setParallelType1"); - qDebug()<<"setParallelType1"; mParallelType = type; mGWRCore->setParallelType(type); - emit message("setParallelType2"); - qDebug()<<"setParallelType2"; } From 527016fc6c2c6f18ec0263442fdf4d8c5690c05b Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Tue, 25 Nov 2025 17:49:16 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E5=90=8E=E4=BB=A3=E7=A0=81=E3=80=81=E7=BB=A7=E7=BB=AD=E4=BF=AE?= =?UTF-8?q?=E6=94=B9XXX=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gwmgwaverageoptionsdialog.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/gwmgwaverageoptionsdialog.h b/src/gwmgwaverageoptionsdialog.h index 367ee5c..fb9ceff 100644 --- a/src/gwmgwaverageoptionsdialog.h +++ b/src/gwmgwaverageoptionsdialog.h @@ -54,11 +54,6 @@ public slots: bool bandwidthType(); IParallelalbe::ParallelType approachType(); double bandwidthSize(); -<<<<<<< HEAD -// GwmGWRTaskThread::BandwidthSelectionApproach bandwidthSelectionApproach(); -// QString bandWidthUnit(); -======= ->>>>>>> origin/master gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); GwmDistance::DistanceType distanceSourceType(); QVariant distanceSourceParameters(); @@ -68,8 +63,9 @@ public slots: void updateFields(); void enableAccept(); + GwmLayerGroupItem *selectedLayer() const; void setSelectedLayer(GwmLayerGroupItem *selectedLayer); }; -#endif // GWMGWAVERAGEOPTIONSDIALOG_H \ No newline at end of file +#endif // GWMGWAVERAGEOPTIONSDIALOG_H From 6f6753214cb8bb82f1fb37d570bcb63df697b3f6 Mon Sep 17 00:00:00 2001 From: Shaoqi Yang <1647246791@qq.com> Date: Mon, 29 Dec 2025 01:56:38 +0800 Subject: [PATCH 6/6] fix:GWPCA and RobustGWPCA using library criterion function --- src/CMakeLists.txt | 5 +- src/Model/gwmlayergwpcaitem.cpp | 70 +- src/Model/gwmlayergwpcaitem.h | 6 +- src/PropertyPanelTabs/gwmpropertygwpcatab.cpp | 167 ++-- src/TaskThread/gwmgwpcataskthread.cpp | 713 +++++++++--------- src/TaskThread/gwmgwpcataskthread.h | 56 +- src/gwmapp.cpp | 15 +- src/gwmpropertypanel.cpp | 3 + 8 files changed, 553 insertions(+), 482 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6eaa3cf..f5778be 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -225,7 +225,8 @@ add_subdirectory("./Validity") qt5_wrap_ui(FORMS_H ${FORMS}) if(WIN32) - add_executable(GWmodelS WIN32 ${SOURCES} ${HEADERS} ${FORMS_H} ${app_WINRC} ${GWMODEL_ICONS}) + add_executable(GWmodelS WIN32 ${SOURCES} ${HEADERS} ${FORMS_H} ${app_WINRC} ${GWMODEL_ICONS} + ) endif(WIN32) if(UNIX AND NOT CYGWIN) @@ -273,4 +274,4 @@ target_link_libraries(GWmodelS PRIVATE ${GWMODELCUDA_LIBRARIES} ) -endif(ENABLE_CUDA) \ No newline at end of file +endif(ENABLE_CUDA) diff --git a/src/Model/gwmlayergwpcaitem.cpp b/src/Model/gwmlayergwpcaitem.cpp index 704ba52..80779e2 100644 --- a/src/Model/gwmlayergwpcaitem.cpp +++ b/src/Model/gwmlayergwpcaitem.cpp @@ -1,24 +1,50 @@ -#include "gwmlayergwpcaitem.h" +#include "gwmlayergwpcaitem.h" #include "gwmlayergroupitem.h" #include +#include GwmLayerGWPCAItem::GwmLayerGWPCAItem(GwmLayerItem* parent, QgsVectorLayer* vector, const GwmGWPCATaskThread *taskThread) : GwmLayerVectorItem(parent, vector) { if (taskThread) { - mDResult1 = taskThread->variance(); - mLocalPV = taskThread->localPV(); - mK = taskThread->k(); - mWeight = taskThread->spatialWeight().weight(); - mBandwidthSelScores = taskThread->bandwidthSelectorCriterions(); - - isBandwidthOptimized = taskThread->isAutoselectBandwidth(); - // - mLoadings = taskThread->loadings(); - mScores = taskThread->scores(); - mVariance = taskThread->variance(); + try + { + mDResult1 = taskThread->variance(); + mLocalPV = taskThread->localPV(); + mK = taskThread->k(); + + gwm::SpatialWeight sw = taskThread->spatialWeight(); + gwm::BandwidthWeight* gwmBw = sw.weight(); + if (gwmBw) + { + if(gwmBw->bandwidth() == 0) + { + qDebug() << "[GwmLayerGWPCAItem] WARNING: Bandwidth is 0! This will cause display issues in property panel."; + } + mWeight = gwm::BandwidthWeight(*gwmBw); + } + else + { + qDebug() << "[GwmLayerGWPCAItem] ERROR: Cannot get gwm::BandwidthWeight from spatialWeight!"; + mWeight = gwm::BandwidthWeight(); + } + + mBandwidthSelScores = taskThread->bandwidthSelectorCriterions(); + isBandwidthOptimized = taskThread->isAutoselectBandwidth(); + mLoadings = taskThread->loadings(); + mScores = taskThread->scores(); + mVariance = taskThread->variance(); + } + catch (const std::exception& e) + { + qDebug() << "[GwmLayerGWPCAItem] EXCEPTION during data copy:" << e.what(); + } + catch (...) + { + qDebug() << "[GwmLayerGWPCAItem] UNKNOWN EXCEPTION during data copy"; + } } } @@ -35,8 +61,14 @@ bool GwmLayerGWPCAItem::readXml(QDomNode &node) { double bandwidth = weightNode.attribute("bandwidth").toDouble(); bool adaptive = weightNode.attribute("adaptive").toInt(); - GwmBandwidthWeight::KernelFunctionType kernel = GwmBandwidthWeight::KernelFunctionTypeNameMapper.value(weightNode.attribute("kernel")); - mWeight = GwmBandwidthWeight(bandwidth, adaptive, kernel); + auto it = std::find_if( + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.begin(), + gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end(), + [&](const auto& kv){ return kv.second == weightNode.attribute("kernel").toStdString(); } + ); + gwm::BandwidthWeight::KernelFunctionType kernel = + it != gwm::BandwidthWeight::KernelFunctionTypeNameMapper.end() ? it->first : gwm::BandwidthWeight::Gaussian; + mWeight = gwm::BandwidthWeight(bandwidth, adaptive, kernel); } else return false; @@ -54,6 +86,7 @@ bool GwmLayerGWPCAItem::readXml(QDomNode &node) double criterion = bandwidthNode.attribute("criterion").toDouble(); mBandwidthSelScores.push_back(std::make_pair(size, criterion)); } + bandwidthNode = bandwidthNode.nextSiblingElement("bandwidth"); } } else @@ -104,7 +137,10 @@ bool GwmLayerGWPCAItem::writeXml(QDomNode &node, QDomDocument &doc) nodeAnalyse.setAttribute("k", mK); QDomElement nodeBandwidth = doc.createElement("weight"); - nodeBandwidth.setAttribute("kernel", GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(mWeight.kernel())); + nodeBandwidth.setAttribute( + "kernel", + QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(mWeight.kernel())) + ); nodeBandwidth.setAttribute("bandwidth", mWeight.bandwidth()); nodeBandwidth.setAttribute("adaptive", mWeight.adaptive()); nodeAnalyse.appendChild(nodeBandwidth); @@ -163,12 +199,12 @@ bool GwmLayerGWPCAItem::writeXml(QDomNode &node, QDomDocument &doc) else return false; } -GwmBandwidthWeight GwmLayerGWPCAItem::weight() const +gwm::BandwidthWeight GwmLayerGWPCAItem::weight() const { return mWeight; } -BandwidthCriterionList GwmLayerGWPCAItem::bandwidthSelScores() const +gwm::BandwidthCriterionList GwmLayerGWPCAItem::bandwidthSelScores() const { return mBandwidthSelScores; } diff --git a/src/Model/gwmlayergwpcaitem.h b/src/Model/gwmlayergwpcaitem.h index 578b106..8713e63 100644 --- a/src/Model/gwmlayergwpcaitem.h +++ b/src/Model/gwmlayergwpcaitem.h @@ -24,7 +24,7 @@ class GwmLayerGWPCAItem : public GwmLayerVectorItem virtual bool writeXml(QDomNode &node, QDomDocument &doc) override; public: - GwmBandwidthWeight weight() const; + gwm::BandwidthWeight weight() const; // GwmLayerItem interface public: @@ -35,7 +35,7 @@ class GwmLayerGWPCAItem : public GwmLayerVectorItem return isBandwidthOptimized; } - BandwidthCriterionList bandwidthSelScores() const; + gwm::BandwidthCriterionList bandwidthSelScores() const; public: int mK = 0; @@ -45,7 +45,7 @@ class GwmLayerGWPCAItem : public GwmLayerVectorItem cube mLoadings; cube mScores; mat mVariance; - GwmBandwidthWeight mWeight; + gwm::BandwidthWeight mWeight; BandwidthCriterionList mBandwidthSelScores; }; diff --git a/src/PropertyPanelTabs/gwmpropertygwpcatab.cpp b/src/PropertyPanelTabs/gwmpropertygwpcatab.cpp index c9c5883..e1f3545 100644 --- a/src/PropertyPanelTabs/gwmpropertygwpcatab.cpp +++ b/src/PropertyPanelTabs/gwmpropertygwpcatab.cpp @@ -1,4 +1,4 @@ -#include "gwmpropertygwpcatab.h" +#include "gwmpropertygwpcatab.h" #include "ui_gwmpropertygwpcatab.h" #include @@ -49,10 +49,13 @@ GwmPropertyGWPCATab::~GwmPropertyGWPCATab() void GwmPropertyGWPCATab::updateUI() { if (!mLayerItem) + { + qDebug() << "[GwmPropertyGWPCATab::updateUI] ERROR: mLayerItem is NULL!"; return; + } - GwmBandwidthWeight weight = mLayerItem->weight(); - ui->lblKernelFunction->setText(GwmBandwidthWeight::KernelFunctionTypeNameMapper.name(weight.kernel())); + gwm::BandwidthWeight weight = mLayerItem->weight(); + ui->lblKernelFunction->setText(QString::fromStdString(gwm::BandwidthWeight::KernelFunctionTypeNameMapper.at(weight.kernel()))); ui->lblBandwidthType->setText(weight.adaptive() ? tr("Adaptive") : tr("Fixed")); if (weight.adaptive()) { @@ -70,21 +73,39 @@ void GwmPropertyGWPCATab::updateUI() { ui->lblDistanceMetric->setText(tr("Edclidean distance metric is used.")); } - //ui->lblNumberDataPoints->setText(QString("%1").arg(mLayerItem->dataPointsSize())); ui->lblPCCount->setText(QString("%1").arg(mLayerItem->mK)); - // 计算四分位数 - //QList indepVars = mLayerItem->indepVars(); + qDebug() << "[GwmPropertyGWPCATab::updateUI] Accessing data matrices..."; + const mat& betas = mLayerItem->mLocalPV; + qDebug() << "[GwmPropertyGWPCATab::updateUI] mLocalPV accessed:" << betas.n_rows << "x" << betas.n_cols << ", empty:" << betas.is_empty(); + + const mat& betas2 = mLayerItem->mDResult1; + qDebug() << "[GwmPropertyGWPCATab::updateUI] mDResult1 accessed:" << betas2.n_rows << "x" << betas2.n_cols << ", empty:" << betas2.is_empty(); + + if (betas.is_empty() || betas.n_cols == 0) + { + qDebug() << "[GwmPropertyGWPCATab::updateUI] ERROR: mLocalPV is empty or has no columns"; + return; + } + + if (betas2.is_empty() || betas2.n_cols == 0) + { + qDebug() << "[GwmPropertyGWPCATab::updateUI] ERROR: mDResult1 is empty or has no columns"; + return; + } + + qDebug() << "[GwmPropertyGWPCATab::updateUI] Data matrices are valid, proceeding..."; + + // 计算四分位数 - Local Proportion of Variance ui->tbwProp->setRowCount(mLayerItem->mK+1); ui->tbwProp->setColumnCount(6); ui->tbwProp->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); QStringList headers = QStringList() << tr("Name") << tr("Min") << tr("1st Qu") << tr("Median") << tr("3rd Qu") << tr("Max"); ui->tbwProp->setHorizontalHeaderLabels(headers); - //const mat& betas = mLayerItem->betas(); - const mat& betas2 = mLayerItem->mDResult1; - const mat& betas = mLayerItem->mLocalPV; + const vec p = { 0.0, 0.25, 0.5, 0.75, 1.0 }; - for (uword r = 0; r < betas.n_cols; r++) + uword nCols = std::min((uword)mLayerItem->mK, betas.n_cols); + for (uword r = 0; r < nCols; r++) { vec q = quantile(betas.col(r), p); QString name = QString("Comp.%1").arg(r+1); @@ -104,24 +125,24 @@ void GwmPropertyGWPCATab::updateUI() QString name = QString("Cumulative"); QTableWidgetItem* nameItem = new QTableWidgetItem(name); nameItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); - ui->tbwProp->setItem(betas.n_cols, 0, nameItem); + ui->tbwProp->setItem(nCols, 0, nameItem); for (int c = 0; c < 5; c++) { QTableWidgetItem* quantileItem = new QTableWidgetItem(QString("%1").arg(q(c), 0, 'f', 3)); quantileItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); quantileItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); - ui->tbwProp->setItem(betas.n_cols, c + 1, quantileItem); + ui->tbwProp->setItem(nCols, c + 1, quantileItem); } - ui->tbwLocalvariance->setRowCount(mLayerItem->mK); + uword nVarCols = betas2.n_cols; + uword nDisplayCols = std::min((uword)mLayerItem->mK, nVarCols); + ui->tbwLocalvariance->setRowCount(nDisplayCols); ui->tbwLocalvariance->setColumnCount(6); ui->tbwLocalvariance->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); QStringList headers2 = QStringList() << tr("Name") << tr("Min") << tr("1st Qu") << tr("Median") << tr("3rd Qu") << tr("Max"); - ui->tbwLocalvariance->setHorizontalHeaderLabels(headers); - //const mat& betas = mLayerItem->betas(); - //const mat&betas2 = mLayerItem->mdResult1; - //const vec p = { 0.0, 0.25, 0.5, 0.75, 1.0 }; - for (uword r = 0; r < betas2.n_cols; r++) + ui->tbwLocalvariance->setHorizontalHeaderLabels(headers2); + + for (uword r = 0; r < nDisplayCols; r++) { vec q = quantile(betas2.col(r), p); QString name = QString("Comp.%1").arg(r+1); @@ -136,16 +157,19 @@ void GwmPropertyGWPCATab::updateUI() ui->tbwLocalvariance->setItem(r, c + 1, quantileItem); } } - // 绘制可视化图标 if(mLayerItem->bandwidthOptimized()) { - BandwidthCriterionList bwScores = mLayerItem->bandwidthSelScores(); - QVariant data = QVariant::fromValue(bwScores); + gwm::BandwidthCriterionList bwScores = mLayerItem->bandwidthSelScores(); + qDebug() << "bwScores size:" << bwScores.size(); + QVector> qlist; + for (const auto &item : bwScores) + qlist.append(qMakePair(item.first, item.second)); + QVariant data = QVariant::fromValue(qlist); GwmBandwidthSizeSelector::PlotBandwidthResult(data, mBandwidthSelPlot); } - // 若没有得分数据,则清空表格并返回 - if (mLayerItem->mScores.is_empty()) + + if (mLayerItem->mScores.is_empty() || mLayerItem->mScores.n_rows == 0 || mLayerItem->mScores.n_cols == 0) { ui->tbwScores->setRowCount(0); ui->tbwScores->setColumnCount(0); @@ -154,56 +178,77 @@ void GwmPropertyGWPCATab::updateUI() } else { - // 将 cube(scores) 的所有 slice 按“行拼接”的方式合并为一个二维矩阵 - // 假设 mScores 的维度是 [nSamples x mK x nSlices],每列为一个主成分 - const uword nRows = mLayerItem->mScores.n_rows; - const uword nCols = mLayerItem->mScores.n_cols; // 通常等于 mK - const uword nSlices = mLayerItem->mScores.n_slices; - - mat scoresCombined(nRows * nSlices, nCols); - for (uword s = 0; s < nSlices; s++) + try { - scoresCombined.rows(s * nRows, s * nRows + nRows - 1) = mLayerItem->mScores.slice(s); - } + const uword nRows = mLayerItem->mScores.n_rows; // nDp + const uword nCols = mLayerItem->mScores.n_cols; // mK + const uword nSlices = mLayerItem->mScores.n_slices; // nDp - // 与前面两张表一致的表头与统计分位点 - ui->tbwScores->setRowCount(nCols); - ui->tbwScores->setColumnCount(6); - ui->tbwScores->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + if (nRows == 0 || nCols == 0 || nSlices == 0) + { + ui->tbwScores->setRowCount(0); + ui->tbwScores->setColumnCount(0); + ui->label_5->hide(); + ui->tbwScores->hide(); + return; + } - QStringList scoreHeaders = QStringList() - << tr("Name") << tr("Min") << tr("1st Qu") << tr("Median") << tr("3rd Qu") << tr("Max"); - ui->tbwScores->setHorizontalHeaderLabels(scoreHeaders); + // Local Scores应该是每个数据点在自己的局部PCA空间中的scores + // 即提取对角线上的值:mScores.slice(i)(i, j) for each component j + mat localScores(nRows, nCols, fill::zeros); + for (uword i = 0; i < nRows && i < nSlices; i++) + { + for (uword j = 0; j < nCols; j++) + { + localScores(i, j) = mLayerItem->mScores.slice(i)(i, j); + } + } - const vec p = { 0.0, 0.25, 0.5, 0.75, 1.0 }; - for (uword r = 0; r < scoresCombined.n_cols; r++) - { - // 每个主成分一行:统计所有 slice 和全部样本上的 score 分布 - vec q = quantile(scoresCombined.col(r), p); + ui->tbwScores->setRowCount(nCols); + ui->tbwScores->setColumnCount(6); + ui->tbwScores->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); - QString name = QString("Comp.%1").arg(r + 1); - QTableWidgetItem* nameItem = new QTableWidgetItem(name); - nameItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); - ui->tbwScores->setItem(r, 0, nameItem); + QStringList scoreHeaders = QStringList() + << tr("Name") << tr("Min") << tr("1st Qu") << tr("Median") << tr("3rd Qu") << tr("Max"); + ui->tbwScores->setHorizontalHeaderLabels(scoreHeaders); - for (int c = 0; c < 5; c++) + const vec p = { 0.0, 0.25, 0.5, 0.75, 1.0 }; + for (uword r = 0; r < localScores.n_cols; r++) { - QTableWidgetItem* quantileItem = new QTableWidgetItem(QString("%1").arg(q(c), 0, 'f', 3)); - quantileItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); - quantileItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); - ui->tbwScores->setItem(r, c + 1, quantileItem); + vec q = quantile(localScores.col(r), p); + + QString name = QString("Comp.%1").arg(r + 1); + QTableWidgetItem* nameItem = new QTableWidgetItem(name); + nameItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); + ui->tbwScores->setItem(r, 0, nameItem); + + for (int c = 0; c < 5; c++) + { + QTableWidgetItem* quantileItem = new QTableWidgetItem(QString("%1").arg(q(c), 0, 'f', 3)); + quantileItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); + quantileItem->setFlags(Qt::ItemFlag::NoItemFlags | Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable); + ui->tbwScores->setItem(r, c + 1, quantileItem); + } } } + catch (const std::exception& e) + { + qDebug() << "[GwmPropertyGWPCATab::updateUI] EXCEPTION when processing scores:" << e.what(); + ui->tbwScores->setRowCount(0); + ui->tbwScores->setColumnCount(0); + ui->label_5->hide(); + ui->tbwScores->hide(); + } } } -bool GwmPropertyGWPCATab::openSelectFile()//弹出选择文件对话框 +bool GwmPropertyGWPCATab::openSelectFile() { QString strPath = QFileDialog::getSaveFileName(NULL,QString::fromUtf8("选择文件"),"",QObject::tr("txt(*.txt)")); if(strPath == "") { QMessageBox::information(this,QString::fromUtf8("提示"),QString::fromUtf8("选择文件失败,无路径"),"OK"); - return false;//用户点击的取消按钮 + return false; } FilePath = strPath; return true; @@ -211,20 +256,20 @@ bool GwmPropertyGWPCATab::openSelectFile()//弹出选择文件对话框 void GwmPropertyGWPCATab::on_btnSaveRes_clicked() { - if(false == openSelectFile())//弹出选择文件对话框 如果成功选择文件,主线程myWidget类就有对象存储了文件路径 + if(false == openSelectFile()) { return; } - if(FilePath == "")//如果没有选择文件,即文件路径为空 + if(FilePath == "") { return; } - QFile myfile(FilePath);//创建一个输出文件的文档 - if (myfile.open(QFile::WriteOnly|QFile::Text))//注意WriteOnly是往文本中写入的时候用,ReadOnly是在读文本中内容的时候用,Truncate表示将原来文件中的内容清空 + QFile myfile(FilePath); + if (myfile.open(QFile::WriteOnly|QFile::Text)) { QTextStream out(&myfile); -// 使用组件赋值 + out << " Model Calibration Information"<< Qt::endl; out << "----------------------------------------------"<< Qt::endl; out << "Kernel function: "; out << ui->lblKernelFunction->text() << Qt::endl; diff --git a/src/TaskThread/gwmgwpcataskthread.cpp b/src/TaskThread/gwmgwpcataskthread.cpp index 44e980d..3b5cab1 100644 --- a/src/TaskThread/gwmgwpcataskthread.cpp +++ b/src/TaskThread/gwmgwpcataskthread.cpp @@ -1,4 +1,4 @@ -#include "gwmgwpcataskthread.h" +#include "gwmgwpcataskthread.h" #include #include "TaskThread/gwmgeographicalweightedregressionalgorithm.h" #include "gwmtaskthread.h" @@ -9,11 +9,13 @@ #include #include #include +#include +#include int GwmGWPCATaskThread::treeChildCount = 0; GwmGWPCATaskThread::GwmGWPCATaskThread() : GwmSpatialMonoscaleAlgorithm(), - mGWRCore(std::make_unique()) + mAlgorithm(std::make_unique()) { } @@ -29,10 +31,9 @@ void GwmGWPCATaskThread::run() { if(!checkCanceled()) { - // 设置矩阵 emit message(QString(tr("Setting data points ..."))); initPoints(); - // + emit message(QString(tr("Setting X and Y."))); initXY(mX,mVariables); @@ -41,61 +42,171 @@ void GwmGWPCATaskThread::run() variableZscore(mX); } } - //选带宽 - //这里判断是否选带宽 + if(mIsAutoselectBandwidth && !checkCanceled()) { emit message(QString(tr("Automatically selecting bandwidth ..."))); emit tick(0, 0); - gwm::BandwidthWeight* bandwidthWeight0 = static_cast(mSpatialWeight.weight()); - mSelector.setBandwidth(bandwidthWeight0); + + if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || + mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) + { + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + if(d) + { + d->makeParameter({ mDataPoints, mDataPoints }); + } + } + + gwm::BandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); + if(!bandwidthWeight0) + { + qDebug() << "[GWPCA] ERROR: Cannot get bandwidth weight!"; + emit error(tr("Cannot get bandwidth weight for bandwidth selection.")); + return; + } + double tmpMaxD = mSpatialWeight.distance()->maxDistance(); double lower = bandwidthWeight0->adaptive() ? 2 : tmpMaxD / 5000; double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : tmpMaxD; + + if(bandwidthWeight0->bandwidth() <= 0 || + (bandwidthWeight0->adaptive() && bandwidthWeight0->bandwidth() < lower) || + (!bandwidthWeight0->adaptive() && bandwidthWeight0->bandwidth() < lower)) + { + double initialBandwidth = bandwidthWeight0->adaptive() ? + std::max(2.0, std::min(20.0, (double)mDataPoints.n_rows * 0.1)) : + std::max(lower, tmpMaxD * 0.1); + bandwidthWeight0->setBandwidth(initialBandwidth); + } + + mSelector.setBandwidth(bandwidthWeight0); mSelector.setLower(lower); mSelector.setUpper(upper); - mGWRCore->setCoords(mDataPoints); - // mGWRCore->setDependentVariable(mY); - mGWRCore->setIndependentVariables(mX); - mGWRCore->setSpatialWeight(mSpatialWeight); - gwm::BandwidthWeight* bandwidthWeight = mSelector.optimize(mGWRCore.get()); - if(bandwidthWeight && !checkCanceled()) + + try + { + gwm::BandwidthWeight* bandwidthWeight = mSelector.optimize(this); + if(bandwidthWeight && !checkCanceled()) + { + mSpatialWeight.setWeight(bandwidthWeight); + mSelector.setBandwidth(bandwidthWeight); + + gwm::BandwidthWeight* verifyBw = mSpatialWeight.weight(); + if(verifyBw && verifyBw->bandwidth() == 0) + { + qDebug() << "[GWPCA] ERROR: Bandwidth is 0 after setWeight! This may cause display issues."; + } + } + else if(!bandwidthWeight) + { + qDebug() << "[GWPCA] WARNING: Bandwidth optimization returned NULL"; + emit error(tr("Bandwidth optimization failed: no optimal bandwidth found.")); + return; + } + } + catch(const std::exception& e) + { + qDebug() << "[GWPCA] EXCEPTION during bandwidth optimization:" << e.what(); + emit error(QString(tr("Bandwidth optimization error: %1")).arg(e.what())); + return; + } + catch(...) { - mSpatialWeight.setWeight(bandwidthWeight); + qDebug() << "[GWPCA] UNKNOWN EXCEPTION during bandwidth optimization"; + emit error(tr("Unknown error occurred during bandwidth optimization.")); + return; } } + if(!checkCanceled()) { emit message(QString(tr("Principle components analyzing ..."))); - //存储d的计算值 - mLatestWt = mat(mDataPoints.n_rows,1,fill::zeros); - } - mat sdev; - if(scoresCal() && mDataPoints.n_rows <= 4096 && !checkCanceled()) - { - mLocalPV = pca(mX,mLoadings,sdev,mScores); - } - else - { - mLocalPV = pca(mX,mLoadings,sdev); - mScoresCal = false; - } - mVariance = sdev % sdev; - //准备resultlayer的数据 + try + { + if(Robust()) + { + emit message(QString(tr("Running Robust GWPCA ..."))); + mLocalPV = robustSolveSerial(mX, mLoadings, mSDev); + + if(checkCanceled()) + { + return; + } + + mVariance = mSDev % mSDev; + } + else + { + if(!mAlgorithm) + { + qDebug() << "[GWPCA] ERROR: mAlgorithm is NULL!"; + emit error(tr("GWPCA algorithm object is not initialized.")); + return; + } + + mAlgorithm->setCoords(mDataPoints); + mAlgorithm->setVariables(mX); + mAlgorithm->setSpatialWeight(mSpatialWeight); + mAlgorithm->setKeepComponents(mK); + + if(!mAlgorithm->isValid()) + { + qDebug() << "[GWPCA] ERROR: Algorithm configuration is invalid!"; + emit error(tr("GWPCA algorithm configuration is invalid.")); + return; + } + + mAlgorithm->setTelegram(std::make_unique(this)); + mAlgorithm->run(); + + auto status = mAlgorithm->status(); + if(status != gwm::Status::Success) + { + qDebug() << "[GWPCA] ERROR: Algorithm execution failed with status:" << static_cast(status); + emit error(tr("GWPCA algorithm execution failed.")); + return; + } + + mLocalPV = mAlgorithm->localPV(); + mLoadings = mAlgorithm->loadings(); + mSDev = mAlgorithm->sdev(); + mVariance = mSDev % mSDev; + } + + if(scoresCal() && mDataPoints.n_rows <= 4096) + { + calculateScores(); + } + else + { + mScoresCal = false; + } + } + catch(const std::exception& e) + { + qDebug() << "[GWPCA] EXCEPTION caught:" << e.what(); + emit error(QString(tr("GWPCA execution error: %1")).arg(e.what())); + return; + } + catch(...) + { + qDebug() << "[GWPCA] UNKNOWN EXCEPTION caught"; + emit error(tr("Unknown error occurred during GWPCA execution.")); + return; + } + } - //win_var_PC1 列 - // 取RW矩阵每一行最大的列的索引 QList win_var_PC1; uvec iWinVar = index_max(mLoadings.slice(0), 1); for(int i = 0; i < mDataPoints.n_rows && !checkCanceled(); i++) { win_var_PC1.append(mVariables.at(iWinVar(i)).name); } + if(!checkCanceled()) { - //Com.1_PV列 - //有几列生成几列 CreateResultLayerData resultLayerData = { qMakePair(QString("Comp.%1_PV"), mLocalPV), qMakePair(QString("local_CP"), sum(mLocalPV, 1)) @@ -106,12 +217,9 @@ void GwmGWPCATaskThread::run() } }; createResultLayer(resultLayerData,win_var_PC1); - //进行GlyphPlot + if(getPlot()){ CreatePlotLayerData plotLayerData = {}; -// for(int i = 0; i < mVariables.size(); i++){ -// plotLayerData += qMakePair(mVariables.at(i).name, mLoadings.slice(0).col(i)); -// } vec vecLoadings(mDataPoints.n_rows * mVariables.size()); QList var_pc; int v = 0; @@ -160,8 +268,15 @@ bool GwmGWPCATaskThread::isValid() void GwmGWPCATaskThread::initPoints() { + if(!mDataLayer) + { + qDebug() << "[GWPCA::initPoints] ERROR: Data layer is NULL!"; + return; + } + int nDp = mDataLayer->featureCount(); mDataPoints = mat(nDp, 2, fill::zeros); + QgsFeatureIterator iterator = mDataLayer->getFeatures(); QgsFeature f; for (int i = 0; iterator.nextFeature(f); i++) @@ -170,31 +285,36 @@ void GwmGWPCATaskThread::initPoints() mDataPoints(i, 0) = centroPoint.x(); mDataPoints(i, 1) = centroPoint.y(); } - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) - { - GwmCRSDistance* d = mSpatialWeight.distance(); - d->setDataPoints(&mDataPoints); - d->setFocusPoints(&mDataPoints); - } } void GwmGWPCATaskThread::initXY(mat &x, const QList &indepVars) { int nDp = mDataLayer->featureCount(), nVar = indepVars.size(); - // Data layer and X,Y + x = mat(nDp, nVar, fill::zeros); - //y = vec(nDp, fill::zeros); + QgsFeatureIterator iterator = mDataLayer->getFeatures(); QgsFeature f; bool ok = false; + int errorCount = 0; for (int i = 0; iterator.nextFeature(f); i++) { - //double vY = f.attribute(depVar.name).toDouble(&ok); for (int k = 0; k < indepVars.size(); k++) { double vX = f.attribute(indepVars[k].name).toDouble(&ok); - if (ok) x(i, k) = vX; - else emit error(tr("Independent variable value cannot convert to a number. Set to 0.")); + if (ok) + { + x(i, k) = vX; + } + else + { + errorCount++; + if(errorCount <= 5) + { + qDebug() << "[GWPCA::initXY] WARNING: Cannot convert variable" << indepVars[k].name << "at row" << i << "to number"; + } + emit error(tr("Independent variable value cannot convert to a number. Set to 0.")); + } } } } @@ -209,9 +329,46 @@ void GwmGWPCATaskThread::variableZscore(mat& x) } } + +void GwmGWPCATaskThread::calculateScores() +{ + uword nDp = mDataPoints.n_rows, nVar = mVariables.size(); + mScores = cube(nDp, mK, nDp, fill::zeros); + + for(uword i = 0; i < nDp && !checkCanceled(); i++) + { + vec wt = mSpatialWeight.weightVector(i); + uvec positive = find(wt > 0); + vec newWt = wt.elem(positive); + mat newX = mX.rows(positive); + + if(newWt.n_rows <= 5) + { + break; + } + + mat V; + vec d; + if(!Robust()){ + wpca(newX, newWt, V, d); + }else{ + rwpca(newX, newWt, V, d); + } + + mat scorei(nDp, mK, fill::zeros); + for(int j = 0; j < mK && !checkCanceled(); j++) + { + mat score = newX.each_row() % trans(V.col(j)); + scorei.col(j) = sum(score, 1); + } + mScores.slice(i) = scorei; + emit tick(i + 1, nDp); + } +} + void GwmGWPCATaskThread::wpca(const mat &x, const vec &wt, mat &V, vec &S) { - //首先完成中心化 + mat xw = x.each_col() % wt; mat centerized = (x.each_row() - sum(xw) / sum(wt)).each_col() % sqrt(wt); //SVD @@ -221,16 +378,91 @@ void GwmGWPCATaskThread::wpca(const mat &x, const vec &wt, mat &V, vec &S) //V即为R中的v } -void GwmGWPCATaskThread::rwpca(const mat &x, const vec &wt, mat &coeff, vec &latent, double nu=0, double nv=2) +void GwmGWPCATaskThread::rwpca(const mat &x, const vec &wt, mat &V, vec &S) { - //计算mids + mat mids = x; mids = mids.each_row() - x.row((abs(wt - 0.5)).index_min()); - //计算robustSvd的值 + mat score; vec tsquared; - princomp(coeff, score, latent, tsquared, mids.each_col() % wt); - //?coeff是对的,差一个参数 + princomp(V, score, S, tsquared, mids.each_col() % wt); + +} + +mat GwmGWPCATaskThread::robustSolveSerial(const mat& x, cube& loadings, mat& sdev) +{ + int nDp = mDataPoints.n_rows, nVar = mX.n_cols; + + mat d_all(nVar, nDp, fill::zeros); + + loadings = cube(nDp, nVar, mK, fill::zeros); + + for(int i=0;idistance(i); + vec wt = mSpatialWeight.weightVector(i); + + uvec positive = find(wt > 0); + vec newWt = wt.elem(positive); + mat newX = x.rows(positive); + if(newWt.n_rows<=5) + { + break; + } + + mat V; + vec d; + rwpca(newX,newWt,V,d); + + mLatestWt = newWt; + d_all.col(i) = d; + + for(int j = 0; j < mK && !checkCanceled(); j++) + { + loadings.slice(j).row(i) = trans(V.col(j)); + } + emit tick(i, nDp); + } + + d_all = trans(d_all); + mat variance = (d_all / pow(sum(mLatestWt),0.5)) % (d_all / pow(sum(mLatestWt),0.5)); + + sdev = sqrt(variance); + + mat pv = variance.cols(0, mK - 1).each_col() % (1.0 / sum(variance,1)) * 100.0; + return pv; +} + +gwm::Status GwmGWPCATaskThread::getCriterion(gwm::BandwidthWeight* weight, double& criterion) +{ + if(checkCanceled()) + { + criterion = DBL_MAX; + return gwm::Status::Terminated; + } + + // 将内核库的BandwidthWeight转换为本地的GwmBandwidthWeight + GwmBandwidthWeight::KernelFunctionType kernelType = static_cast(weight->kernel()); + GwmBandwidthWeight localWeight(weight->bandwidth(), weight->adaptive(), kernelType); + + try + { + criterion = (this->*mBandwidthSelectCriterionFunction)(&localWeight); + return gwm::Status::Success; + } + catch(const std::exception& e) + { + qDebug() << "[GWPCA::getCriterion] EXCEPTION:" << e.what(); + criterion = DBL_MAX; + return gwm::Status::Success; + } + catch(...) + { + qDebug() << "[GWPCA::getCriterion] UNKNOWN EXCEPTION"; + criterion = DBL_MAX; + return gwm::Status::Success; + } } void GwmGWPCATaskThread::setBandwidthSelectionCriterionType(const GwmGWPCATaskThread::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) @@ -269,25 +501,8 @@ void GwmGWPCATaskThread::setParallelType(const IParallelalbe::ParallelType &type if(type & parallelAbility()) { mParallelType = type; - switch (type) { - case IParallelalbe::ParallelType::SerialOnly: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mPcaLoadingsSdevScoresFunction = &GwmGWPCATaskThread::pcaLoadingsSdevScoresSerial; - mPcaLoadingsSdevFunction = &GwmGWPCATaskThread::pcaLoadingsSdevSerial; - break; -#ifdef ENABLE_OpenMP - case IParallelalbe::ParallelType::OpenMP: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mPcaLoadingsSdevScoresFunction = &GwmGWPCATaskThread::pcaLoadingsSdevScoresOmp; - mPcaLoadingsSdevFunction = &GwmGWPCATaskThread::pcaLoadingsSdevOmp; - break; -#endif - default: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mPcaLoadingsSdevScoresFunction = &GwmGWPCATaskThread::pcaLoadingsSdevScoresSerial; - mPcaLoadingsSdevFunction = &GwmGWPCATaskThread::pcaLoadingsSdevSerial; - break; - } + setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); + } } @@ -297,7 +512,7 @@ void GwmGWPCATaskThread::createResultLayer(CreateResultLayerData data, QListwkbType()) + QStringLiteral("?"); QString layerName = srcLayer->name(); - //避免图层名重复 + if(treeChildCount > 0) { if(!Robust()) layerName += QStringLiteral("_GWPCA") + "(" + QString::number(treeChildCount) + ")"; @@ -307,7 +522,7 @@ void GwmGWPCATaskThread::createResultLayer(CreateResultLayerData data, QListsetCrs(srcLayer->crs()); - // 设置字段 + QgsFields fields; for (QPair item : data) { @@ -343,7 +558,7 @@ void GwmGWPCATaskThread::createResultLayer(CreateResultLayerData data, QListdataProvider()->addAttributes(fields.toList()); mResultLayer->updateFields(); - // 设置要素几何 + mResultLayer->startEditing(); QgsFeatureIterator iterator = srcLayer->getFeatures(); QgsFeature f; @@ -352,7 +567,6 @@ void GwmGWPCATaskThread::createResultLayer(CreateResultLayerData data, QList item : data) { @@ -375,7 +589,7 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QListwkbType()) + QStringLiteral("?"); QString layerName = srcLayer->name(); - //避免图层名重复 + if(treeChildCount > 0) { layerName += QStringLiteral("_GlyphPlot") + "(" + QString::number(treeChildCount) + ")"; @@ -383,7 +597,7 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QListsetCrs(srcLayer->crs()); - // 设置字段 QgsFields fields; // for (QPair item : data) // { @@ -419,7 +632,7 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QListdataProvider()->addAttributes(fields.toList()); mPlotLayer->updateFields(); - // 设置要素几何 + mPlotLayer->startEditing(); QgsFeatureIterator iterator = srcLayer->getFeatures(); QgsFeature f; @@ -435,9 +648,9 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QList item : data) @@ -453,7 +666,7 @@ void GwmGWPCATaskThread::createPlotLayer(CreatePlotLayerData data, QListtype() == gwm::Distance::CRSDistance || + mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + { + gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + if(d) + { + d->makeParameter({ mDataPoints, mDataPoints }); + } + } + for (int i = 0; i < n && !checkCanceled(); i++) { vec distvi = mSpatialWeight.distance()->distance(i); + if(distvi.n_elem == 0) + { + qDebug() << "[GWPCA::bandwidthSizeCriterionCVSerial] ERROR: Empty distance vector at point" << i; + score = DBL_MAX; + break; + } + vec wt = weight->weight(distvi); wt(i) = 0; - //取wt大于0的部分 - //临时变量?很麻烦 + uvec positive = find(wt > 0); + if(positive.n_elem == 0) + { + qDebug() << "[GWPCA::bandwidthSizeCriterionCVSerial] WARNING: No positive weights at point" << i; + score = DBL_MAX; + break; + } + vec newWt = wt.elem(positive); mat newX = mX.rows(positive); //判断length(newWt) - if(newWt.n_rows <=1) + if(newWt.n_rows <= 1) { + qDebug() << "[GWPCA::bandwidthSizeCriterionCVSerial] WARNING: Insufficient points at" << i << ", n_rows:" << newWt.n_rows; score = DBL_MAX; break; } - //调用PCA函数 - //事先准备好的S和V + mat V; vec S; - wpca(newX, newWt, V, S); - V = V.cols(0, mK - 1); - V = V * trans(V); - score = score + pow(sum(mX.row(i) - mX.row(i) * V),2); + try + { + wpca(newX, newWt, V, S); + if(V.n_cols < mK) + { + qDebug() << "[GWPCA::bandwidthSizeCriterionCVSerial] WARNING: V.n_cols < mK at point" << i; + score = DBL_MAX; + break; + } + V = V.cols(0, mK - 1); + V = V * trans(V); + score = score + pow(sum(mX.row(i) - mX.row(i) * V),2); + } + catch(const std::exception& e) + { + qDebug() << "[GWPCA::bandwidthSizeCriterionCVSerial] EXCEPTION at point" << i << ":" << e.what(); + score = DBL_MAX; + break; + } + mBandwidthCounter++; if (mBandwidthCounter < 10) emit tick(mBandwidthCounter * 10 + i * 5 / n, 100); @@ -520,8 +771,6 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh int n = mX.n_rows; int m = mX.n_cols; double score = 0; - //主循环开始 - //主循环 bool flag = true; vec score_all(mOmpThreadNum, fill::zeros); int current = 0; @@ -533,10 +782,7 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh int thread = omp_get_thread_num(); vec distvi = mSpatialWeight.distance()->distance(i); vec wt = weight->weight(distvi); - qDebug() << weight->bandwidth(); wt(i) = 0; - //取wt大于0的部分 - //临时变量?很麻烦 uvec positive = find(wt > 0); vec newWt = wt.elem(positive); mat newX = mX.rows(positive); @@ -545,10 +791,10 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh { flag=false; }else{ - //调用PCA函数 - //事先准备好的S和V mat V; vec S; + // 带宽选择时总是使用普通GWPCA(wpca),无论是否Robust模式 + // 这样Robust GWPCA会使用与普通GWPCA相同的带宽 wpca(newX, newWt, V, S); V = V.cols(0, mK - 1); V = V * trans(V); @@ -603,262 +849,3 @@ void GwmGWPCATaskThread::setPlot(bool plot) mPlot=plot; } -mat GwmGWPCATaskThread::pcaLoadingsSdevScoresSerial(const mat &x, cube &loadings, mat &stddev, cube &scores) -{ - int nDp = mDataPoints.n_rows, nVar = mVariables.size(); - //存储d的计算值 - mat d_all(nVar, nDp,fill::zeros); - // 初始化矩阵 - loadings = cube(nDp, nVar, mK, fill::zeros); - scores = cube(nDp, mK, nDp, fill::zeros); - for(int i=0;idistance(i); - vec wt = mSpatialWeight.weightVector(i); - //取wt大于0的部分 - //临时变量?很麻烦 - uvec positive = find(wt > 0); - vec newWt = wt.elem(positive); - mat newX = x.rows(positive); - if(newWt.n_rows<=5) - { - break; - } - //调用PCA函数 - //事先准备好的D和V - mat V; - vec d; - if(!Robust()){ - wpca(newX,newWt,V,d); - }else{ - rwpca(newX,newWt,V,d); - } - //存储最新的wt - mLatestWt = newWt; - d_all.col(i) = d; - //计算loadings - for(int j = 0; j < mK && !checkCanceled(); j++) - { - loadings.slice(j).row(i) = trans(V.col(j)); - } - //计算scores - //如果点数大于4096不保存scores - mat scorei(nDp, mK, fill::zeros); - for(int j = 0; j < mK && !checkCanceled(); j++) - { - mat score = newX.each_row() % trans(V.col(j)); - scorei.col(j) = sum(score, 1); - } - scores.slice(i) = scorei; - emit tick(i, nDp); - } - //R代码中的d1计算 - d_all = trans(d_all); - mat variance = (d_all / pow(sum(mLatestWt),0.5)) % (d_all / pow(sum(mLatestWt),0.5)); - //计算sdev - stddev = sqrt(variance); - //dResult1.print(); - //取dResult1的前K列 - mat pv = variance.cols(0, mK - 1).each_col() % (1.0 / sum(variance,1)) * 100.0; - return pv; -} -#ifdef ENABLE_OpenMP -mat GwmGWPCATaskThread::pcaLoadingsSdevScoresOmp(const mat &x, cube &loadings, mat &stddev, cube &scores) -{ - int nDp = mDataPoints.n_rows, nVar = mVariables.size(); - //存储d的计算值 - mat d_all(nVar, nDp, fill::zeros); - // 初始化矩阵 - loadings = cube(nDp, nVar, mK, fill::zeros); - scores = cube(nDp, mK, nDp, fill::zeros); - bool flag = true; - int current = 0; -#pragma omp parallel for num_threads(mOmpThreadNum) - for(int i=0;idistance(i); - vec wt = mSpatialWeight.weightVector(i); - //取wt大于0的部分 - //临时变量?很麻烦 - uvec positive = find(wt > 0); - vec newWt = wt.elem(positive); - mat newX = x.rows(positive); - if(newWt.n_rows<=5) - { - flag = false; - continue; - } - //调用PCA函数 - //事先准备好的D和V - mat V; - vec d; - if(!Robust()){ - wpca(newX,newWt,V,d); - }else{ - rwpca(newX,newWt,V,d); - } - //存储最新的wt - if(i == nDp - 1) - { - mLatestWt = newWt; - } - if (d.n_rows==nVar){ - d_all.col(i) = d; - }else{ - continue; - } - //计算loadings - for(int j=0;jdistance(i); - vec wt = mSpatialWeight.weightVector(i); - //取wt大于0的部分 - //临时变量?很麻烦 - uvec positive = find(wt > 0); - vec newWt = wt.elem(positive); - mat newX = x.rows(positive); - if(newWt.n_rows<=5) - { - break; - } - //调用PCA函数 - //事先准备好的D和V - mat V; - vec d; - if(!Robust()){ - wpca(newX,newWt,V,d); - }else{ - rwpca(newX,newWt,V,d); - } - //存储最新的wt - mLatestWt = newWt; - d_all.col(i) = d; - //计算loadings - for(int j = 0; j < mK && !checkCanceled(); j++) - { - loadings.slice(j).row(i) = trans(V.col(j)); - } - emit tick(i, nDp); - } - //R代码中的d1计算 - d_all = trans(d_all); - mat variance = (d_all / pow(sum(mLatestWt),0.5)) % (d_all / pow(sum(mLatestWt),0.5)); - stddev = sqrt(variance); - //dResult1.print(); - //取dResult1的前K列 - mat pv = variance.cols(0, mK - 1).each_col() % (1.0 / sum(variance,1)) * 100.0; - return pv; -} -#ifdef ENABLE_OpenMP -mat GwmGWPCATaskThread::pcaLoadingsSdevOmp(const mat &x, cube &loadings, mat &stddev) -{ - int nDp = mDataPoints.n_rows, nVar = mVariables.size(); - //存储d的计算值 - mat d_all(nVar, nDp,fill::zeros); - // 初始化矩阵 - loadings = cube(nDp, nVar, mK, fill::zeros); - - bool flag = true; - //scores = cube(nDp, mK, nDp, fill::zeros); - int current = 0; -#pragma omp parallel for num_threads(mOmpThreadNum) - for(int i=0;i 0); - vec newWt = wt.elem(positive); - mat newX = x.rows(positive); - if(newWt.n_rows<=5) - { - flag = false; - continue; - } - //调用PCA函数 - //事先准备好的D和V - mat V; - vec d; - if(!Robust()){ - wpca(newX,newWt,V,d); - }else{ - rwpca(newX,newWt,V,d); - } - //存储最新的wt - if(i == nDp - 1) - { - mLatestWt = newWt; - } - if (d.n_rows==nVar){ - d_all.col(i) = d; - }else{ - continue; - } - //计算loadings - for(int j = 0; j < mK; j++) - { - if(!checkCanceled()) - { - loadings.slice(j).row(i) = trans(V.col(j)); - } - } - emit tick(current++, nDp); - } - } - //R代码中的d1计算 - d_all = trans(d_all); - mat variance = (d_all / pow(sum(mLatestWt),0.5)) % (d_all / pow(sum(mLatestWt),0.5)); - stddev = sqrt(variance); - //dResult1.print(); - //取dResult1的前K列 - mat pv = variance.cols(0, mK - 1).each_col() % (1.0 / sum(variance,1)) * 100.0; - return pv; -} -#endif diff --git a/src/TaskThread/gwmgwpcataskthread.h b/src/TaskThread/gwmgwpcataskthread.h index 93553cc..a558c9c 100644 --- a/src/TaskThread/gwmgwpcataskthread.h +++ b/src/TaskThread/gwmgwpcataskthread.h @@ -1,4 +1,4 @@ -#ifndef GWMGWPCATASKTHREAD_H +#ifndef GWMGWPCATASKTHREAD_H #define GWMGWPCATASKTHREAD_H #include @@ -7,8 +7,9 @@ #include "TaskThread/iparallelable.h" #include "TaskThread/gwmbandwidthsizeselector.h" +#include -class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidthSizeSelectable, public IGwmMultivariableAnalysis, public IOpenmpParallelable +class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidthSizeSelectable, public IGwmMultivariableAnalysis, public IOpenmpParallelable, public gwm::IBandwidthSelectable { Q_OBJECT enum BandwidthSelectionCriterionType @@ -21,9 +22,6 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt typedef double (GwmGWPCATaskThread::*BandwidthSelectCriterionFunction)(GwmBandwidthWeight*); - typedef mat (GwmGWPCATaskThread::*PcaLoadingsSdevScoresFunction)(const mat& , cube& , mat& , cube& ); - typedef mat (GwmGWPCATaskThread::*PcaLoadingsSdev)(const mat&, cube&, mat&); - public: GwmGWPCATaskThread(); @@ -59,6 +57,8 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt mat localPV() const; mat variance() const; + + mat sdev() const; cube loadings() const; @@ -103,32 +103,20 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt void initPoints(); void initXY(mat& x, const QList& indepVars); void variableZscore(mat& x); - //void wpca(const mat &x, const vec &wt, double nu, double nv, mat &V, vec &S); - void wpca(const mat &x, const vec &wt, mat &V, vec &S); - void rwpca(const mat &x, const vec &wt, mat &coeff, vec &latent, double nu, double nv); + void calculateScores(); + void createResultLayer(CreateResultLayerData data,QList winvar); void createPlotLayer(CreatePlotLayerData data, QList varpc); - std::unique_ptr mGWRCore; - - mat pca(const mat& x, cube& loadings, mat& sdev, cube& scores) - { - return (this->*mPcaLoadingsSdevScoresFunction)(x , loadings, sdev, scores); - }; + std::unique_ptr mAlgorithm; + + // wpca函数保留,用于带宽选择(内核库的wpca是私有的,无法直接访问) + void wpca(const mat &x, const vec &wt, mat &V, vec &S); - //实现不计算scores的pca - mat pca(const mat& x, cube& loadings, mat& variance) - { - return (this->*mPcaLoadingsSdevFunction)(x,loadings,variance); - } + // Robust weighted PCA 函数 + void rwpca(const mat &x, const vec &wt, mat &V, vec &S); - mat pcaLoadingsSdevScoresSerial(const mat& x, cube& loadings, mat& stddev, cube& scores); -#ifdef ENABLE_OpenMP - mat pcaLoadingsSdevScoresOmp(const mat& x, cube& loadings, mat& stddev, cube& scores); -#endif - mat pcaLoadingsSdevSerial(const mat& x, cube& loadings, mat& stddev); -#ifdef ENABLE_OpenMP - mat pcaLoadingsSdevOmp(const mat& x, cube& loadings, mat& stddev); -#endif + // Robust GWPCA 求解函数 + mat robustSolveSerial(const mat& x, cube& loadings, mat& sdev); double bandwidthSizeCriterionCVSerial(GwmBandwidthWeight* weight); #ifdef ENABLE_OpenMP @@ -139,6 +127,9 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt return (this->*mBandwidthSelectCriterionFunction)(weight); } +public: // gwm::IBandwidthSelectable interface + gwm::Status getCriterion(gwm::BandwidthWeight* weight, double& criterion) override; + private: QList mVariables; mat mDataPoints; @@ -157,17 +148,13 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt IParallelalbe::ParallelType mParallelType = IParallelalbe::ParallelType::SerialOnly; int mOmpThreadNum = 8; - PcaLoadingsSdevScoresFunction mPcaLoadingsSdevScoresFunction = &GwmGWPCATaskThread::pcaLoadingsSdevScoresSerial; - PcaLoadingsSdev mPcaLoadingsSdevFunction = &GwmGWPCATaskThread::pcaLoadingsSdevSerial; - mat mLocalPV; mat mVariance; + mat mSDev; cube mLoadings; cube mScores; - //用户选择是否Z-score标准化 bool mZscore; - //用户选择是否计算scores bool mScoresCal; @@ -188,6 +175,11 @@ inline mat GwmGWPCATaskThread::variance() const return mVariance; } +inline mat GwmGWPCATaskThread::sdev() const +{ + return mSDev; +} + inline int GwmGWPCATaskThread::parallelAbility() const { return IParallelalbe::SerialOnly diff --git a/src/gwmapp.cpp b/src/gwmapp.cpp index 282dc5f..862a6ed 100644 --- a/src/gwmapp.cpp +++ b/src/gwmapp.cpp @@ -1,4 +1,4 @@ -#include "gwmapp.h" +#include "gwmapp.h" #include "ui_gwmapp.h" #include @@ -1059,7 +1059,6 @@ void GwmApp::onMapSelectionChanged(QgsMapLayer *mapLayer) QgsVectorLayer* layer = static_cast(mapLayer); - // 移除旧的橡皮条 QList rubbers0 = mMapLayerRubberDict[layer]; if (rubbers0.size() > 0) { @@ -1070,7 +1069,6 @@ void GwmApp::onMapSelectionChanged(QgsMapLayer *mapLayer) } rubbers0.clear(); - //添加新的橡皮条 QgsFeatureList selectedFeatures = layer->selectedFeatures(); for (QgsFeature feature : selectedFeatures) { @@ -1163,7 +1161,9 @@ void GwmApp::onMapModelChanged() void GwmApp::onShowLayerProperty(const QModelIndex &index) { + qDebug() << "[GwmApp::onShowLayerProperty] Called with index:" << index; mPropertyPanel->addPropertyTab(index); + qDebug() << "[GwmApp::onShowLayerProperty] addPropertyTab completed"; } @@ -1711,11 +1711,18 @@ void GwmApp::onGWPCABtnClicked() if (progressDlg->exec() == QDialog::Accepted) { QgsVectorLayer* resultLayer = gwpcaTaskThread->resultLayer(); + qDebug() << "[GwmApp::onGWPCABtnClicked] Result layer obtained"; QgsVectorLayer* resultLayer0 = new QgsVectorLayer(); resultLayer0 = resultLayer->clone(); + qDebug() << "[GwmApp::onGWPCABtnClicked] Creating GwmLayerGWPCAItem..."; GwmLayerGWPCAItem * gwrItem = new GwmLayerGWPCAItem(selectedItem, resultLayer0, gwpcaTaskThread); + qDebug() << "[GwmApp::onGWPCABtnClicked] GwmLayerGWPCAItem created"; mMapModel->appentItem(gwrItem, selectedIndex); - onShowLayerProperty(mMapModel->indexFromItem(gwrItem)); + qDebug() << "[GwmApp::onGWPCABtnClicked] Item appended to model"; + QModelIndex itemIndex = mMapModel->indexFromItem(gwrItem); + qDebug() << "[GwmApp::onGWPCABtnClicked] Calling onShowLayerProperty..."; + onShowLayerProperty(itemIndex); + qDebug() << "[GwmApp::onGWPCABtnClicked] onShowLayerProperty completed"; if(gwpcaTaskThread->plotLayer()){ QgsVectorLayer* plotLayer = gwpcaTaskThread->plotLayer(); QgsVectorLayer* plotLayer0 = new QgsVectorLayer(); diff --git a/src/gwmpropertypanel.cpp b/src/gwmpropertypanel.cpp index 0618cac..10461a9 100644 --- a/src/gwmpropertypanel.cpp +++ b/src/gwmpropertypanel.cpp @@ -127,8 +127,11 @@ void GwmPropertyPanel::addPropertyTab(const QModelIndex& index) (static_cast(tabWidget))->updateUI(); break; case GwmLayerItem::GWPCA: + qDebug() << "[GwmPropertyPanel::addPropertyTab] Creating GWPCA property tab..."; tabWidget = new GwmPropertyGWPCATab(this, static_cast(item)); + qDebug() << "[GwmPropertyPanel::addPropertyTab] GWPCA property tab created, calling updateUI..."; (static_cast(tabWidget))->updateUI(); + qDebug() << "[GwmPropertyPanel::addPropertyTab] GWPCA property tab updateUI completed"; break; default: break;