From 922cdfb100b404d3da2a8a1e45192d8f65b637b4 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Tue, 10 Mar 2026 14:25:02 +0800 Subject: [PATCH 1/6] update lcgwr --- src/TaskThread/gwmscalablegwralgorithm.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/TaskThread/gwmscalablegwralgorithm.cpp b/src/TaskThread/gwmscalablegwralgorithm.cpp index 8aa5716..c3aa810 100644 --- a/src/TaskThread/gwmscalablegwralgorithm.cpp +++ b/src/TaskThread/gwmscalablegwralgorithm.cpp @@ -255,8 +255,12 @@ void GwmScalableGWRAlgorithm::run() mBetas = betas; // mDiagnostic = CalcDiagnostic(mY, mX, mBetas, mShat); mDiagnostic0 = mSGWRCore->diagnostic(); - // arma::uword nDp = mX.n_rows; - // double sigmaHat = mDiagnostic0.RSS / (nDp - 2 * trS + trStS); + mShat = mSGWRCore->sHat(); + mBetasSE = mSGWRCore->betasSE(); + mat betasTV = mBetas / mBetasSE; + double trS = mShat(0), trStS = mShat(1); + arma::uword nDp = mX.n_rows; + double sigmaHat = mDiagnostic0.RSS / (nDp - 2 * trS + trStS); vec yhat = sum(mX % mBetas, 1); vec residual = mY - yhat; @@ -264,9 +268,9 @@ void GwmScalableGWRAlgorithm::run() qMakePair(QString("%1"), mBetas), qMakePair(QString("y"), mY), qMakePair(QString("yhat"), yhat), - qMakePair(QString("residual"), residual) - // qMakePair(QString("%1_SE"), mBetasSE), - // qMakePair(QString("%1_TV"), betasTV) + qMakePair(QString("residual"), residual), + qMakePair(QString("%1_SE"), mBetasSE), + qMakePair(QString("%1_TV"), betasTV) }); } else From 2cd56b0a863e654afb4f2014aa8b27a05cab55eb Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Mon, 20 Apr 2026 15:46:58 +0800 Subject: [PATCH 2/6] sync multithreading GWR implementation --- src/TaskThread/gwmbasicgwralgorithm.cpp | 16 +++++--- src/TaskThread/gwmgeneralizedgwralgorithm.cpp | 26 ++++++------- src/TaskThread/gwmgwpcataskthread.cpp | 38 ++++++++++++++++++- .../gwmlocalcollinearitygwralgorithm.cpp | 9 +++-- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 54217f9..e4cb4a3 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmbasicgwralgorithm.h" +#include "gwmbasicgwralgorithm.h" #include #include #include @@ -826,6 +826,7 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICSerial(GwmBandwidthWeight* double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp(GwmBandwidthWeight *bandwidthWeight) { int nDp = mDataPoints.n_rows, nVar = mIndepVars.size() + 1; + const int selectorStep = static_cast(mBandwidthSizeSelector.bandwidthCriterion().size()); mat betas(nVar, nDp, fill::zeros); mat shat_all(2, mOmpThreadNum, fill::zeros); bool flag = true; @@ -854,8 +855,10 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp(GwmBandwidthWeight *ba { flag = false; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current * 10 / nDp, 100); current++; } } @@ -976,6 +979,7 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVSerial(GwmBandwidthWeight * double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *bandwidthWeight) { int nDp = mDataPoints.n_rows; + const int selectorStep = static_cast(mBandwidthSizeSelector.bandwidthCriterion().size()); vec shat(2, fill::zeros); vec cv_all(mOmpThreadNum, fill::zeros); bool flag = true; @@ -1006,8 +1010,10 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *ban { flag = false; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current * 10 / nDp, 100); current++; } } diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index 9f00eb6..00bdb5f 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -613,7 +613,7 @@ mat GwmGeneralizedGWRAlgorithm::regressionPoissonOmp(const mat &x, const vec &y) mat S(isStoreS ? nDp : 1, nDp, fill::zeros); int current = 0; if(mHasHatMatrix && !checkCanceled()){ - mat shat = mat(2,mOmpThreadNum,fill::zeros); + mat shat = mat(2,mOmpThreadNum,fill::zeros); #pragma omp parallel for num_threads(mOmpThreadNum) for(int i = 0; i < nDp; i++){ mat ci,s_ri; @@ -842,7 +842,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial(GwmBandwid .arg(res); emit message(msg); return res; - } + } else return DBL_MAX; } @@ -907,7 +907,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICSerial(GwmBandwi int n = mDataPoints.n_rows; vec cv = vec(n); mat S = mat(n,n); - mat wt = mat(n,n); + mat wt = mat(n,n); for (int i = 0; i < n && !checkCanceled(); i++) { vec d = mSpatialWeight.distance()->distance(i); @@ -1484,11 +1484,11 @@ void GwmGeneralizedGWRAlgorithm::fTest(FTestParameters params) f3.append(f3i); continue; } - + double g1 = diagB(0); double g2 = diagB(1); double numdf = g1 * g1 / g2; - + // 检查计算结果的有效性 if (g1 <= 0 || g2 <= 0 || numdf <= 0 || !isfinite(numdf)) { @@ -1500,7 +1500,7 @@ void GwmGeneralizedGWRAlgorithm::fTest(FTestParameters params) f3.append(f3i); continue; } - + GwmFTestResult f3i; f3i.s = (vk2(i) / g1) / sigma2delta1; f3i.df1 = numdf; @@ -1540,20 +1540,20 @@ vec GwmGeneralizedGWRAlgorithm::calcDiagBSerial(int i) arma::uword nDp = mX.n_rows, nVar = mX.n_cols; vec diagB(nDp, fill::zeros), c(nDp, fill::zeros); mat wspan(1, nVar, fill::ones); - + // 第一遍循环:计算 c(所有数据点的系数矩阵第 i 列的平均值) for (arma::uword j = 0; j < nDp && !checkCanceled(); j++) { vec wj = mWtMat2.col(j); vec weights = wj % mWt2; - + // 检查权重有效性 if (sum(weights) < 1e-10 || any(weights < 0) || !weights.is_finite()) { emit error("Invalid weights in calcDiagB (first loop)."); return { DBL_MAX, DBL_MAX }; } - + mat xtw = trans(mX % (weights * wspan)); try { // 使用 inv_sympd 替代 pinv,与 BasicGWR 保持一致 @@ -1564,20 +1564,20 @@ vec GwmGeneralizedGWRAlgorithm::calcDiagBSerial(int i) return { DBL_MAX, DBL_MAX }; } } - + // 第二遍循环:计算 diagB for (arma::uword k = 0; k < nDp && !checkCanceled(); k++) { vec wk = mWtMat2.col(k); vec weights = wk % mWt2; - + // 检查权重有效性 if (sum(weights) < 1e-10 || any(weights < 0) || !weights.is_finite()) { emit error("Invalid weights in calcDiagB (second loop)."); return { DBL_MAX, DBL_MAX }; } - + mat xtw = trans(mX % (weights * wspan)); try { // 使用 inv_sympd 替代 pinv,与 BasicGWR 保持一致 @@ -1589,7 +1589,7 @@ vec GwmGeneralizedGWRAlgorithm::calcDiagBSerial(int i) return { DBL_MAX, DBL_MAX }; } } - + diagB = 1.0 / nDp * diagB; return { sum(diagB), sum(diagB % diagB) }; } diff --git a/src/TaskThread/gwmgwpcataskthread.cpp b/src/TaskThread/gwmgwpcataskthread.cpp index d338bd0..43045a6 100644 --- a/src/TaskThread/gwmgwpcataskthread.cpp +++ b/src/TaskThread/gwmgwpcataskthread.cpp @@ -129,6 +129,14 @@ void GwmGWPCATaskThread::run() if(Robust()) { emit message(QString(tr("Running Robust GWPCA ..."))); + + // Robust scores 需要与 loadings 使用同一份 rwpca(V) 结果, + // 否则可能因为特征向量符号不确定性导致 scores 与旧版不一致。 + if (scoresCal()) + { + mScores = cube(mDataPoints.n_rows, mK, mDataPoints.n_rows, fill::zeros); + } + mLocalPV = robustSolveSerial(mX, mLoadings, mSDev); if(checkCanceled()) @@ -137,6 +145,8 @@ void GwmGWPCATaskThread::run() } mVariance = mSDev % mSDev; + + // Robust 分支在 robustSolveSerial() 内已按需要同步填充 mScores。 } else { @@ -318,6 +328,7 @@ void GwmGWPCATaskThread::initPoints() mDataPoints(i, 0) = centroPoint.x(); mDataPoints(i, 1) = centroPoint.y(); } + } void GwmGWPCATaskThread::initXY(mat &x, const QList &indepVars) @@ -452,6 +463,12 @@ mat GwmGWPCATaskThread::robustSolveSerial(const mat& x, cube& loadings, mat& sde mat d_all(nVar, nDp, fill::zeros); loadings = cube(nDp, nVar, mK, fill::zeros); + // 若外层希望输出 scores,则同时计算,确保与 loadings 使用同一份 V。 + const bool needScores = scoresCal(); + if (needScores && mScores.n_elem == 0) + { + mScores = cube(nDp, mK, nDp, fill::zeros); + } for(int i=0;i(mSelector.bandwidthCriterion().size()); #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -855,8 +887,10 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh V = V * trans(V); score_all(thread) += pow(sum(mX.row(i) - mX.row(i) * V),2); } - if(mSelector.counter<10) - emit tick(mSelector.counter * 10 + current * 10 / n, 100); + // if(mSelector.counter<10) + // emit tick(mSelector.counter * 10 + current * 10 / n, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current * 10 / n, 100); current++; } } diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index 70196d8..cc9365d 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmlocalcollinearitygwralgorithm.h" +#include "gwmlocalcollinearitygwralgorithm.h" #include @@ -326,6 +326,7 @@ double GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidt mat mXnot1 = mX.cols(1, mX.n_cols - 1); //主循环 int current = 0; + const int selectorStep = static_cast(selector.bandwidthCriterion().size()); #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -359,8 +360,10 @@ double GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidt } } betas.row(i) = trans( ridgelm(wgt,locallambda(i)) ); - if(selector.counter<10) - emit tick(selector.counter*10 + current * 10 / n, 100); + // if(selector.counter<10) + // emit tick(selector.counter*10 + current * 10 / n, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current * 10 / n, 100); current++; } } From a160f9aa991541a1739981a0565701887af737d4 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Sat, 9 May 2026 11:42:11 +0800 Subject: [PATCH 3/6] fix multithreading support in gwr algorithms --- src/TaskThread/gwmbasicgwralgorithm.cpp | 15 ++++- src/TaskThread/gwmgeneralizedgwralgorithm.cpp | 28 ++++++--- .../gwmlocalcollinearitygwralgorithm.cpp | 57 ++++++++----------- .../gwmlocalcollinearitygwralgorithm.h | 18 +++--- src/TaskThread/gwmrobustgwralgorithm.cpp | 35 ++++-------- src/gwmlcrgwroptionsdialog.cpp | 4 +- 6 files changed, 80 insertions(+), 77 deletions(-) diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index e4cb4a3..c3ad9cb 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmbasicgwralgorithm.h" +#include "gwmbasicgwralgorithm.h" #include #include #include @@ -138,11 +138,22 @@ void GwmBasicGWRAlgorithm::run() if (mIsAutoselectBandwidth) { emit message(QString(tr("Automatically selecting bandwidth ..."))); + qDebug() << "ParallelType in run before =" << mParallelType; + qDebug() << "OmpThreadNum in run before =" << mOmpThreadNum; mGWRCore->setParallelType(mParallelType); + mGWRCore->setOmpThreadNum(mOmpThreadNum); + qDebug() << "core parallelType =" << mGWRCore->parallelType(); + qDebug() << "core parallelAbility =" << mGWRCore->parallelAbility(); mGWRCore->setTelegram(std::make_unique(this)); + QElapsedTimer timer; + timer.start(); + mBetas = mGWRCore->fit(); + qint64 elapsed = timer.elapsed(); + qDebug() << "fit() time =" << elapsed << "ms"; + gwm::BandwidthWeight* bw = mGWRCore->spatialWeight().weight(); if (bw && !checkCanceled()) { @@ -155,7 +166,7 @@ void GwmBasicGWRAlgorithm::run() QVariant data = QVariant::fromValue(qlist); emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); } - std::cout << "mBetas = \n" << mBetas << std::endl; + // std::cout << "mBetas = \n" << mBetas << std::endl; } else { diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index 00bdb5f..6dda9cf 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -853,6 +853,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthW vec cv = vec(n); mat wt = mat(n,n); int current1 = 0, current2 = 0; + const int selectorStep = static_cast(mBandwidthSizeSelector.bandwidthCriterion().size()); #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -862,9 +863,11 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthW vec w = bandwidthWeight->weight(d); w.row(i) = 0; wt.col(i) = w; - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current1 * 5 / n, 100); - current1++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current2 * 5 / n + 5, 100); + current2++; } } if (!checkCanceled()) (this->*mCalWtFunction)(mX,mY,wt); @@ -881,8 +884,10 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthW else{ cv.row(i) = mY.row(i) - exp(yhatnoi)/(1+exp(yhatnoi)); } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current2 * 5 / n + 5, 100); current2++; } } @@ -959,6 +964,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp(GwmBandwidth mat S = mat(n,n); mat wt = mat(n,n); int current1 = 0, current2 = 0; + const int selectorStep = static_cast(mBandwidthSizeSelector.bandwidthCriterion().size()); #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -967,8 +973,10 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp(GwmBandwidth vec d = mSpatialWeight.distance()->distance(i); vec w = bandwidthWeight->weight(d); wt.col(i) = w; - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current1 * 5 / n, 100); + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current1 * 5 / n, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current1 * 5 / n, 100); current1++; } } @@ -983,8 +991,10 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp(GwmBandwidth mat Ci = CiMat(mX,wi); S.row(i) = mX.row(i) * Ci; trS(thread) += S(i,i); - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + if (selectorStep < 10) + emit tick(selectorStep * 10 + current2 * 5 / n + 5, 100); current2++; } } diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index cc9365d..0eb7024 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -1,4 +1,4 @@ -#include "gwmlocalcollinearitygwralgorithm.h" +#include "gwmlocalcollinearitygwralgorithm.h" #include @@ -75,8 +75,20 @@ void GwmLocalCollinearityGWRAlgorithm::run() mLCGWRCore->setTelegram(std::make_unique(this)); + mLCGWRCore->setParallelType(mParallelType); + mLCGWRCore->setOmpThreadNum(mOmpThreadNum); + qDebug() << "core parallelType =" << mLCGWRCore->parallelType(); + qDebug() << "core parallelAbility =" << mLCGWRCore->parallelAbility(); + + QElapsedTimer timer; + timer.start(); + mBetas = mLCGWRCore->fit(); - std::cout << "mBetas = \n" << mBetas << std::endl; + + qint64 elapsed = timer.elapsed(); + qDebug() << "fit() time =" << elapsed << "ms"; + + // std::cout << "mBetas = \n" << mBetas << std::endl; gwm::BandwidthWeight* bw = mLCGWRCore->spatialWeight().weight(); mSpatialWeight.setWeight(bw); @@ -117,18 +129,18 @@ bool GwmLocalCollinearityGWRAlgorithm::isAutoselectBandwidth() const return mIsAutoselectBandwidth; } -void GwmLocalCollinearityGWRAlgorithm::setBandwidthSelectionCriterionType(const GwmLocalCollinearityGWRAlgorithm::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) +void GwmLocalCollinearityGWRAlgorithm::setBandwidthSelectionCriterionType(const gwm::GWRBasic::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType) { mBandwidthSelectionCriterionType = bandwidthSelectionCriterionType; - QMap, BandwidthSelectCriterionFunction> mapper = { - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::SerialOnly), &GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVSerial), + QMap, BandwidthSelectCriterionFunction> mapper = { + std::make_pair(qMakePair(gwm::GWRBasic::CV, gwm::ParallelType::SerialOnly), &GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVSerial), #ifdef ENABLE_OpenMP - std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::OpenMP), &GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVOmp), + std::make_pair(qMakePair(gwm::GWRBasic::CV, gwm::ParallelType::OpenMP), &GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVOmp), #endif - //std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, IParallelalbe::ParallelType::CUDA), &GwmLcrGWRTaskThread::bandwidthSizeCriterionCVCuda), - //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::SerialOnly), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICSerial), - //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::OpenMP), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICOmp), - //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, IParallelalbe::ParallelType::CUDA), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICCuda) + //std::make_pair(qMakePair(BandwidthSelectionCriterionType::CV, gwm::ParallelType::CUDA), &GwmLcrGWRTaskThread::bandwidthSizeCriterionCVCuda), + //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::SerialOnly), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICSerial), + //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::OpenMP), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICOmp), + //std::make_pair(qMakePair(BandwidthSelectionCriterionType::AIC, gwm::ParallelType::CUDA), &GwmLcrGWRTaskThread::bandwidthSizeCriterionAICCuda) }; mBandwidthSelectCriterionFunction = mapper[qMakePair(bandwidthSelectionCriterionType, mParallelType)]; } @@ -501,29 +513,10 @@ mat GwmLocalCollinearityGWRAlgorithm::regressionOmp(const mat &x, const vec &y) return betas; } #endif -void GwmLocalCollinearityGWRAlgorithm::setParallelType(const IParallelalbe::ParallelType &type) +void GwmLocalCollinearityGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - if(type & parallelAbility()) - { - mParallelType = type; - switch(type) - { - case IParallelalbe::ParallelType::SerialOnly: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mRegressionFunction = &GwmLocalCollinearityGWRAlgorithm::regressionSerial; - break; -#ifdef ENABLE_OpenMP - case IParallelalbe::ParallelType::OpenMP: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mRegressionFunction = &GwmLocalCollinearityGWRAlgorithm::regressionOmp; - break; -#endif - default: - setBandwidthSelectionCriterionType(mBandwidthSelectionCriterionType); - mRegressionFunction = &GwmLocalCollinearityGWRAlgorithm::regressionSerial; - break; - } - } + mParallelType = type; + mLCGWRCore->setParallelType(type); } bool GwmLocalCollinearityGWRAlgorithm::lambdaAdjust() const diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h index 1e24c60..1e31761 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h @@ -11,7 +11,7 @@ using namespace arma; -class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable,public IOpenmpParallelable +class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public IIndependentVariableSelectable, public gwm::IParallelizable, public gwm::IParallelOpenmpEnabled, public gwm::IParallelCudaEnabled { public: @@ -71,8 +71,8 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA return criterionList; } - BandwidthSelectionCriterionType bandwidthSelectionCriterionType() const; - void setBandwidthSelectionCriterionType(const BandwidthSelectionCriterionType &bandwidthSelectionCriterionType); + gwm::GWRBasic::BandwidthSelectionCriterionType bandwidthSelectionCriterionType() const; + void setBandwidthSelectionCriterionType(const gwm::GWRBasic::BandwidthSelectionCriterionType &bandwidthSelectionCriterionType); public: bool isValid() override; @@ -92,9 +92,9 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA void createResultLayer(CreateResultLayerData data); public: 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; // IOpenmpParallelable interface public: @@ -127,7 +127,7 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA #ifdef ENABLE_OpenMP double bandwidthSizeCriterionCVOmp(GwmBandwidthWeight* weight); #endif - BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::CV; + gwm::GWRBasic::BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = gwm::GWRBasic::BandwidthSelectionCriterionType::CV; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVSerial; mat regressionSerial(const mat& x, const vec& y); @@ -136,7 +136,7 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA #endif Regression mRegressionFunction = &GwmLocalCollinearityGWRAlgorithm::regressionSerial; - IParallelalbe::ParallelType mParallelType = IParallelalbe::ParallelType::SerialOnly; + gwm::ParallelType mParallelType = gwm::ParallelType::SerialOnly; int mOmpThreadNum = 8; int mGpuId = 0; int mGroupSize = 64; @@ -146,10 +146,10 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA inline int GwmLocalCollinearityGWRAlgorithm::parallelAbility() const { - return IParallelalbe::SerialOnly | IParallelalbe::OpenMP; + return gwm::SerialOnly | gwm::OpenMP; } -inline IParallelalbe::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const +inline gwm::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const { return mParallelType; } diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index fe9e9e1..a595735 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.cpp +++ b/src/TaskThread/gwmrobustgwralgorithm.cpp @@ -55,9 +55,20 @@ void GwmRobustGWRAlgorithm::run() { emit message("Regression ..."); mRGWRCore->setParallelType(mParallelType); + mRGWRCore->setOmpThreadNum(mOmpThreadNum); + qDebug() << "core parallelType =" << mRGWRCore->parallelType(); + qDebug() << "core parallelAbility =" << mRGWRCore->parallelAbility(); mRGWRCore->setTelegram(std::make_unique(this)); + + QElapsedTimer timer; + timer.start(); + mBetas = mRGWRCore->fit(); - qDebug() << "mBetas:"; mBetas.print(); + + qint64 elapsed = timer.elapsed(); + qDebug() << "fit() time =" << elapsed << "ms"; + + // qDebug() << "mBetas:"; mBetas.print(); } if(mOLS&&!checkCanceled()){ @@ -259,28 +270,6 @@ void GwmRobustGWRAlgorithm::createResultLayer(CreateResultLayerData data) void GwmRobustGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { GwmBasicGWRAlgorithm::setParallelType(type); - if (type & parallelAbility()) - { - mParallelType = type; - switch (type) { - case gwm::ParallelType::SerialOnly: - mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixSerial; - break; -#ifdef ENABLE_OpenMP - case gwm::ParallelType::OpenMP: - mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixOmp; - break; -#endif -#ifdef ENABLE_CUDA - case gwm::ParallelType::CUDA: - mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixCuda; - break; -#endif - default: - mRegressionHatmatrixFunction = &GwmRobustGWRAlgorithm::regressionHatmatrixSerial; - break; - } - } } mat GwmRobustGWRAlgorithm::robustGWRCaliFirst(const mat &x, const vec &y, mat &betasSE, vec &shat, vec &qDiag, mat &S) diff --git a/src/gwmlcrgwroptionsdialog.cpp b/src/gwmlcrgwroptionsdialog.cpp index e4e91b1..0610fac 100644 --- a/src/gwmlcrgwroptionsdialog.cpp +++ b/src/gwmlcrgwroptionsdialog.cpp @@ -498,11 +498,11 @@ void GwmLcrGWROptionsDialog::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()); } // 其他设置 From 8de413fdff8732da1158f1b3583cc4c1b83e2d44 Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Thu, 14 May 2026 16:04:59 +0800 Subject: [PATCH 4/6] 111 --- src/TaskThread/gwmbasicgwralgorithm.cpp | 4 ++-- src/TaskThread/gwmgwaveragetaskthread.cpp | 4 +++- src/TaskThread/gwmgwcorrelationtaskthread.cpp | 2 ++ src/TaskThread/gwmgwpcataskthread.cpp | 2 +- src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp | 4 ++-- src/TaskThread/gwmrobustgwralgorithm.cpp | 2 +- src/gwmgwcorrelationoptionsdialog.cpp | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index c3ad9cb..559ac2d 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -1547,6 +1547,6 @@ void GwmBasicGWRAlgorithm::setBandwidthSelectionCriterionType(const gwm::GWRBasi void GwmBasicGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - mParallelType = type; - mGWRCore->setParallelType(type); + // mParallelType = type; + // mGWRCore->setParallelType(type); } diff --git a/src/TaskThread/gwmgwaveragetaskthread.cpp b/src/TaskThread/gwmgwaveragetaskthread.cpp index 480c760..2bf54d8 100644 --- a/src/TaskThread/gwmgwaveragetaskthread.cpp +++ b/src/TaskThread/gwmgwaveragetaskthread.cpp @@ -1,4 +1,4 @@ -#include "gwmgwaveragetaskthread.h" +#include "gwmgwaveragetaskthread.h" #include #include #include "SpatialWeight/gwmcrsdistance.h" @@ -75,6 +75,8 @@ void GwmGWAverageTaskThread::run() try { mAlgorithm.setTelegram(make_unique(this)); + qDebug() << "core parallelType =" << mAlgorithm.parallelType(); + qDebug() << "core parallelAbility =" << mAlgorithm.parallelAbility(); mAlgorithm.run(); if(!checkCanceled()) { diff --git a/src/TaskThread/gwmgwcorrelationtaskthread.cpp b/src/TaskThread/gwmgwcorrelationtaskthread.cpp index 80216fc..03b3c56 100644 --- a/src/TaskThread/gwmgwcorrelationtaskthread.cpp +++ b/src/TaskThread/gwmgwcorrelationtaskthread.cpp @@ -197,6 +197,8 @@ void GwmGWCorrelationTaskThread::run() mGWCorrCore->setBandwidthSelectionApproach(bandwidthSelTypes); mGWCorrCore->setParallelType(static_cast(mParallelType)); mGWCorrCore->setOmpThreadNum(mOmpThreadNum); + qDebug() << "core parallelType =" << mGWCorrCore->parallelType(); + qDebug() << "core parallelAbility =" << mGWCorrCore->parallelAbility(); // std::vector a = mGWCorrCore->spatialWeights(); // gwm::BandwidthWeight bwa = a[0].weight(); diff --git a/src/TaskThread/gwmgwpcataskthread.cpp b/src/TaskThread/gwmgwpcataskthread.cpp index 43045a6..385a2e2 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" diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index 0eb7024..d4f05cf 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -515,8 +515,8 @@ mat GwmLocalCollinearityGWRAlgorithm::regressionOmp(const mat &x, const vec &y) #endif void GwmLocalCollinearityGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - mParallelType = type; - mLCGWRCore->setParallelType(type); + // mParallelType = type; + // mLCGWRCore->setParallelType(type); } bool GwmLocalCollinearityGWRAlgorithm::lambdaAdjust() const diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index a595735..7ec099c 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.cpp +++ b/src/TaskThread/gwmrobustgwralgorithm.cpp @@ -269,7 +269,7 @@ void GwmRobustGWRAlgorithm::createResultLayer(CreateResultLayerData data) void GwmRobustGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - GwmBasicGWRAlgorithm::setParallelType(type); + // GwmBasicGWRAlgorithm::setParallelType(type); } mat GwmRobustGWRAlgorithm::robustGWRCaliFirst(const mat &x, const vec &y, mat &betasSE, vec &shat, vec &qDiag, mat &S) diff --git a/src/gwmgwcorrelationoptionsdialog.cpp b/src/gwmgwcorrelationoptionsdialog.cpp index a6f6872..deca301 100644 --- a/src/gwmgwcorrelationoptionsdialog.cpp +++ b/src/gwmgwcorrelationoptionsdialog.cpp @@ -1,4 +1,4 @@ -#include "gwmgwcorrelationoptionsdialog.h" +#include "gwmgwcorrelationoptionsdialog.h" #include "ui_gwmgwcorrelationoptionsdialog.h" #ifdef ENABLE_OpenMP #include From b211d978fa560c6d3ebb83a8dfd369cc63bc6adc Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Mon, 18 May 2026 15:52:57 +0800 Subject: [PATCH 5/6] 123 --- src/Model/gwmalgorithmmetavariable.cpp | 2 +- src/Model/gwmalgorithmmetavariable.h | 1 + src/TaskThread/gwmgwaveragetaskthread.cpp | 3 + src/gwmgwaverageoptionsdialog.cpp | 40 ++++++++++++- src/gwmgwaverageoptionsdialog.h | 3 + src/gwmgwaverageoptionsdialog.ui | 68 +++++++++++++++++++---- 6 files changed, 103 insertions(+), 14 deletions(-) diff --git a/src/Model/gwmalgorithmmetavariable.cpp b/src/Model/gwmalgorithmmetavariable.cpp index 0aa5bbb..05b20b1 100644 --- a/src/Model/gwmalgorithmmetavariable.cpp +++ b/src/Model/gwmalgorithmmetavariable.cpp @@ -20,7 +20,7 @@ bool GwmAlgorithmMetaVariable::validate(QString &error) const if (weightType == Weight::WeightType::BandwidthWeight) { - if (weightBandwidthSize == 0) + if (!weightBandwidthAutoselect && weightBandwidthSize == 0) { error = QTranslator::tr("Bandwidth size is too small."); return false; diff --git a/src/Model/gwmalgorithmmetavariable.h b/src/Model/gwmalgorithmmetavariable.h index 4b13418..3cf400d 100644 --- a/src/Model/gwmalgorithmmetavariable.h +++ b/src/Model/gwmalgorithmmetavariable.h @@ -14,6 +14,7 @@ struct GwmAlgorithmMetaVariable gwm::Weight::WeightType weightType = gwm::Weight::BandwidthWeight; double weightBandwidthSize = DBL_MAX; bool weightBandwidthAdaptive = true; + bool weightBandwidthAutoselect = false; gwm::BandwidthWeight::KernelFunctionType weightBandwidthKernel = gwm::BandwidthWeight::KernelFunctionType::Gaussian; // Distance gwm::Distance::DistanceType distanceType = gwm::Distance::DistanceType::CRSDistance; diff --git a/src/TaskThread/gwmgwaveragetaskthread.cpp b/src/TaskThread/gwmgwaveragetaskthread.cpp index 2bf54d8..f3b41cb 100644 --- a/src/TaskThread/gwmgwaveragetaskthread.cpp +++ b/src/TaskThread/gwmgwaveragetaskthread.cpp @@ -45,6 +45,7 @@ GwmGWAverageTaskThread::GwmGWAverageTaskThread(const GwmAlgorithmMetaVariable& m } SpatialWeight spatialWeight(&weight, distance); mAlgorithm.setSpatialWeight(spatialWeight); + mAlgorithm.setAutoselectBandwidth(meta.weightBandwidthAutoselect); // Parallel mAlgorithm.setParallelType(meta.parallelType); switch (meta.parallelType) @@ -77,7 +78,9 @@ void GwmGWAverageTaskThread::run() mAlgorithm.setTelegram(make_unique(this)); qDebug() << "core parallelType =" << mAlgorithm.parallelType(); qDebug() << "core parallelAbility =" << mAlgorithm.parallelAbility(); + qDebug() << "core autoselect bandwidth =" << mAlgorithm.isAutoselectBandwidth(); mAlgorithm.run(); + qDebug() << "runfinished"; if(!checkCanceled()) { mResultList.push_back(qMakePair(QString("LM"), localmean())); diff --git a/src/gwmgwaverageoptionsdialog.cpp b/src/gwmgwaverageoptionsdialog.cpp index 974e194..ac47a1f 100644 --- a/src/gwmgwaverageoptionsdialog.cpp +++ b/src/gwmgwaverageoptionsdialog.cpp @@ -37,6 +37,11 @@ GwmGWAverageOptionsDialog::GwmGWAverageOptionsDialog(QList o connect(ui->mBwTypeFixedRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::onFixedRadioToggled); connect(ui->mBwTypeAdaptiveRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::onVariableRadioToggled); + QButtonGroup* bwSelectionBtnGroup = new QButtonGroup(this); + bwSelectionBtnGroup->addButton(ui->mBwSizeAutomaticRadio); + bwSelectionBtnGroup->addButton(ui->mBwSizeCustomizeRadio); + connect(ui->mBwSizeAutomaticRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::onAutomaticRadioToggled); + connect(ui->mBwSizeCustomizeRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::onCustomizeRadioToggled); //距离计算部分 QButtonGroup* distanceSettingBtnGroup = new QButtonGroup(this); @@ -70,6 +75,8 @@ GwmGWAverageOptionsDialog::GwmGWAverageOptionsDialog(QList o connect(ui->mIndepVarSelector, &GwmIndepVarSelectorWidget::selectedIndepVarChangedSignal, this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); connect(ui->mBwTypeFixedRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); connect(ui->mBwTypeAdaptiveRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); + connect(ui->mBwSizeAutomaticRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); + connect(ui->mBwSizeCustomizeRadio, &QAbstractButton::toggled, this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); connect(ui->mBwSizeFixedSize, static_cast(&QDoubleSpinBox::valueChanged), this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); connect(ui->mBwSizeFixedUnit, static_cast(&QComboBox::currentIndexChanged), this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); connect(ui->mBwSizeAdaptiveSize, static_cast(&QSpinBox::valueChanged), this, &GwmGWAverageOptionsDialog::updateFieldsAndEnable); @@ -91,6 +98,9 @@ GwmGWAverageOptionsDialog::GwmGWAverageOptionsDialog(QList o ui->mBwSizeAdaptiveSize->setMaximum(INT_MAX); ui->mBwSizeFixedSize->setMaximum(DBL_MAX); + ui->mBwTypeAdaptiveRadio->setChecked(true); + ui->mBwSizeAutomaticRadio->setChecked(true); + onAutomaticRadioToggled(ui->mBwSizeAutomaticRadio->isChecked()); ui->mDistTypeCRSRadio->setChecked(true); updateFieldsAndEnable(); } @@ -257,6 +267,33 @@ void GwmGWAverageOptionsDialog::onVariableRadioToggled(bool checked) ui->mBwSizeSettingStack->setCurrentIndex(0); } +void GwmGWAverageOptionsDialog::onAutomaticRadioToggled(bool checked) +{ + if (checked) + { + ui->mBwSizeAdaptiveSize->setEnabled(false); + ui->mBwSizeAdaptiveUnit->setEnabled(false); + ui->mBwSizeFixedSize->setEnabled(false); + ui->mBwSizeFixedUnit->setEnabled(false); + } +} + +void GwmGWAverageOptionsDialog::onCustomizeRadioToggled(bool checked) +{ + if (checked) + { + ui->mBwSizeAdaptiveSize->setEnabled(true); + ui->mBwSizeAdaptiveUnit->setEnabled(true); + ui->mBwSizeFixedSize->setEnabled(true); + ui->mBwSizeFixedUnit->setEnabled(true); + } +} + +bool GwmGWAverageOptionsDialog::bandwidthAutoSelect() +{ + return ui->mBwSizeAutomaticRadio->isChecked(); +} + double GwmGWAverageOptionsDialog::bandwidthSize(){ if (ui->mBwTypeAdaptiveRadio->isChecked()) { @@ -324,8 +361,9 @@ void GwmGWAverageOptionsDialog::updateFields() } mAlgorithmMeta.weightType = gwm::Weight::BandwidthWeight; - mAlgorithmMeta.weightBandwidthSize = bandwidthSize(); + mAlgorithmMeta.weightBandwidthSize = bandwidthAutoSelect() ? 1.0 : bandwidthSize(); mAlgorithmMeta.weightBandwidthAdaptive = bandwidthType(); + mAlgorithmMeta.weightBandwidthAutoselect = bandwidthAutoSelect(); mAlgorithmMeta.weightBandwidthKernel = bandwidthKernelFunction(); diff --git a/src/gwmgwaverageoptionsdialog.h b/src/gwmgwaverageoptionsdialog.h index fb9ceff..153d09f 100644 --- a/src/gwmgwaverageoptionsdialog.h +++ b/src/gwmgwaverageoptionsdialog.h @@ -38,6 +38,8 @@ public slots: void onFixedRadioToggled(bool checked); void onVariableRadioToggled(bool checked); + void onAutomaticRadioToggled(bool checked); + void onCustomizeRadioToggled(bool checked); void onNoneRadioToggled(bool checked); void onMultithreadingRadioToggled(bool checked); void onGPURadioToggled(bool checked); @@ -52,6 +54,7 @@ public slots: QString crsRotateTheta(); QString crsRotateP(); bool bandwidthType(); + bool bandwidthAutoSelect(); IParallelalbe::ParallelType approachType(); double bandwidthSize(); gwm::BandwidthWeight::KernelFunctionType bandwidthKernelFunction(); diff --git a/src/gwmgwaverageoptionsdialog.ui b/src/gwmgwaverageoptionsdialog.ui index 41a9d56..7032322 100644 --- a/src/gwmgwaverageoptionsdialog.ui +++ b/src/gwmgwaverageoptionsdialog.ui @@ -27,8 +27,8 @@ 0 0 - 600 - 650 + 644 + 778 @@ -144,7 +144,58 @@ + + + + Bandwidth Selection + + + + + + 6 + + + + + Automatic + + + true + + + + + + + Customize + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Bandwidth Size + + + + 0 @@ -252,14 +303,14 @@ - + Kernel Function - + @@ -288,13 +339,6 @@ - - - - Bandwidth Size - - - @@ -705,4 +749,4 @@ - \ No newline at end of file + From 7091f5b7b5d90e87d8cf20926e0023a71b274e5c Mon Sep 17 00:00:00 2001 From: szh <2659007320@qq.com> Date: Thu, 21 May 2026 14:43:23 +0800 Subject: [PATCH 6/6] anova --- src/Model/gwmlayergwaverageitem.cpp | 11 ++++++- .../gwmpropertygwaveragetab.cpp | 6 ++++ src/TaskThread/gwmgwaveragetaskthread.cpp | 32 +++++++++++++++++++ src/TaskThread/gwmgwaveragetaskthread.h | 5 ++- .../gwmlocalcollinearitygwralgorithm.cpp | 17 ++++++++-- .../gwmlocalcollinearitygwralgorithm.h | 12 +++++-- 6 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/Model/gwmlayergwaverageitem.cpp b/src/Model/gwmlayergwaverageitem.cpp index 1a6461e..72b7ed6 100644 --- a/src/Model/gwmlayergwaverageitem.cpp +++ b/src/Model/gwmlayergwaverageitem.cpp @@ -9,7 +9,16 @@ GwmLayerGWAverageItem::GwmLayerGWAverageItem(GwmLayerItem* parentItem, QgsVector auto taskMeta = taskThread->meta(); mDataPointsSize = taskMeta.layer->featureCount(); mVariables = taskMeta.variables; - mBandwidth = new gwm::BandwidthWeight(taskMeta.weightBandwidthSize, taskMeta.weightBandwidthAdaptive, gwm::BandwidthWeight::KernelFunctionType(taskMeta.weightBandwidthKernel)); + // Use final bandwidth from taskThread (may be updated by autoselect), fallback to meta + gwm::BandwidthWeight finalBw = taskThread->finalBandwidth(); + if (finalBw.bandwidth() != 0.0 || finalBw.adaptive()) + { + mBandwidth = new gwm::BandwidthWeight(finalBw); + } + else + { + mBandwidth = new gwm::BandwidthWeight(taskMeta.weightBandwidthSize, taskMeta.weightBandwidthAdaptive, gwm::BandwidthWeight::KernelFunctionType(taskMeta.weightBandwidthKernel)); + } mQuantile = taskThread->quantile(); mResultList = taskThread->resultlist(); diff --git a/src/PropertyPanelTabs/gwmpropertygwaveragetab.cpp b/src/PropertyPanelTabs/gwmpropertygwaveragetab.cpp index 28d624a..00e1304 100644 --- a/src/PropertyPanelTabs/gwmpropertygwaveragetab.cpp +++ b/src/PropertyPanelTabs/gwmpropertygwaveragetab.cpp @@ -53,6 +53,12 @@ void GwmPropertyGWAverageTab::updateUI() QString bwSizeString = QString("%1 (number of nearest neighbours)").arg(int(weight.bandwidth())); ui->lblBandwidthSize->setText(bwSizeString); } + else + { + // for fixed bandwidth show distance value + QString bwSizeString = QString("%1 (distance)").arg(weight.bandwidth(), 0, 'f', 3); + ui->lblBandwidthSize->setText(bwSizeString); + } ui->lblNumberDataPoints->setText(QString("%1").arg(mLayerItem->dataPointsSize())); if (true) { diff --git a/src/TaskThread/gwmgwaveragetaskthread.cpp b/src/TaskThread/gwmgwaveragetaskthread.cpp index f3b41cb..15a7ad1 100644 --- a/src/TaskThread/gwmgwaveragetaskthread.cpp +++ b/src/TaskThread/gwmgwaveragetaskthread.cpp @@ -46,6 +46,10 @@ GwmGWAverageTaskThread::GwmGWAverageTaskThread(const GwmAlgorithmMetaVariable& m SpatialWeight spatialWeight(&weight, distance); mAlgorithm.setSpatialWeight(spatialWeight); mAlgorithm.setAutoselectBandwidth(meta.weightBandwidthAutoselect); + qDebug() << "GWAverageTaskThread configured: autoselectBandwidth=" << mAlgorithm.isAutoselectBandwidth() + << ", initial bandwidth=" << weight.bandwidth() + << ", adaptive=" << weight.adaptive() + << ", kernel=" << (int)weight.kernel(); // Parallel mAlgorithm.setParallelType(meta.parallelType); switch (meta.parallelType) @@ -61,6 +65,14 @@ GwmGWAverageTaskThread::GwmGWAverageTaskThread(const GwmAlgorithmMetaVariable& m delete distance; } +gwm::BandwidthWeight GwmGWAverageTaskThread::finalBandwidth() const +{ + auto bw = mAlgorithm.spatialWeight().weight(); + if (bw) + return *bw; + return gwm::BandwidthWeight(); +} + void GwmGWAverageTaskThread::run() { emit tick(0, 0); @@ -79,8 +91,28 @@ void GwmGWAverageTaskThread::run() qDebug() << "core parallelType =" << mAlgorithm.parallelType(); qDebug() << "core parallelAbility =" << mAlgorithm.parallelAbility(); qDebug() << "core autoselect bandwidth =" << mAlgorithm.isAutoselectBandwidth(); + if (mAlgorithm.isAutoselectBandwidth()) + { + auto bw = mAlgorithm.spatialWeight().weight(); + if (bw) + { + qDebug() << "core bandwidth before run =" << bw->bandwidth() + << ", adaptive =" << bw->adaptive() + << ", kernel =" << (int)bw->kernel(); + } + } mAlgorithm.run(); qDebug() << "runfinished"; + if (mAlgorithm.isAutoselectBandwidth()) + { + auto bw = mAlgorithm.spatialWeight().weight(); + if (bw) + { + qDebug() << "core bandwidth after run =" << bw->bandwidth() + << ", adaptive =" << bw->adaptive() + << ", kernel =" << (int)bw->kernel(); + } + } if(!checkCanceled()) { mResultList.push_back(qMakePair(QString("LM"), localmean())); diff --git a/src/TaskThread/gwmgwaveragetaskthread.h b/src/TaskThread/gwmgwaveragetaskthread.h index bde7314..9c51652 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 @@ -74,6 +74,9 @@ class GwmGWAverageTaskThread : public GwmSpatialMonoscaleAlgorithm, public IGwmM QList mVariables; CreateResultLayerData mResultList; +public: + gwm::BandwidthWeight finalBandwidth() const; + public: static int treeChildCount; diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index d4f05cf..7d83f18 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -43,6 +43,16 @@ void GwmLocalCollinearityGWRAlgorithm::setCanceled(bool canceled) return GwmTaskThread::setCanceled(canceled); } +void GwmLocalCollinearityGWRAlgorithm::setGPUId(const int gpuId) +{ + mGpuId = gpuId; +} + +void GwmLocalCollinearityGWRAlgorithm::setGroupSize(const std::size_t size) +{ + mGroupSize = static_cast(size); +} + void GwmLocalCollinearityGWRAlgorithm::run() { if(!checkCanceled()) @@ -515,8 +525,11 @@ mat GwmLocalCollinearityGWRAlgorithm::regressionOmp(const mat &x, const vec &y) #endif void GwmLocalCollinearityGWRAlgorithm::setParallelType(const gwm::ParallelType &type) { - // mParallelType = type; - // mLCGWRCore->setParallelType(type); + if (mLCGWRCore && (type & mLCGWRCore->parallelAbility())) + { + mParallelType = type; + mLCGWRCore->setParallelType(type); + } } bool GwmLocalCollinearityGWRAlgorithm::lambdaAdjust() const diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h index 1e31761..cc25739 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h @@ -11,7 +11,7 @@ using namespace arma; -class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public IIndependentVariableSelectable, public gwm::IParallelizable, public gwm::IParallelOpenmpEnabled, public gwm::IParallelCudaEnabled +class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, public gwm::IParallelizable, public gwm::IParallelOpenmpEnabled, public gwm::IParallelCudaEnabled { public: @@ -100,6 +100,10 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA public: void setOmpThreadNum(const int threadNum) override; + // IParallelCudaEnabled interface + void setGPUId(const int gpuId) override; + void setGroupSize(const std::size_t size) override; + void setCanceled(bool canceled) override; private: double mLambda; @@ -146,7 +150,7 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA inline int GwmLocalCollinearityGWRAlgorithm::parallelAbility() const { - return gwm::SerialOnly | gwm::OpenMP; + return mLCGWRCore ? mLCGWRCore->parallelAbility() : (gwm::SerialOnly | gwm::OpenMP); } inline gwm::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const @@ -157,6 +161,10 @@ inline gwm::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const inline void GwmLocalCollinearityGWRAlgorithm::setOmpThreadNum(const int threadNum) { mOmpThreadNum = threadNum; + if (mLCGWRCore) + { + mLCGWRCore->setOmpThreadNum(threadNum); + } } #endif // GWMLCRGWRTASKTHREAD_H