From 3e80e0bbce2c3c3e3abe760aa4e0d0dfbfcf5e93 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Sat, 9 May 2026 15:59:36 +0800 Subject: [PATCH 1/4] update gwr multithreading support --- include/gwmodelpp/GWAverage.h | 4 ++-- include/gwmodelpp/GWRBasic.h | 10 +++++----- include/gwmodelpp/GWRLocalCollinearity.h | 4 ++-- include/gwmodelpp/GWRRobust.h | 2 +- src/gwmodelpp/GWAverage.cpp | 6 +++--- src/gwmodelpp/GWRBasic.cpp | 8 ++++---- src/gwmodelpp/GWRLocalCollinearity.cpp | 10 +++++----- src/gwmodelpp/GWRRobust.cpp | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/gwmodelpp/GWAverage.h b/include/gwmodelpp/GWAverage.h index 2ba38ed7..88131071 100644 --- a/include/gwmodelpp/GWAverage.h +++ b/include/gwmodelpp/GWAverage.h @@ -180,7 +180,7 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP | ParallelType::OpenMP #endif ; @@ -218,7 +218,7 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi */ void GWAverageSerial(); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP /** * @brief \~english GWAverage algorithm implemented with OpenMP. \~chinese GWAverage算法的多线程实现。 */ diff --git a/include/gwmodelpp/GWRBasic.h b/include/gwmodelpp/GWRBasic.h index e333c491..d7bf349a 100644 --- a/include/gwmodelpp/GWRBasic.h +++ b/include/gwmodelpp/GWRBasic.h @@ -517,7 +517,7 @@ class GWRBasic : public GWRBase, public IBandwidthSelectable, public IVarialbeSe arma::mat fitCoreCVSerial(const arma::mat& x, const arma::vec& y, const SpatialWeight& sw); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP /** * \~english @@ -684,16 +684,16 @@ class GWRBasic : public GWRBase, public IBandwidthSelectable, public IVarialbeSe int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP | ParallelType::OpenMP -#endif // ENABLE_OPENMP +#endif // ENABLE_OpenMP #ifdef ENABLE_CUDA | ParallelType::CUDA #endif // ENABLE_CUDA #ifdef ENABLE_MPI -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP | ParallelType::OpenMP -#endif // ENABLE_OPENMP +#endif // ENABLE_OpenMP #ifdef ENABLE_CUDA | ParallelType::CUDA #endif // ENABLE_CUDA diff --git a/include/gwmodelpp/GWRLocalCollinearity.h b/include/gwmodelpp/GWRLocalCollinearity.h index e80bc2fa..ee723d67 100644 --- a/include/gwmodelpp/GWRLocalCollinearity.h +++ b/include/gwmodelpp/GWRLocalCollinearity.h @@ -261,7 +261,7 @@ class GWRLocalCollinearity : public GWRBase, public IBandwidthSelectable, public */ arma::mat predictSerial(const arma::mat& locations, const arma::mat& x, const arma::vec& y); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP /** * @brief \~english Multithreading implementation of prediction function. \~chinese 预测函数的多线程实现。 * @@ -319,7 +319,7 @@ class GWRLocalCollinearity : public GWRBase, public IBandwidthSelectable, public */ double bandwidthSizeCriterionCVSerial(BandwidthWeight* bandwidthWeight); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP /** * @brief \~english Multithreading implementation of calculator to get CV criterion for given bandwidths. \~chinese 获取给定带宽值对应的CV值的多线程实现。 * diff --git a/include/gwmodelpp/GWRRobust.h b/include/gwmodelpp/GWRRobust.h index e22256c7..f10b2854 100644 --- a/include/gwmodelpp/GWRRobust.h +++ b/include/gwmodelpp/GWRRobust.h @@ -73,7 +73,7 @@ class GWRRobust : public GWRBasic private: arma::mat fitSerial(const arma::mat& x, const arma::vec& y, arma::mat& betasSE, arma::vec& shat, arma::vec& qDiag, arma::mat& S); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP //arma::mat predictOmp(const arma::mat& locations, const arma::mat& x, const arma::vec& y); arma::mat fitOmp(const arma::mat& x, const arma::vec& y, arma::mat& betasSE, arma::vec& shat, arma::vec& qDiag, arma::mat& S); #endif diff --git a/src/gwmodelpp/GWAverage.cpp b/src/gwmodelpp/GWAverage.cpp index 91f097c9..ddfd73b3 100644 --- a/src/gwmodelpp/GWAverage.cpp +++ b/src/gwmodelpp/GWAverage.cpp @@ -2,7 +2,7 @@ #include #include -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP #include #endif @@ -115,7 +115,7 @@ void GWAverage::GWAverageSerial() mLCV = mStandardDev / mLocalMean; } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP void GWAverage::GWAverageOmp() { mat rankX = mX; @@ -224,7 +224,7 @@ void GWAverage::updateCalculator() case ParallelType::SerialOnly: mSummaryFunction = &GWAverage::GWAverageSerial; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: mSummaryFunction = &GWAverage::GWAverageOmp; break; diff --git a/src/gwmodelpp/GWRBasic.cpp b/src/gwmodelpp/GWRBasic.cpp index 8985f853..177014db 100644 --- a/src/gwmodelpp/GWRBasic.cpp +++ b/src/gwmodelpp/GWRBasic.cpp @@ -3,7 +3,7 @@ #include "VariableForwardSelector.h" #include "Logger.h" -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP #include #endif @@ -416,7 +416,7 @@ double gwm::GWRBasic::indepVarsSelectionCriterion(const vector& indepVar } } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP mat GWRBasic::predictOmp(const mat& locations, const mat& x, const vec& y) { uword nRp = locations.n_rows, nVar = x.n_cols; @@ -1079,7 +1079,7 @@ void GWRBasic::setParallelType(const ParallelType& type) mFitCoreCVFunction = &GWRBasic::fitCoreCVSerial; mFitCoreSHatFunction = &GWRBasic::fitCoreSHatSerial; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: case ParallelType::MPI_MP: mPredictFunction = &GWRBasic::predictOmp; @@ -1087,7 +1087,7 @@ void GWRBasic::setParallelType(const ParallelType& type) mFitCoreCVFunction = &GWRBasic::fitCoreCVOmp; mFitCoreSHatFunction = &GWRBasic::fitCoreSHatOmp; break; -#endif // ENABLE_OPENMP +#endif // ENABLE_OpenMP #ifdef ENABLE_CUDA case ParallelType::CUDA: case ParallelType::MPI_CUDA: diff --git a/src/gwmodelpp/GWRLocalCollinearity.cpp b/src/gwmodelpp/GWRLocalCollinearity.cpp index 66fc8f99..dc5ed392 100644 --- a/src/gwmodelpp/GWRLocalCollinearity.cpp +++ b/src/gwmodelpp/GWRLocalCollinearity.cpp @@ -3,7 +3,7 @@ #include "VariableForwardSelector.h" #include -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP #include #endif @@ -118,7 +118,7 @@ void GWRLocalCollinearity::setBandwidthSelectionCriterion(const BandwidthSelecti make_pair(BandwidthSelectionCriterionType::CV, &GWRLocalCollinearity::bandwidthSizeCriterionCVSerial), }; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: mapper = { make_pair(BandwidthSelectionCriterionType::CV, &GWRLocalCollinearity::bandwidthSizeCriterionCVOmp) @@ -177,7 +177,7 @@ void GWRLocalCollinearity::setParallelType(const ParallelType& type) mFitFunction = &GWRLocalCollinearity::fitSerial; mPredictFunction = &GWRLocalCollinearity::predictSerial; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: mFitFunction = &GWRLocalCollinearity::fitOmp; mPredictFunction = &GWRLocalCollinearity::predictOmp; @@ -258,7 +258,7 @@ double GWRLocalCollinearity::bandwidthSizeCriterionCVSerial(BandwidthWeight* ban } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP double GWRLocalCollinearity::bandwidthSizeCriterionCVOmp(BandwidthWeight* bandwidthWeight) { //行数 @@ -420,7 +420,7 @@ mat GWRLocalCollinearity::predictSerial(const arma::mat &locations, const mat& x return betas; } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP mat GWRLocalCollinearity::fitOmp(const mat& x, const vec& y, vec& localcn, vec& locallambda) { uword nDp = mCoords.n_rows, nVar = x.n_cols; diff --git a/src/gwmodelpp/GWRRobust.cpp b/src/gwmodelpp/GWRRobust.cpp index dc8c8e1f..5eb5bead 100644 --- a/src/gwmodelpp/GWRRobust.cpp +++ b/src/gwmodelpp/GWRRobust.cpp @@ -4,7 +4,7 @@ #include #include "Logger.h" -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP #include #endif @@ -167,7 +167,7 @@ mat GWRRobust::fitSerial(const mat& x, const vec& y, mat& betasSE, vec& shat, ve return betas.t(); } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP mat GWRRobust::fitOmp(const mat& x, const vec& y, mat& betasSE, vec& shat, vec& qDiag, mat& S) { uword nDp = mCoords.n_rows, nVar = x.n_cols; @@ -323,7 +323,7 @@ void GWRRobust::setParallelType(const ParallelType &type) case ParallelType::SerialOnly: mfitFunction = &GWRRobust::fitSerial; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: mfitFunction = &GWRRobust::fitOmp; break; From c5bbf21cb957950621a482daa84ac4ab80dd43d1 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Thu, 14 May 2026 11:38:24 +0800 Subject: [PATCH 2/4] feat: add multithreading support for gwr --- include/gwmodelpp/GWCorrelation.h | 10 +++++----- src/gwmodelpp/GWCorrelation.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/gwmodelpp/GWCorrelation.h b/include/gwmodelpp/GWCorrelation.h index fb0d5df5..715b3a59 100644 --- a/include/gwmodelpp/GWCorrelation.h +++ b/include/gwmodelpp/GWCorrelation.h @@ -314,7 +314,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ BandwidthSizeCriterionFunction bandwidthSizeCriterionVar(BandwidthSelectionCriterionType type) { -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP if (mParallelType & ParallelType::OpenMP) { switch (type) @@ -327,7 +327,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna return &GWCorrelation::bandwidthSizeCriterionAICOmp; } } -#endif // ENABLE_OPENMP +#endif // ENABLE_OpenMP switch (type) { case BandwidthSelectionCriterionType::CV: @@ -371,7 +371,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ double bandwidthSizeCriterionAICSerial(BandwidthWeight* bandwidthWeight); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP double bandwidthSizeCriterionCVOmp(BandwidthWeight* bandwidthWeight); double bandwidthSizeCriterionAICOmp(BandwidthWeight* bandwidthWeight); @@ -389,7 +389,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP | ParallelType::OpenMP #endif ; @@ -427,7 +427,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ void GWCorrelationSerial(); -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP /** * @brief \~english GWCorrelation algorithm implemented with OpenMP. \~chinese GWCorrelation算法的多线程实现。 */ diff --git a/src/gwmodelpp/GWCorrelation.cpp b/src/gwmodelpp/GWCorrelation.cpp index 0bce1513..2bbd1e32 100644 --- a/src/gwmodelpp/GWCorrelation.cpp +++ b/src/gwmodelpp/GWCorrelation.cpp @@ -5,7 +5,7 @@ #include "Logger.h" #include -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP #include #endif @@ -211,7 +211,7 @@ void GWCorrelation::setParallelType(const ParallelType& type) case ParallelType::SerialOnly: mSummaryFunction = &GWCorrelation::GWCorrelationSerial; break; -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP case ParallelType::OpenMP: mSummaryFunction = &GWCorrelation::GWCorrelationOmp; break; @@ -225,7 +225,7 @@ void GWCorrelation::setParallelType(const ParallelType& type) } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP void GWCorrelation::GWCorrelationOmp() { mat rankX = mX; @@ -339,7 +339,7 @@ double GWCorrelation::bandwidthSizeCriterionCVSerial(BandwidthWeight *bandwidthW return DBL_MAX; } -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP double GWCorrelation::bandwidthSizeCriterionAICOmp(BandwidthWeight *bandwidthWeight) { int var = mBandwidthSelectionCurrentIndex; @@ -396,7 +396,7 @@ double GWCorrelation::bandwidthSizeCriterionAICOmp(BandwidthWeight *bandwidthWei } #endif -#ifdef ENABLE_OPENMP +#ifdef ENABLE_OpenMP double GWCorrelation::bandwidthSizeCriterionCVOmp(BandwidthWeight *bandwidthWeight) { int var = mBandwidthSelectionCurrentIndex; From 4196ec464f0da33fd8e8301ad61fe6726b569193 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Thu, 21 May 2026 14:36:38 +0800 Subject: [PATCH 3/4] Implement ANOVA-based bandwidth selection for GWAverage --- include/gwmodelpp/GWAverage.h | 23 ++- src/gwmodelpp/BandwidthSelector.cpp | 11 +- src/gwmodelpp/GWAverage.cpp | 251 ++++++++++++++++++++++++++-- test/testGWAverage.cpp | 8 + 4 files changed, 278 insertions(+), 15 deletions(-) diff --git a/include/gwmodelpp/GWAverage.h b/include/gwmodelpp/GWAverage.h index 88131071..e599bf8a 100644 --- a/include/gwmodelpp/GWAverage.h +++ b/include/gwmodelpp/GWAverage.h @@ -3,6 +3,7 @@ #include "SpatialMonoscaleAlgorithm.h" #include "IMultivariableAnalysis.h" +#include "IBandwidthSelectable.h" #include "IParallelizable.h" namespace gwm @@ -41,7 +42,7 @@ namespace gwm * - local interquartile ranges <- GWAverage::iqr() * - local quantile imbalances and coordinates <- GWAverage::qi() */ -class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysis, public IParallelizable, public IParallelOpenmpEnabled +class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysis, public IParallelizable, public IParallelOpenmpEnabled, public IBandwidthSelectable { public: @@ -100,6 +101,21 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi */ void setQuantile(bool quantile) { mQuantile = quantile; } + /** + * @brief \~english Get whether bandwidth autoselect is enabled. \~chinese 获取是否启用带宽自动选择。 + * + * @return true \~english if autoselect bandwidth is enabled \~chinese 启用带宽自动选择 + * @return false \~english if autoselect bandwidth is disabled \~chinese 不启用带宽自动选择 + */ + bool isAutoselectBandwidth() const { return mIsAutoselectBandwidth; } + + /** + * @brief \~english Set whether bandwidth autoselect is enabled. \~chinese 设置是否启用带宽自动选择。 + * + * @param isAutoselect \~english whether autoselect bandwidth is enabled \~chinese 是否启用带宽自动选择 + */ + void setAutoselectBandwidth(bool isAutoselect) { mIsAutoselectBandwidth = isAutoselect; } + /** * @brief \~english Get local mean on each sample. \~chinese 获取每个样本的局部均值。 * @@ -171,6 +187,8 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi void setVariables(const arma::mat& x) override { mX = x; } void run() override; + // Implement IBandwidthSelectable + Status getCriterion(BandwidthWeight* weight, double& criterion) override; void calibration(const arma::mat& locations, const arma::mat& x); @@ -238,7 +256,8 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi arma::mat mLocalMedian; //!< \~english Local medians \~chinese 局部中位数 arma::mat mIQR; //!< \~english Local interquartile ranges \~chinese 局部分位距 arma::mat mQI; //!< \~english Local quantile imbalances and coordinates \~chinese 局部分位数不平衡度 - + bool mIsAutoselectBandwidth = false; //!< \~english Whether bandwidth autoselect is enabled \~chinese 是否启用带宽自动选择 + BandwidthCriterionList mBandwidthSelectionCriterionList; //!< \~english List of bandwidth selection criteria \~chinese 带宽选择标准列表 SummaryCalculator mSummaryFunction = &GWAverage::GWAverageSerial; //!< \~english Calculator for summary statistics \~chinese 计算函数 ParallelType mParallelType = ParallelType::SerialOnly; //!< \~english Parallel type \~chinese 并行方法 int mOmpThreadNum = 8; //!< \~english Numbers of threads to be created while paralleling \~chinese 多线程所使用的线程数 diff --git a/src/gwmodelpp/BandwidthSelector.cpp b/src/gwmodelpp/BandwidthSelector.cpp index fbd47670..b631ad43 100644 --- a/src/gwmodelpp/BandwidthSelector.cpp +++ b/src/gwmodelpp/BandwidthSelector.cpp @@ -1,10 +1,14 @@ #include "BandwidthSelector.h" +#include +#include using namespace std; using namespace gwm; BandwidthWeight* BandwidthSelector::optimize(IBandwidthSelectable* instance) { + cerr << "[BandwidthSelector] optimize() starting: lower=" << mLower << ", upper=" << mUpper + << ", adaptive=" << std::boolalpha << mBandwidth->adaptive() << ", kernel=" << mBandwidth->kernel() << "\n"; BandwidthWeight* w1 = static_cast(mBandwidth->clone()); BandwidthWeight* w2 = static_cast(mBandwidth->clone()); double xU = mUpper, xL = mLower; @@ -32,6 +36,8 @@ BandwidthWeight* BandwidthSelector::optimize(IBandwidthSelectable* instance) mBandwidthCriterion[x1] = f1; if (f2 < DBL_MAX) mBandwidthCriterion[x2] = f2; + cerr << fixed << setprecision(6); + cerr << "[BandwidthSelector] initial x1=" << x1 << ", f1=" << f1 << "; x2=" << x2 << ", f2=" << f2 << "\n"; double d1 = f2 - f1; double xopt = f1 < f2 ? x1 : x2; double ea = 100; @@ -47,7 +53,8 @@ BandwidthWeight* BandwidthSelector::optimize(IBandwidthSelectable* instance) w1->setBandwidth(x1); s1 = instance->getCriterion(w1, f1); if (f1 < DBL_MAX) - mBandwidthCriterion[x1] = f1; + mBandwidthCriterion[x1] = f1; + cerr << "[BandwidthSelector] iter=" << iter << " x1=" << x1 << " f1=" << f1 << " x2=" << x2 << " f2=" << f2 << " xopt=" << xopt << " d=" << d << "\n"; } else { @@ -63,9 +70,11 @@ BandwidthWeight* BandwidthSelector::optimize(IBandwidthSelectable* instance) iter = iter + 1; xopt = (f1 < f2) ? x1 : x2; d1 = f2 - f1; + cerr << "[BandwidthSelector] iter=" << iter << " x1=" << x1 << " f1=" << f1 << " x2=" << x2 << " f2=" << f2 << " xopt=" << xopt << " d=" << d << "\n"; } delete w1; delete w2; + cerr << "[BandwidthSelector] optimize completed: xopt=" << xopt << ", s1=" << static_cast(s1) << ", s2=" << static_cast(s2) << "\n"; if (s1 == Status::Success && s2 == Status::Success) { BandwidthWeight* wopt = new BandwidthWeight(); diff --git a/src/gwmodelpp/GWAverage.cpp b/src/gwmodelpp/GWAverage.cpp index ddfd73b3..57abeac6 100644 --- a/src/gwmodelpp/GWAverage.cpp +++ b/src/gwmodelpp/GWAverage.cpp @@ -1,6 +1,10 @@ #include "GWAverage.h" #include +#include #include +#include "BandwidthSelector.h" +#include "Logger.h" +#include #ifdef ENABLE_OpenMP #include @@ -23,6 +27,11 @@ vec GWAverage::del(vec x, uword rowcount){ vec GWAverage::findq(const mat &x, const vec &w) { + if (x.n_rows != w.n_rows || x.n_rows == 0 || !std::all_of(w.begin(), w.end(), [](double v) { return std::isfinite(v); })) + { + return vec(3, fill::zeros); + } + uword lw = w.n_rows; uword lp = 3; vec q = vec(lp,fill::zeros); @@ -67,6 +76,29 @@ void GWAverage::run() createDistanceParameter(); GWM_LOG_STOP_RETURN(mStatus, void()); + if (mIsAutoselectBandwidth) + { + GWM_LOG_STAGE("Bandwidth selection"); + BandwidthWeight* bw0 = mSpatialWeight.weight(); + double lower = bw0->adaptive() ? 2.0 : mSpatialWeight.distance()->minDistance(); + double upper = bw0->adaptive() ? (double)nRp : mSpatialWeight.distance()->maxDistance(); + + GWM_LOG_INFO(IBandwidthSelectable::infoBandwidthCriterion(bw0)); + BandwidthSelector selector(bw0, lower, upper); + BandwidthWeight* bw = selector.optimize(this); + if (bw) + { + mSpatialWeight.setWeight(bw); +#ifdef ENABLE_CUDA + if (mParallelType & ParallelType::CUDA) + { + mSpatialWeight.prepareCuda(mGpuId); + } +#endif // ENABLE_CUDA + mBandwidthSelectionCriterionList = selector.bandwidthCriterion(); + } + } + mLocalMean = mat(nRp, nVar, fill::zeros); mStandardDev = mat(nRp, nVar, fill::zeros); mLocalSkewness = mat(nRp, nVar, fill::zeros); @@ -92,8 +124,16 @@ void GWAverage::GWAverageSerial() { GWM_LOG_STOP_BREAK(mStatus); vec w = mSpatialWeight.weightVector(i); + if (w.n_rows != nRp || !std::all_of(w.begin(), w.end(), [](double v) { return std::isfinite(v); })) + { + w = vec(nRp, fill::zeros); + } double sumw = sum(w); - vec Wi = w / sumw; + vec Wi = arma::zeros(nRp); + if (isfinite(sumw) && sumw != 0.0) + { + Wi = w / sumw; + } mLocalMean.row(i) = trans(Wi) * mX; if (mQuantile) { @@ -104,15 +144,48 @@ void GWAverage::GWAverageSerial() } mLocalMedian.row(i) = quant.row(1); mIQR.row(i) = quant.row(2) - quant.row(0); - mQI.row(i) = (2 * quant.row(1) - quant.row(2) - quant.row(0)) / mIQR.row(i); + rowvec qi = (2 * quant.row(1) - quant.row(2) - quant.row(0)); + for (uword j = 0; j < nVar; j++) + { + double denom = mIQR(i, j); + mQI(i, j) = (isfinite(denom) && denom != 0.0) ? qi(j) / denom : 0.0; + } } mat centerized = mX.each_row() - mLocalMean.row(i); mLVar.row(i) = Wi.t() * (centerized % centerized); mStandardDev.row(i) = sqrt(mLVar.row(i)); - mLocalSkewness.row(i) = (Wi.t() * (centerized % centerized % centerized)) / (mLVar.row(i) % mStandardDev.row(i)); + rowvec denom = mLVar.row(i) % mStandardDev.row(i); + rowvec numerator = trans(Wi) * (centerized % centerized % centerized); + mLocalSkewness.row(i).zeros(); + for (uword j = 0; j < nVar; j++) + { + if (isfinite(denom(j)) && denom(j) != 0.0) + { + mLocalSkewness(i, j) = numerator(j) / denom(j); + } + else + { + mLocalSkewness(i, j) = 0.0; + } + } GWM_LOG_PROGRESS(i + 1, nRp); } - mLCV = mStandardDev / mLocalMean; + mLCV.zeros(); + for (uword i = 0; i < nRp; i++) + { + for (uword j = 0; j < nVar; j++) + { + double meanVal = mLocalMean(i, j); + if (isfinite(meanVal) && meanVal != 0.0) + { + mLCV(i, j) = mStandardDev(i, j) / meanVal; + } + else + { + mLCV(i, j) = 0.0; + } + } + } } #ifdef ENABLE_OpenMP @@ -127,8 +200,16 @@ void GWAverage::GWAverageOmp() { GWM_LOG_STOP_CONTINUE(mStatus); vec w = mSpatialWeight.weightVector(i); + if (w.n_rows != nRp || !std::all_of(w.begin(), w.end(), [](double v) { return std::isfinite(v); })) + { + w = vec(nRp, fill::zeros); + } double sumw = sum(w); - vec Wi = w / sumw; + vec Wi = arma::zeros(nRp); + if (isfinite(sumw) && sumw != 0.0) + { + Wi = w / sumw; + } mLocalMean.row(i) = trans(Wi) * mX; if (mQuantile) { @@ -139,15 +220,48 @@ void GWAverage::GWAverageOmp() } mLocalMedian.row(i) = quant.row(1); mIQR.row(i) = quant.row(2) - quant.row(0); - mQI.row(i) = (2 * quant.row(1) - quant.row(2) - quant.row(0)) / mIQR.row(i); + rowvec qi = (2 * quant.row(1) - quant.row(2) - quant.row(0)); + for (uword j = 0; j < nVar; j++) + { + double denom = mIQR(i, j); + mQI(i, j) = (isfinite(denom) && denom != 0.0) ? qi(j) / denom : 0.0; + } } mat centerized = mX.each_row() - mLocalMean.row(i); mLVar.row(i) = Wi.t() * (centerized % centerized); mStandardDev.row(i) = sqrt(mLVar.row(i)); - mLocalSkewness.row(i) = (Wi.t() * (centerized % centerized % centerized)) / (mLVar.row(i) % mStandardDev.row(i)); + rowvec denom = mLVar.row(i) % mStandardDev.row(i); + rowvec numerator = trans(Wi) * (centerized % centerized % centerized); + mLocalSkewness.row(i).zeros(); + for (uword j = 0; j < nVar; j++) + { + if (isfinite(denom(j)) && denom(j) != 0.0) + { + mLocalSkewness(i, j) = numerator(j) / denom(j); + } + else + { + mLocalSkewness(i, j) = 0.0; + } + } GWM_LOG_PROGRESS(i + 1, nRp); } - mLCV = mStandardDev / mLocalMean; + mLCV.zeros(); + for (uword i = 0; i < nRp; i++) + { + for (uword j = 0; j < nVar; j++) + { + double meanVal = mLocalMean(i, j); + if (isfinite(meanVal) && meanVal != 0.0) + { + mLCV(i, j) = mStandardDev(i, j) / meanVal; + } + else + { + mLCV(i, j) = 0.0; + } + } + } } #endif @@ -186,7 +300,11 @@ void GWAverage::calibration(const mat& locations, const mat& x) GWM_LOG_STOP_BREAK(mStatus); vec w = mSpatialWeight.weightVector(i); double sumw = sum(w); - vec Wi = w / sumw; + vec Wi = arma::zeros(w.n_rows); + if (isfinite(sumw) && sumw != 0.0) + { + Wi = w / sumw; + } mLocalMean.row(i) = trans(Wi) * x; if (mQuantile) { @@ -197,15 +315,48 @@ void GWAverage::calibration(const mat& locations, const mat& x) } mLocalMedian.row(i) = quant.row(1); mIQR.row(i) = quant.row(2) - quant.row(0); - mQI.row(i) = (2 * quant.row(1) - quant.row(2) - quant.row(0)) / mIQR.row(i); + rowvec qi = (2 * quant.row(1) - quant.row(2) - quant.row(0)); + for (uword j = 0; j < nVar; j++) + { + double denom = mIQR(i, j); + mQI(i, j) = (isfinite(denom) && denom != 0.0) ? qi(j) / denom : 0.0; + } } mat centerized = x.each_row() - mLocalMean.row(i); mLVar.row(i) = Wi.t() * (centerized % centerized); mStandardDev.row(i) = sqrt(mLVar.row(i)); - mLocalSkewness.row(i) = (Wi.t() * (centerized % centerized % centerized)) / (mLVar.row(i) % mStandardDev.row(i)); + rowvec denom = mLVar.row(i) % mStandardDev.row(i); + rowvec numerator = trans(Wi) * (centerized % centerized % centerized); + mLocalSkewness.row(i).zeros(); + for (uword j = 0; j < nVar; j++) + { + if (isfinite(denom(j)) && denom(j) != 0.0) + { + mLocalSkewness(i, j) = numerator(j) / denom(j); + } + else + { + mLocalSkewness(i, j) = 0.0; + } + } GWM_LOG_PROGRESS(i + 1, nRp); } - mLCV = mStandardDev / mLocalMean; + mLCV.zeros(); + for (uword i = 0; i < nRp; i++) + { + for (uword j = 0; j < nVar; j++) + { + double meanVal = mLocalMean(i, j); + if (isfinite(meanVal) && meanVal != 0.0) + { + mLCV(i, j) = mStandardDev(i, j) / meanVal; + } + else + { + mLCV(i, j) = 0.0; + } + } + } } void GWAverage::setParallelType(const ParallelType &type) @@ -234,3 +385,79 @@ void GWAverage::updateCalculator() break; } } + +Status GWAverage::getCriterion(BandwidthWeight* weight, double& criterion) +{ + BandwidthWeight* currentBw = mSpatialWeight.weight(); + if (!currentBw || !weight) + { + criterion = DBL_MAX; + return Status::Success; + } + + BandwidthWeight* backup = static_cast(currentBw->clone()); + mSpatialWeight.setWeight(weight); + + uword n = mCoords.n_rows; + uword p = mX.n_cols; + if (n < 2 || p == 0) + { + criterion = DBL_MAX; + mSpatialWeight.setWeight(backup); + delete backup; + return Status::Success; + } + + double totalF = 0.0; + bool valid = false; + + for (uword j = 0; j < p; j++) + { + mat weightedVals(n, n, fill::zeros); + for (uword i = 0; i < n; i++) + { + vec w = mSpatialWeight.weightVector(i); + if (w.n_rows != n) + continue; + weightedVals.col(i) = w % mX.col(j); + } + + double yMean = accu(weightedVals) / double(n * n); + mat centered = weightedVals - yMean; + double SST = accu(centered % centered); + if (!isfinite(SST) || SST < 0.0) + continue; + + rowvec groupMeans = mean(weightedVals, 0); + double SSE = 0.0; + for (uword i = 0; i < n; i++) + { + vec diff = weightedVals.col(i) - groupMeans(i); + SSE += accu(diff % diff); + } + + double SSB = 0.0; + for (uword i = 0; i < n; i++) + { + double meanDiff = groupMeans(i) - yMean; + SSB += double(n) * meanDiff * meanDiff; + } + double MSB = SSB / double(n - 1); + double MSW = SSE / double(n * n - n); + if (!isfinite(MSB) || !isfinite(MSW) || MSW == 0.0) + continue; + + double F = MSB / MSW; + if (!isfinite(F)) + continue; + + totalF += F; + valid = true; + } + + criterion = valid ? -totalF : DBL_MAX; + + mSpatialWeight.setWeight(backup); + delete backup; + return Status::Success; +} diff --git a/test/testGWAverage.cpp b/test/testGWAverage.cpp index 671bb11e..8a8cd1b2 100644 --- a/test/testGWAverage.cpp +++ b/test/testGWAverage.cpp @@ -42,6 +42,10 @@ TEST_CASE("GWAverage: londonhp100") algorithm.setVariables(x); algorithm.setSpatialWeight(spatial); REQUIRE_NOTHROW(algorithm.run()); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localMean())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localSDev())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localSkewness())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localCV())))); vec p = {0.0, 0.25, 0.5, 0.75, 1.0}; @@ -138,6 +142,10 @@ TEST_CASE("GWAverage: londonhp100") algorithm.setParallelType(ParallelType::OpenMP); algorithm.setOmpThreadNum(omp_get_num_threads()); REQUIRE_NOTHROW(algorithm.run()); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localMean())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localSDev())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localSkewness())))); + REQUIRE(arma::all(arma::vectorise(arma::is_finite(algorithm.localCV())))); vec p = {0.0, 0.25, 0.5, 0.75, 1.0}; From 37330207f449c42929db97c4c20c13db4e22024a Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Fri, 10 Jul 2026 14:00:44 +0800 Subject: [PATCH 4/4] end --- include/gwmodelpp/GWAverage.h | 4 ++-- include/gwmodelpp/GWCorrelation.h | 10 +++++----- include/gwmodelpp/GWRBasic.h | 10 +++++----- include/gwmodelpp/GWRLocalCollinearity.h | 4 ++-- include/gwmodelpp/GWRRobust.h | 2 +- src/gwmodelpp/GWAverage.cpp | 6 +++--- src/gwmodelpp/GWCorrelation.cpp | 10 +++++----- src/gwmodelpp/GWRBasic.cpp | 8 ++++---- src/gwmodelpp/GWRLocalCollinearity.cpp | 10 +++++----- src/gwmodelpp/GWRRobust.cpp | 6 +++--- 10 files changed, 35 insertions(+), 35 deletions(-) diff --git a/include/gwmodelpp/GWAverage.h b/include/gwmodelpp/GWAverage.h index e599bf8a..44dea62b 100644 --- a/include/gwmodelpp/GWAverage.h +++ b/include/gwmodelpp/GWAverage.h @@ -198,7 +198,7 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP | ParallelType::OpenMP #endif ; @@ -236,7 +236,7 @@ class GWAverage : public SpatialMonoscaleAlgorithm, public IMultivariableAnalysi */ void GWAverageSerial(); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP /** * @brief \~english GWAverage algorithm implemented with OpenMP. \~chinese GWAverage算法的多线程实现。 */ diff --git a/include/gwmodelpp/GWCorrelation.h b/include/gwmodelpp/GWCorrelation.h index 715b3a59..fb0d5df5 100644 --- a/include/gwmodelpp/GWCorrelation.h +++ b/include/gwmodelpp/GWCorrelation.h @@ -314,7 +314,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ BandwidthSizeCriterionFunction bandwidthSizeCriterionVar(BandwidthSelectionCriterionType type) { -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP if (mParallelType & ParallelType::OpenMP) { switch (type) @@ -327,7 +327,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna return &GWCorrelation::bandwidthSizeCriterionAICOmp; } } -#endif // ENABLE_OpenMP +#endif // ENABLE_OPENMP switch (type) { case BandwidthSelectionCriterionType::CV: @@ -371,7 +371,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ double bandwidthSizeCriterionAICSerial(BandwidthWeight* bandwidthWeight); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP double bandwidthSizeCriterionCVOmp(BandwidthWeight* bandwidthWeight); double bandwidthSizeCriterionAICOmp(BandwidthWeight* bandwidthWeight); @@ -389,7 +389,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP | ParallelType::OpenMP #endif ; @@ -427,7 +427,7 @@ class GWCorrelation : public SpatialMultiscaleAlgorithm, public IMultivariateAna */ void GWCorrelationSerial(); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP /** * @brief \~english GWCorrelation algorithm implemented with OpenMP. \~chinese GWCorrelation算法的多线程实现。 */ diff --git a/include/gwmodelpp/GWRBasic.h b/include/gwmodelpp/GWRBasic.h index d7bf349a..e333c491 100644 --- a/include/gwmodelpp/GWRBasic.h +++ b/include/gwmodelpp/GWRBasic.h @@ -517,7 +517,7 @@ class GWRBasic : public GWRBase, public IBandwidthSelectable, public IVarialbeSe arma::mat fitCoreCVSerial(const arma::mat& x, const arma::vec& y, const SpatialWeight& sw); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP /** * \~english @@ -684,16 +684,16 @@ class GWRBasic : public GWRBase, public IBandwidthSelectable, public IVarialbeSe int parallelAbility() const override { return ParallelType::SerialOnly -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP | ParallelType::OpenMP -#endif // ENABLE_OpenMP +#endif // ENABLE_OPENMP #ifdef ENABLE_CUDA | ParallelType::CUDA #endif // ENABLE_CUDA #ifdef ENABLE_MPI -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP | ParallelType::OpenMP -#endif // ENABLE_OpenMP +#endif // ENABLE_OPENMP #ifdef ENABLE_CUDA | ParallelType::CUDA #endif // ENABLE_CUDA diff --git a/include/gwmodelpp/GWRLocalCollinearity.h b/include/gwmodelpp/GWRLocalCollinearity.h index ee723d67..e80bc2fa 100644 --- a/include/gwmodelpp/GWRLocalCollinearity.h +++ b/include/gwmodelpp/GWRLocalCollinearity.h @@ -261,7 +261,7 @@ class GWRLocalCollinearity : public GWRBase, public IBandwidthSelectable, public */ arma::mat predictSerial(const arma::mat& locations, const arma::mat& x, const arma::vec& y); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP /** * @brief \~english Multithreading implementation of prediction function. \~chinese 预测函数的多线程实现。 * @@ -319,7 +319,7 @@ class GWRLocalCollinearity : public GWRBase, public IBandwidthSelectable, public */ double bandwidthSizeCriterionCVSerial(BandwidthWeight* bandwidthWeight); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP /** * @brief \~english Multithreading implementation of calculator to get CV criterion for given bandwidths. \~chinese 获取给定带宽值对应的CV值的多线程实现。 * diff --git a/include/gwmodelpp/GWRRobust.h b/include/gwmodelpp/GWRRobust.h index f10b2854..e22256c7 100644 --- a/include/gwmodelpp/GWRRobust.h +++ b/include/gwmodelpp/GWRRobust.h @@ -73,7 +73,7 @@ class GWRRobust : public GWRBasic private: arma::mat fitSerial(const arma::mat& x, const arma::vec& y, arma::mat& betasSE, arma::vec& shat, arma::vec& qDiag, arma::mat& S); -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP //arma::mat predictOmp(const arma::mat& locations, const arma::mat& x, const arma::vec& y); arma::mat fitOmp(const arma::mat& x, const arma::vec& y, arma::mat& betasSE, arma::vec& shat, arma::vec& qDiag, arma::mat& S); #endif diff --git a/src/gwmodelpp/GWAverage.cpp b/src/gwmodelpp/GWAverage.cpp index 57abeac6..bf6e10bf 100644 --- a/src/gwmodelpp/GWAverage.cpp +++ b/src/gwmodelpp/GWAverage.cpp @@ -6,7 +6,7 @@ #include "Logger.h" #include -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP #include #endif @@ -188,7 +188,7 @@ void GWAverage::GWAverageSerial() } } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP void GWAverage::GWAverageOmp() { mat rankX = mX; @@ -375,7 +375,7 @@ void GWAverage::updateCalculator() case ParallelType::SerialOnly: mSummaryFunction = &GWAverage::GWAverageSerial; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: mSummaryFunction = &GWAverage::GWAverageOmp; break; diff --git a/src/gwmodelpp/GWCorrelation.cpp b/src/gwmodelpp/GWCorrelation.cpp index 2bbd1e32..0bce1513 100644 --- a/src/gwmodelpp/GWCorrelation.cpp +++ b/src/gwmodelpp/GWCorrelation.cpp @@ -5,7 +5,7 @@ #include "Logger.h" #include -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP #include #endif @@ -211,7 +211,7 @@ void GWCorrelation::setParallelType(const ParallelType& type) case ParallelType::SerialOnly: mSummaryFunction = &GWCorrelation::GWCorrelationSerial; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: mSummaryFunction = &GWCorrelation::GWCorrelationOmp; break; @@ -225,7 +225,7 @@ void GWCorrelation::setParallelType(const ParallelType& type) } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP void GWCorrelation::GWCorrelationOmp() { mat rankX = mX; @@ -339,7 +339,7 @@ double GWCorrelation::bandwidthSizeCriterionCVSerial(BandwidthWeight *bandwidthW return DBL_MAX; } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP double GWCorrelation::bandwidthSizeCriterionAICOmp(BandwidthWeight *bandwidthWeight) { int var = mBandwidthSelectionCurrentIndex; @@ -396,7 +396,7 @@ double GWCorrelation::bandwidthSizeCriterionAICOmp(BandwidthWeight *bandwidthWei } #endif -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP double GWCorrelation::bandwidthSizeCriterionCVOmp(BandwidthWeight *bandwidthWeight) { int var = mBandwidthSelectionCurrentIndex; diff --git a/src/gwmodelpp/GWRBasic.cpp b/src/gwmodelpp/GWRBasic.cpp index 177014db..8985f853 100644 --- a/src/gwmodelpp/GWRBasic.cpp +++ b/src/gwmodelpp/GWRBasic.cpp @@ -3,7 +3,7 @@ #include "VariableForwardSelector.h" #include "Logger.h" -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP #include #endif @@ -416,7 +416,7 @@ double gwm::GWRBasic::indepVarsSelectionCriterion(const vector& indepVar } } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP mat GWRBasic::predictOmp(const mat& locations, const mat& x, const vec& y) { uword nRp = locations.n_rows, nVar = x.n_cols; @@ -1079,7 +1079,7 @@ void GWRBasic::setParallelType(const ParallelType& type) mFitCoreCVFunction = &GWRBasic::fitCoreCVSerial; mFitCoreSHatFunction = &GWRBasic::fitCoreSHatSerial; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: case ParallelType::MPI_MP: mPredictFunction = &GWRBasic::predictOmp; @@ -1087,7 +1087,7 @@ void GWRBasic::setParallelType(const ParallelType& type) mFitCoreCVFunction = &GWRBasic::fitCoreCVOmp; mFitCoreSHatFunction = &GWRBasic::fitCoreSHatOmp; break; -#endif // ENABLE_OpenMP +#endif // ENABLE_OPENMP #ifdef ENABLE_CUDA case ParallelType::CUDA: case ParallelType::MPI_CUDA: diff --git a/src/gwmodelpp/GWRLocalCollinearity.cpp b/src/gwmodelpp/GWRLocalCollinearity.cpp index dc5ed392..66fc8f99 100644 --- a/src/gwmodelpp/GWRLocalCollinearity.cpp +++ b/src/gwmodelpp/GWRLocalCollinearity.cpp @@ -3,7 +3,7 @@ #include "VariableForwardSelector.h" #include -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP #include #endif @@ -118,7 +118,7 @@ void GWRLocalCollinearity::setBandwidthSelectionCriterion(const BandwidthSelecti make_pair(BandwidthSelectionCriterionType::CV, &GWRLocalCollinearity::bandwidthSizeCriterionCVSerial), }; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: mapper = { make_pair(BandwidthSelectionCriterionType::CV, &GWRLocalCollinearity::bandwidthSizeCriterionCVOmp) @@ -177,7 +177,7 @@ void GWRLocalCollinearity::setParallelType(const ParallelType& type) mFitFunction = &GWRLocalCollinearity::fitSerial; mPredictFunction = &GWRLocalCollinearity::predictSerial; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: mFitFunction = &GWRLocalCollinearity::fitOmp; mPredictFunction = &GWRLocalCollinearity::predictOmp; @@ -258,7 +258,7 @@ double GWRLocalCollinearity::bandwidthSizeCriterionCVSerial(BandwidthWeight* ban } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP double GWRLocalCollinearity::bandwidthSizeCriterionCVOmp(BandwidthWeight* bandwidthWeight) { //行数 @@ -420,7 +420,7 @@ mat GWRLocalCollinearity::predictSerial(const arma::mat &locations, const mat& x return betas; } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP mat GWRLocalCollinearity::fitOmp(const mat& x, const vec& y, vec& localcn, vec& locallambda) { uword nDp = mCoords.n_rows, nVar = x.n_cols; diff --git a/src/gwmodelpp/GWRRobust.cpp b/src/gwmodelpp/GWRRobust.cpp index 5eb5bead..dc8c8e1f 100644 --- a/src/gwmodelpp/GWRRobust.cpp +++ b/src/gwmodelpp/GWRRobust.cpp @@ -4,7 +4,7 @@ #include #include "Logger.h" -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP #include #endif @@ -167,7 +167,7 @@ mat GWRRobust::fitSerial(const mat& x, const vec& y, mat& betasSE, vec& shat, ve return betas.t(); } -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP mat GWRRobust::fitOmp(const mat& x, const vec& y, mat& betasSE, vec& shat, vec& qDiag, mat& S) { uword nDp = mCoords.n_rows, nVar = x.n_cols; @@ -323,7 +323,7 @@ void GWRRobust::setParallelType(const ParallelType &type) case ParallelType::SerialOnly: mfitFunction = &GWRRobust::fitSerial; break; -#ifdef ENABLE_OpenMP +#ifdef ENABLE_OPENMP case ParallelType::OpenMP: mfitFunction = &GWRRobust::fitOmp; break;