diff --git a/src/Model/gwmlayerbasicgwritem.cpp b/src/Model/gwmlayerbasicgwritem.cpp index 50900af..f8f7f9a 100644 --- a/src/Model/gwmlayerbasicgwritem.cpp +++ b/src/Model/gwmlayerbasicgwritem.cpp @@ -10,7 +10,7 @@ GwmLayerBasicGWRItem::GwmLayerBasicGWRItem(GwmLayerItem* parent, QgsVectorLayer* mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(taskThread->spatialWeight().weight()); mDiagnostic = taskThread->diagnostic(); mDiagnostic0 = taskThread->diagnostic0(); mBetas = mat(taskThread->betas()); diff --git a/src/Model/gwmlayercollinearitygwritem.cpp b/src/Model/gwmlayercollinearitygwritem.cpp index 6d82ef2..63d2e4d 100644 --- a/src/Model/gwmlayercollinearitygwritem.cpp +++ b/src/Model/gwmlayercollinearitygwritem.cpp @@ -9,7 +9,7 @@ GwmLayerCollinearityGWRItem::GwmLayerCollinearityGWRItem(GwmLayerItem* parent, Q mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(taskThread->spatialWeight().weight()); mDiagnostic = taskThread->dialnostic(); mDiagnostic0 = taskThread->diagnostic0(); mBetas = mat(taskThread->betas()); diff --git a/src/Model/gwmlayerggwritem.cpp b/src/Model/gwmlayerggwritem.cpp index 04bd4ce..5be4a9a 100644 --- a/src/Model/gwmlayerggwritem.cpp +++ b/src/Model/gwmlayerggwritem.cpp @@ -8,7 +8,7 @@ GwmLayerGGWRItem::GwmLayerGGWRItem(GwmLayerItem* parent, QgsVectorLayer* vector, mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(taskThread->spatialWeight().weight()); mBetas = mat(taskThread->betas()); isBandwidthOptimized = taskThread->autoselectBandwidth(); mBandwidthSelScores = taskThread->bandwidthSelectorCriterions(); diff --git a/src/Model/gwmlayergtdritem.cpp b/src/Model/gwmlayergtdritem.cpp index 468a94e..5bcb4a9 100644 --- a/src/Model/gwmlayergtdritem.cpp +++ b/src/Model/gwmlayergtdritem.cpp @@ -42,13 +42,14 @@ GwmLayerGTDRItem::GwmLayerGTDRItem(GwmLayerItem* parentItem, QgsVectorLayer* vec // update mBandwidth if (!sws.empty()) { - auto* optimizedBw = sws[0].weight(); - if (optimizedBw) + const auto& coreW = sws[0].weight(); + if (coreW) { + auto& optimizedBw = sws[0].weight(); // 更新为优化后的带宽值 - mBandwidth->setBandwidth(optimizedBw->bandwidth()); - mBandwidth->setAdaptive(optimizedBw->adaptive()); - mBandwidth->setKernel(static_cast(optimizedBw->kernel())); + mBandwidth->setBandwidth(optimizedBw.bandwidth()); + mBandwidth->setAdaptive(optimizedBw.adaptive()); + mBandwidth->setKernel(static_cast(optimizedBw.kernel())); isBandwidthOptimized = true; } } @@ -57,14 +58,15 @@ GwmLayerGTDRItem::GwmLayerGTDRItem(GwmLayerItem* parentItem, QgsVectorLayer* vec mBandwidths.reserve(sws.size()); for(int i = 0; i < sws.size(); ++i){ // 从 taskMeta 获取初始值,或从优化后的 spatialWeight 获取 - auto* libBw = sws[i].weight(); - if (libBw) + const auto& coreW = sws[i].weight(); + if (coreW) { + auto& libBw = sws[i].weight(); // 创建应用层的带宽权重对象 auto* appBw = new GwmBandwidthWeight( - libBw->bandwidth(), - libBw->adaptive(), - static_cast(libBw->kernel()) + libBw.bandwidth(), + libBw.adaptive(), + static_cast(libBw.kernel()) ); mBandwidths.append(appBw); } diff --git a/src/Model/gwmlayergwpcaitem.cpp b/src/Model/gwmlayergwpcaitem.cpp index 80779e2..9f836cd 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 @@ -16,14 +16,15 @@ GwmLayerGWPCAItem::GwmLayerGWPCAItem(GwmLayerItem* parent, QgsVectorLayer* vecto mK = taskThread->k(); gwm::SpatialWeight sw = taskThread->spatialWeight(); - gwm::BandwidthWeight* gwmBw = sw.weight(); - if (gwmBw) + const auto& coreW = sw.weight(); + if (coreW) { - if(gwmBw->bandwidth() == 0) + gwm::BandwidthWeight& gwmBw = sw.weight(); + if(gwmBw.bandwidth() == 0) { qDebug() << "[GwmLayerGWPCAItem] WARNING: Bandwidth is 0! This will cause display issues in property panel."; } - mWeight = gwm::BandwidthWeight(*gwmBw); + mWeight = gwm::BandwidthWeight(gwmBw); } else { diff --git a/src/Model/gwmlayerscalablegwritem.cpp b/src/Model/gwmlayerscalablegwritem.cpp index 3548952..182e70d 100644 --- a/src/Model/gwmlayerscalablegwritem.cpp +++ b/src/Model/gwmlayerscalablegwritem.cpp @@ -8,7 +8,7 @@ GwmLayerScalableGWRItem::GwmLayerScalableGWRItem(GwmLayerItem* parent, QgsVector mDataPointsSize = taskThread->dataLayer()->featureCount(); mDepVar = taskThread->dependentVariable(); mIndepVars = taskThread->independentVariables(); - mWeight = gwm::BandwidthWeight(*static_cast(taskThread->spatialWeight().weight())); + mWeight = gwm::BandwidthWeight(taskThread->spatialWeight().weight()); mDistanceType = taskThread->spatialWeight().distance()->type(); mDiagnostic = taskThread->diagnostic(); mDiagnostic0 = taskThread->diagnostic0(); diff --git a/src/TaskThread/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 54217f9..104acfe 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -143,10 +143,10 @@ void GwmBasicGWRAlgorithm::run() mGWRCore->setTelegram(std::make_unique(this)); mBetas = mGWRCore->fit(); - gwm::BandwidthWeight* bw = mGWRCore->spatialWeight().weight(); + const auto& bw = mGWRCore->spatialWeight().weight(); if (bw && !checkCanceled()) { - mSpatialWeight.setWeight(bw); + mSpatialWeight.setWeight(mGWRCore->spatialWeight().weight()); criterionList = mGWRCore->bandwidthSelectionCriterionList(); QVector> qlist; @@ -301,7 +301,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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::DMatDistance; if (hasDmat) { for (arma::uword r = 0; r < nRp; r++) @@ -419,25 +419,25 @@ double GwmBasicGWRAlgorithm::indepVarsSelectCriterionCuda(const QListtype() == gwm::Distance::DMatDistance; + bool hasDp = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool gwrStatus = cuda->Regression(true, p, theta, longlat, DBL_MAX, bw->kernel(), bw->adaptive(), mGroupSize, mGpuId); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool gwrStatus = cuda->Regression(true, p, theta, longlat, DBL_MAX, bw.kernel(), bw.adaptive(), mGroupSize, mGpuId); mat betas(nVar, nDp, fill::zeros); vec shat(2, fill::zeros); double value = DBL_MAX; @@ -526,27 +526,27 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } int groupSize = mGroupSize; int gpuID = mGpuId; - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); - bool gwrStatus = cuda->Regression(false, p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, groupSize, gpuID); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); + bool gwrStatus = cuda->Regression(false, p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, groupSize, gpuID); mat betas(nVar, nRp, fill::zeros); if (gwrStatus) { @@ -656,25 +656,25 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); - bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, mGroupSize, mGpuId); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); + bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, mGroupSize, mGpuId); mat betas(nVar, nDp, fill::zeros); betasSE = mat(nVar, nDp, fill::zeros); shat = vec(2, fill::zeros); @@ -829,7 +829,7 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp(GwmBandwidthWeight *ba mat betas(nVar, nDp, fill::zeros); mat shat_all(2, mOmpThreadNum, fill::zeros); bool flag = true; - int current = 0; + // int current = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < nDp; i++) { @@ -854,9 +854,11 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionAICOmp(GwmBandwidthWeight *ba { flag = false; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); - current++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + if (i % std::max(1, nDp / 10) == 0) + emit tick(i * 100 / nDp, 100); + // current++; } } if (flag && !checkCanceled()) @@ -882,25 +884,25 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); - bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, mGroupSize, mGpuId); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); + bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, mGroupSize, mGpuId); mat betas(nVar, nDp, fill::zeros); vec shat(2, fill::zeros); double aic = DBL_MAX; @@ -979,7 +981,7 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *ban vec shat(2, fill::zeros); vec cv_all(mOmpThreadNum, fill::zeros); bool flag = true; - int current = 0; + // int current = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < nDp ; i++) { @@ -1006,9 +1008,11 @@ double GwmBasicGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *ban { flag = false; } - if(mBandwidthSizeSelector.counter<10) - emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); - current++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current * 10 / nDp, 100); + if (i % std::max(1, nDp / 10) == 0) + emit tick(i * 100 / nDp, 100); + // current++; } } if (flag && !checkCanceled()) @@ -1029,21 +1033,21 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } bool adaptive = bandwidthWeight->adaptive(); double cv = DBL_MAX; @@ -1272,25 +1276,25 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); - double trQtQ = cuda->CalcTrQtQ(p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, mGroupSize, mGpuId); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); + double trQtQ = cuda->CalcTrQtQ(p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, mGroupSize, mGpuId); GWCUDA_Del(cuda); return trQtQ; } @@ -1384,26 +1388,26 @@ 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() == gwm::Distance::DMatDistance; + bool hasDmat = mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::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() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); vec diagB(2, fill::zeros); - bool status = cuda->CalcB(i, p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, mGroupSize, mGpuId); + bool status = cuda->CalcB(i, p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, mGroupSize, mGpuId); if (status) { diagB = { cuda->GetTrB(), cuda->GetTrBdB() }; @@ -1426,8 +1430,8 @@ bool GwmBasicGWRAlgorithm::isValid() if (!mIsAutoselectBandwidth) { - gwm::BandwidthWeight* bw = mSpatialWeight.weight(); - if (bw->adaptive() && bw->bandwidth() <= mIndepVars.size()) + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + if (bw.adaptive() && bw.bandwidth() <= static_cast(mIndepVars.size())) return false; } return true; @@ -1441,23 +1445,17 @@ void GwmBasicGWRAlgorithm::initPoints() if (!hasRegressionLayer() && !mHasHatMatrix) { mRegressionPoints = mDataPoints; - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - auto *d = mSpatialWeight.distance(); - if (d) - { - d->makeParameter({ mRegressionPoints, mDataPoints }); - } + auto &d = mSpatialWeight.distance(); + d.makeParameter({ mRegressionPoints, mDataPoints }); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - auto *d2 = mSpatialWeight.distance(); - if (d2) - { - d2->makeParameter({ mRegressionPoints, mDataPoints }); - } + auto &d2 = mSpatialWeight.distance(); + d2.makeParameter({ mRegressionPoints, mDataPoints }); } } } diff --git a/src/TaskThread/gwmbasicgwralgorithm.h b/src/TaskThread/gwmbasicgwralgorithm.h index 2e23c71..02e9e7e 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.h +++ b/src/TaskThread/gwmbasicgwralgorithm.h @@ -165,7 +165,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, rowvec distanceParam1(int i) { - return (mSpatialWeight.distance()->type() == gwm::Distance::DMatDistance ? vec(1).fill(i) : mDataPoints.row(i)); + return (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::DMatDistance ? vec(1).fill(i) : mDataPoints.row(i)); } protected: void OLS(); @@ -248,7 +248,7 @@ class GwmBasicGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgorithm, vec mRegressionLayerY; mat mRegressionLayerX; - gwm::BandwidthSelector mBandwidthSizeSelector; + //gwm::BandwidthSelector mBandwidthSizeSelector; gwm::BandwidthCriterionList criterionList; bool mIsAutoselectBandwidth = false; gwm::GWRBasic::BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = gwm::GWRBasic::BandwidthSelectionCriterionType::AIC; diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index a281f0e..c002b1d 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -106,13 +106,15 @@ void GwmGeneralizedGWRAlgorithm::run() // mBetas = mGGWRCore->fit(); // } - gwm::BandwidthWeight* bw = mGGWRCore->spatialWeight().weight(); - emit message(tr("bandwidth selected: %1").arg(bw->bandwidth())); - if (bw && !checkCanceled()) + const auto &coreW = mGGWRCore->spatialWeight().weight(); + if (coreW && !checkCanceled()) { + gwm::BandwidthWeight& bw = mGGWRCore->spatialWeight().weight(); + emit message(tr("bandwidth selected: %1").arg(bw.bandwidth())); + mSpatialWeight.setWeight(bw); - criterionList = mGGWRCore->mBandwidthSelectionCriterionList; + criterionList = mGGWRCore->bandwidthSelectorCriterions(); // 绘图数据 QVector> qlist; @@ -139,7 +141,7 @@ void GwmGeneralizedGWRAlgorithm::run() // { // emit message(QString(tr("Automatically selecting bandwidth ..."))); // //emit tick(0, 0); - // if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) + // if ((mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) && !checkCanceled()) // { // gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); // d->makeParameter({ mDataPoints, mDataPoints }); @@ -162,7 +164,7 @@ void GwmGeneralizedGWRAlgorithm::run() // QVariant data = QVariant::fromValue(mBandwidthSizeSelector.bandwidthCriterion()); // emit plot(data, &GwmBandwidthSizeSelector::PlotBandwidthResult); // } - // if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) + // if ((mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) && !checkCanceled()) // { // gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); // d->makeParameter({ mDataPoints, mDataPoints }); @@ -194,7 +196,7 @@ void GwmGeneralizedGWRAlgorithm::run() // mWtMat2.col(i) = weight; // emit tick(i, nRp); // } - // if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) + // if ((mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) && !checkCanceled()) // { // gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); // d->makeParameter({ mDataPoints, mDataPoints }); @@ -828,7 +830,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVOmp(GwmBandwidthW int n = mDataPoints.n_rows; vec cv = vec(n); mat wt = mat(n,n); - int current1 = 0, current2 = 0; + // int current1 = 0, current2 = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -838,9 +840,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 + current1 * 5 / n, 100); + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); + // current1++; } } if (!checkCanceled()) (this->*mCalWtFunction)(mX,mY,wt); @@ -857,9 +861,11 @@ 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); - current2++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); + // current2++; } } vec cvsquare = trans(cv) * cv ; @@ -934,7 +940,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionAICOmp(GwmBandwidth vec cv = vec(n); mat S = mat(n,n); mat wt = mat(n,n); - int current1 = 0, current2 = 0; + // int current1 = 0, current2 = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -943,9 +949,11 @@ 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); - current1++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current1 * 5 / n, 100); + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); + // current1++; } } if (!checkCanceled()) (this->*mCalWtFunction)(mX,mY,wt); @@ -959,9 +967,11 @@ 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); - current2++; + // if(mBandwidthSizeSelector.counter<10) + // emit tick(mBandwidthSizeSelector.counter*10 + current2 * 5 / n + 5, 100); + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); + // current2++; } } double AICc; diff --git a/src/TaskThread/gwmgeneralizedgwralgorithm.h b/src/TaskThread/gwmgeneralizedgwralgorithm.h index b154e8a..40ba91a 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.h +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.h @@ -120,7 +120,10 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor public: double criterionLib(gwm::BandwidthWeight* bandwidthWeight){ double criterionValue = 0.0; - mGGWRCore->getCriterion(bandwidthWeight, criterionValue); + auto cloned = bandwidthWeight->clone(); + std::unique_ptr bw( + static_cast(cloned.release())); + mGGWRCore->getCriterion(bw, criterionValue); return criterionValue; } @@ -266,7 +269,7 @@ class GwmGeneralizedGWRAlgorithm : public GwmGeographicalWeightedRegressionAlgor bool mIsAutoselectBandwidth = false; BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::AIC; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial; - gwm::BandwidthSelector mBandwidthSizeSelector; + //gwm::BandwidthSelector mBandwidthSizeSelector; gwm::ParallelType mParallelType = gwm::ParallelType::SerialOnly; int mOmpThreadNum = 8; diff --git a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp index 4cc63d1..4c52e3e 100644 --- a/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp +++ b/src/TaskThread/gwmgeographicalweightedregressionalgorithm.cpp @@ -49,23 +49,17 @@ void GwmGeographicalWeightedRegressionAlgorithm::initPoints() } else mRegressionPoints = mDataPoints; // 设置空间距离中的数据指针 - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - auto *d = mSpatialWeight.distance(); - if (d) - { - d->makeParameter({ mRegressionPoints, mDataPoints }); - } + auto &d = mSpatialWeight.distance(); + d.makeParameter({ mRegressionPoints, mDataPoints }); } - else if (mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - auto *d2 = mSpatialWeight.distance(); - if (d2) - { - d2->makeParameter({ mRegressionPoints, mDataPoints }); - } + auto &d2 = mSpatialWeight.distance(); + d2.makeParameter({ mRegressionPoints, mDataPoints }); } } diff --git a/src/TaskThread/gwmgtdrtaskthread.cpp b/src/TaskThread/gwmgtdrtaskthread.cpp index c5087e0..b23b2ff 100644 --- a/src/TaskThread/gwmgtdrtaskthread.cpp +++ b/src/TaskThread/gwmgtdrtaskthread.cpp @@ -2,6 +2,7 @@ #include #include #include "SpatialWeight/gwmcrsdistance.h" +#include #ifdef ENABLE_OpenMP #include #endif @@ -262,14 +263,16 @@ void GwmGTDRTaskThread::run() int nWeightingVars = mMeta.weightingVariables.size(); for (arma::uword k = 0; k < nWeightingVars && k < mWeightingData.n_cols; ++k) { - auto* od = sws[k].distance(); - if (!od) { - emit error(tr("GTDR invalid: spatialWeights[%1] is not OneDimDistance.").arg(int(k))); + const auto &distH = sws[k].distance(); + if (!distH) + { + emit error(tr("GTDR invalid: spatialWeights[%1] has null distance.").arg(int(k))); return; } + auto &od = sws[k].distance(); // 使用权重变量的第k列来设置距离参数 arma::vec col = mWeightingData.col(k); - od->makeParameter({ col, col }); + od.makeParameter({ col, col }); emit message(tr("Distance parameter set for weighting variable: %1") .arg(mMeta.weightingVariables[k].name)); } @@ -278,13 +281,15 @@ void GwmGTDRTaskThread::run() if (hasTimeStamp && sws.size() > nWeightingVars && mWeightingData.n_cols > nWeightingVars) { arma::uword timeStampIndex = nWeightingVars; - auto* od = sws[timeStampIndex].distance(); - if (!od) { - emit error(tr("GTDR invalid: spatialWeights[%1] (timestamp) is not OneDimDistance.").arg(int(timeStampIndex))); + const auto &distH = sws[timeStampIndex].distance(); + if (!distH) + { + emit error(tr("GTDR invalid: spatialWeights[%1] (timestamp) has null distance.").arg(int(timeStampIndex))); return; } + auto &od = sws[timeStampIndex].distance(); arma::vec col = mWeightingData.col(timeStampIndex); - od->makeParameter({ col, col }); + od.makeParameter({ col, col }); emit message(tr("Distance parameter set for timestamp variable: %1") .arg(mMeta.timeStampVariable.name)); } @@ -295,28 +300,30 @@ void GwmGTDRTaskThread::run() { // Bandwidth size selection emit message(tr("Automatically selecting bandwidth...")); - vector vecBandwidthWeight0 ; + // vector vecBandwidthWeight0 ; mAlgorithm.setBandwidthCriterionType(mMeta.bandwidthCriterionType); // 4. 收集所有维度的带宽权重指针 - std::vector bandwidths; + // std::vector bandwidths; + std::vector> bandwidths; const auto& sws = mAlgorithm.spatialWeights(); for (const auto& sw : sws) { - auto* bw = sw.weight(); - if (bw) + const auto &wH = sw.weight(); + if (wH) { + gwm::BandwidthWeight &bw = sw.weight(); bandwidths.push_back(bw); // 设置初始带宽值(如果当前值不合理) - double lower = bw->adaptive() ? (mIndepVars.size() + 1) : 0.0; - double upper = bw->adaptive() ? mX.n_rows : sw.distance()->maxDistance(); - if (bw->bandwidth() <= lower || bw->bandwidth() >= upper || !isfinite(bw->bandwidth())) + double lower = bw.adaptive() ? (mIndepVars.size() + 1) : 0.0; + double upper = bw.adaptive() ? mX.n_rows : sw.distance()->maxDistance(); + if (bw.bandwidth() <= lower || bw.bandwidth() >= upper || !isfinite(bw.bandwidth())) { - double initBw = bw->adaptive() + double initBw = bw.adaptive() ? std::max(20.0, upper * 0.618) : upper * 0.618; - bw->setBandwidth(initBw); + bw.setBandwidth(initBw); } } } @@ -362,15 +369,16 @@ void GwmGTDRTaskThread::run() const auto& sws = mAlgorithm.spatialWeights(); for (size_t i = 0; i < sws.size(); ++i) { - auto* bw = sws[i].weight(); - if (bw) + const auto &wHi = sws[i].weight(); + if (wHi) { + auto& bw = sws[i].weight(); QString varName = i < mMeta.weightingVariables.size() ? mMeta.weightingVariables[i].name : QString("Dimension_%1").arg(i); emit message(tr("Dimension %1 (%2): optimized bandwidth = %3") - .arg(i).arg(varName).arg(bw->bandwidth())); + .arg(i).arg(varName).arg(bw.bandwidth())); } } } @@ -381,25 +389,26 @@ void GwmGTDRTaskThread::run() const auto& sws = mAlgorithm.spatialWeights(); for (size_t i = 0; i < sws.size(); ++i) { - auto* bw = sws[i].weight(); - if (bw) + const auto &wHi = sws[i].weight(); + if (wHi) { + auto& bw = sws[i].weight(); //bw->setBandwidth(100);// 继续使用初始带宽值(这里需要实时更新) // 直接使用 bandwidths 中的当前值(优化器最后一次尝试的值) - double currentBw = bandwidths[i]->bandwidth(); + double currentBw = bandwidths[i].get().bandwidth(); // 验证值的有效性 - double lower = bw->adaptive() ? (mMeta.weightingVariables.size() + 1) : 0.0; - double upper = bw->adaptive() ? mX.n_rows : sws[i].distance()->maxDistance(); + double lower = bw.adaptive() ? (mMeta.weightingVariables.size() + 1) : 0.0; + double upper = bw.adaptive() ? mX.n_rows : sws[i].distance()->maxDistance(); if (currentBw <= lower || currentBw >= upper || !isfinite(currentBw)) { // 如果值无效,使用合理的默认值 - currentBw = bw->adaptive() + currentBw = bw.adaptive() ? std::round(std::max(20.0, upper * 0.618)) : upper * 0.618; - bw->setBandwidth(currentBw); + bw.setBandwidth(currentBw); } // 如果值有效,不需要设置(已经是当前值) @@ -408,7 +417,7 @@ void GwmGTDRTaskThread::run() : QString("Dimension_%1").arg(i); emit message(tr("Dimension %1 (%2): using initial bandwidth: %3 (optimization failed)") - .arg(i).arg(varName).arg(bw->bandwidth())); + .arg(i).arg(varName).arg(bw.bandwidth())); } } } diff --git a/src/TaskThread/gwmgtdrtaskthread.h b/src/TaskThread/gwmgtdrtaskthread.h index f5404d9..0fed0a7 100644 --- a/src/TaskThread/gwmgtdrtaskthread.h +++ b/src/TaskThread/gwmgtdrtaskthread.h @@ -107,7 +107,7 @@ class GwmGTDRTaskThread : public GwmSpatialAlgorithm, public IOpenmpParallelable std::vector> mBandwidthHolders; std::vector> mDistanceHolders; - gwm::BandwidthSelector mBandwidthSizeSelector; + //gwm::BandwidthSelector mBandwidthSizeSelector; //gwm::GTDRBandwidthOptimizer mGTDRBandwidthOptimizer; int mCurrentOptimizingDim = -1; diff --git a/src/TaskThread/gwmgtwralgorithm.cpp b/src/TaskThread/gwmgtwralgorithm.cpp index 2633ada..c5a25d8 100644 --- a/src/TaskThread/gwmgtwralgorithm.cpp +++ b/src/TaskThread/gwmgtwralgorithm.cpp @@ -79,11 +79,12 @@ void GwmGTWRAlgorithm::run() mGTWRCore->setTelegram(std::make_unique(this)); mBetas = mGTWRCore->fit(); - gwm::BandwidthWeight* bw = mGTWRCore->spatialWeight().weight(); - if (bw && !checkCanceled()) + const auto &coreW = mGTWRCore->spatialWeight().weight(); + if (coreW && !checkCanceled()) { // 更新本地权重 - updateLocalSpatialWeight(bw); + gwm::BandwidthWeight& bw = mGTWRCore->spatialWeight().weight(); + updateLocalSpatialWeight(&bw); mCriterionList = mGTWRCore->bandwidthSelectionCriterionList(); QVector> qlist; @@ -808,10 +809,12 @@ gwm::SpatialWeight GwmGTWRAlgorithm::convertSpatialWeight() // 创建空间距离 (CRSDistance) GwmCRSDistance* gwmDist = mSTWeight.distance(); bool isGeographic = gwmDist ? gwmDist->geographic() : false; - gwm::CRSDistance* spatialDist = new gwm::CRSDistance(isGeographic); + std::unique_ptr spatialDist = + std::make_unique(isGeographic); // 创建时间距离 (OneDimDistance) - gwm::OneDimDistance* temporalDist = new gwm::OneDimDistance(); + std::unique_ptr temporalDist = + std::make_unique(); // 创建 CRSSTDistance,传入空间距离、时间距离和 lambda gwm::CRSSTDistance* dist = new gwm::CRSSTDistance( diff --git a/src/TaskThread/gwmgwcorrelationtaskthread.cpp b/src/TaskThread/gwmgwcorrelationtaskthread.cpp index 80216fc..a148656 100644 --- a/src/TaskThread/gwmgwcorrelationtaskthread.cpp +++ b/src/TaskThread/gwmgwcorrelationtaskthread.cpp @@ -168,17 +168,13 @@ void GwmGWCorrelationTaskThread::run() gwm::SpatialWeight sw(bw, dist); // 设置距离参数(坐标数据已经在 initPoints 中准备好了) - if (dist->type() == gwm::Distance::CRSDistance) { - auto *d = sw.distance(); - if (d) { - d->makeParameter({ mDataPoints, mDataPoints }); - } + if (dist->type() == gwm::Distance::DistanceType::CRSDistance) { + auto &d = sw.distance(); + d.makeParameter({ mDataPoints, mDataPoints }); } - else if (dist->type() == gwm::Distance::MinkwoskiDistance) { - auto *d2 = sw.distance(); - if (d2) { - d2->makeParameter({ mDataPoints, mDataPoints }); - } + else if (dist->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { + auto &d2 = sw.distance(); + d2.makeParameter({ mDataPoints, mDataPoints }); } spatialWeights.push_back(sw); @@ -230,10 +226,10 @@ void GwmGWCorrelationTaskThread::run() for(uword i = 0 ; i(); - - if (gwmBw) + const auto& coreW = gwmSws[i].weight(); + if (coreW) { + gwm::BandwidthWeight& gwmBw = gwmSws[i].weight(); // 获取当前 GwmSpatialWeight 中的带宽权重 GwmBandwidthWeight* currentBw = mSpatialWeights[i].weight(); if (currentBw) @@ -241,11 +237,11 @@ void GwmGWCorrelationTaskThread::run() // 创建新的 GwmBandwidthWeight,使用更新后的带宽值 // 保持原有的 adaptive 和 kernel 设置 GwmBandwidthWeight::KernelFunctionType kernelType = - static_cast(gwmBw->kernel()); + static_cast(gwmBw.kernel()); GwmBandwidthWeight* newBw = new GwmBandwidthWeight( - gwmBw->bandwidth(), - gwmBw->adaptive(), + gwmBw.bandwidth(), + gwmBw.adaptive(), kernelType ); diff --git a/src/TaskThread/gwmgwpcataskthread.cpp b/src/TaskThread/gwmgwpcataskthread.cpp index 2d7d216..2d2a884 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" @@ -49,70 +49,84 @@ void GwmGWPCATaskThread::run() emit message(QString(tr("Automatically selecting bandwidth ..."))); emit tick(0, 0); - if ((mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || - mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) && !checkCanceled()) + if ((mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || + mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) && !checkCanceled()) { - gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); - if(d) + // gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); + // if(d) + // { + // d->makeParameter({ mDataPoints, mDataPoints }); + // } + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - d->makeParameter({ mDataPoints, mDataPoints }); + auto &d = mSpatialWeight.distance(); + d.makeParameter({ mDataPoints, mDataPoints }); + } + else if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) + { + auto &d2 = mSpatialWeight.distance(); + d2.makeParameter({ mDataPoints, mDataPoints }); } } - gwm::BandwidthWeight* bandwidthWeight0 = mSpatialWeight.weight(); - if(!bandwidthWeight0) + const auto &bwHolder = mSpatialWeight.weight(); + if(!bwHolder) { + qDebug() << "[GWPCA] ERROR: Cannot get bandwidth weight!"; emit error(tr("Cannot get bandwidth weight for bandwidth selection.")); return; } + + gwm::BandwidthWeight& bandwidthWeight0 = mSpatialWeight.weight(); double tmpMaxD = mSpatialWeight.distance()->maxDistance(); - double lower = bandwidthWeight0->adaptive() ? 2 : tmpMaxD / 5000; - double upper = bandwidthWeight0->adaptive() ? mDataPoints.n_rows : tmpMaxD; + 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)) + if(bandwidthWeight0.bandwidth() <= 0 || + (bandwidthWeight0.adaptive() && bandwidthWeight0.bandwidth() < lower) || + (!bandwidthWeight0.adaptive() && bandwidthWeight0.bandwidth() < lower)) { - double initialBandwidth = bandwidthWeight0->adaptive() ? + 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); + bandwidthWeight0.setBandwidth(initialBandwidth); } - - mSelector.setBandwidth(bandwidthWeight0); - mSelector.setLower(lower); - mSelector.setUpper(upper); - + try { - gwm::BandwidthWeight* bandwidthWeight = mSelector.optimize(this); - if(bandwidthWeight && !checkCanceled()) + gwm::BandwidthSelector selector(bandwidthWeight0, lower, upper); + gwm::Status optStatus = selector.optimize(this); + if (optStatus == gwm::Status::Terminated || checkCanceled()) { - mSpatialWeight.setWeight(bandwidthWeight); - mSelector.setBandwidth(bandwidthWeight); - - gwm::BandwidthWeight* verifyBw = mSpatialWeight.weight(); - if(verifyBw && verifyBw->bandwidth() == 0) + return; + } + const gwm::BandwidthWeight& rw = selector.result(); + // auto* applied = new GwmBandwidthWeight( + // rw.bandwidth(), + // rw.adaptive(), + // static_cast(rw.kernel())); + mSpatialWeight.setWeight(rw); + mBandwidthCriterionCache = selector.bandwidthCriterion(); + + const auto &verifyHolder = mSpatialWeight.weight(); + if (verifyHolder) + { + gwm::BandwidthWeight &verifyBw = mSpatialWeight.weight(); + if (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) + 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(...) + catch (...) { qDebug() << "[GWPCA] UNKNOWN EXCEPTION during bandwidth optimization"; emit error(tr("Unknown error occurred during bandwidth optimization.")); @@ -287,12 +301,14 @@ void GwmGWPCATaskThread::run() bool GwmGWPCATaskThread::isValid() { - gwm::BandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); - if(bandwidth){ + const auto &wh = mSpatialWeight.weight(); + if(wh){ + gwm::BandwidthWeight &bandwidth = mSpatialWeight.weight(); + if(!mIsAutoselectBandwidth) { - if(bandwidth->adaptive()){ - if(bandwidth->bandwidth() <= mVariables.size()){ + if(bandwidth.adaptive()){ + if(bandwidth.bandwidth() <= mVariables.size()){ return false; } } @@ -520,30 +536,30 @@ mat GwmGWPCATaskThread::robustSolveSerial(const mat& x, cube& loadings, mat& sde return pv; } -gwm::Status GwmGWPCATaskThread::getCriterion(gwm::BandwidthWeight* weight, double& criterion) +gwm::Status GwmGWPCATaskThread::getCriterion(const std::unique_ptr& weight, double& criterion) { - if(checkCanceled()) + if (!weight || checkCanceled()) { criterion = DBL_MAX; - return gwm::Status::Terminated; + return checkCanceled() ? gwm::Status::Terminated : gwm::Status::Success; } - - // 将内核库的BandwidthWeight转换为本地的GwmBandwidthWeight - GwmBandwidthWeight::KernelFunctionType kernelType = static_cast(weight->kernel()); + + 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) + catch (const std::exception& e) { qDebug() << "[GWPCA::getCriterion] EXCEPTION:" << e.what(); criterion = DBL_MAX; return gwm::Status::Success; } - catch(...) + catch (...) { qDebug() << "[GWPCA::getCriterion] UNKNOWN EXCEPTION"; criterion = DBL_MAX; @@ -782,14 +798,11 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVSerial(GwmBandwidthWeight *we int m = mX.n_cols; double score = 0; - if (mSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || - mSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + if (mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || + mSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - gwm::CRSDistance* d = static_cast(mSpatialWeight.distance()); - if(d) - { - d->makeParameter({ mDataPoints, mDataPoints }); - } + gwm::CRSDistance& d = mSpatialWeight.distance(); // static_cast(mSpatialWeight.distance()); + d.makeParameter({ mDataPoints, mDataPoints }); } for (int i = 0; i < n && !checkCanceled(); i++) @@ -859,7 +872,7 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh double score = 0; bool flag = true; vec score_all(mOmpThreadNum, fill::zeros); - int current = 0; + // int current = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -886,9 +899,11 @@ 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); - current++; + // if(mSelector.counter<10) + // emit tick(mSelector.counter * 10 + current * 10 / n, 100); + // current++; + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); } } score = sum(score_all); diff --git a/src/TaskThread/gwmgwpcataskthread.h b/src/TaskThread/gwmgwpcataskthread.h index 3d656d4..1dea73a 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 @@ -8,6 +8,7 @@ #include "TaskThread/gwmbandwidthsizeselector.h" #include +// #include // in case that std::unique_ptr cannot be found class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidthSizeSelectable, public IGwmMultivariableAnalysis, public IOpenmpParallelable, public gwm::IBandwidthSelectable { @@ -48,7 +49,8 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt BandwidthCriterionList bandwidthSelectorCriterions() const { - return mSelector.bandwidthCriterion(); + // return mSelector.bandwidthCriterion(); + return mBandwidthCriterionCache; } double k() const; @@ -130,7 +132,7 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt } public: // gwm::IBandwidthSelectable interface - gwm::Status getCriterion(gwm::BandwidthWeight* weight, double& criterion) override; + gwm::Status getCriterion(const std::unique_ptr& weight, double& criterion) override; private: QList mVariables; @@ -141,7 +143,8 @@ class GwmGWPCATaskThread : public GwmSpatialMonoscaleAlgorithm, public IBandwidt mat mX; vec mLatestWt; - gwm::BandwidthSelector mSelector; + // gwm::BandwidthSelector mSelector; + BandwidthCriterionList mBandwidthCriterionCache; BandwidthSelectionCriterionType mBandwidthSelectionCriterionType = BandwidthSelectionCriterionType::CV; BandwidthSelectCriterionFunction mBandwidthSelectCriterionFunction = &GwmGWPCATaskThread::bandwidthSizeCriterionCVSerial; bool mIsAutoselectBandwidth = false; diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp index 70196d8..3d7deed 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.cpp @@ -78,7 +78,7 @@ void GwmLocalCollinearityGWRAlgorithm::run() mBetas = mLCGWRCore->fit(); std::cout << "mBetas = \n" << mBetas << std::endl; - gwm::BandwidthWeight* bw = mLCGWRCore->spatialWeight().weight(); + gwm::BandwidthWeight& bw = mLCGWRCore->spatialWeight().weight(); mSpatialWeight.setWeight(bw); criterionList = mLCGWRCore->bandwidthSelectionCriterionList(); @@ -325,7 +325,7 @@ double GwmLocalCollinearityGWRAlgorithm::bandwidthSizeCriterionCVOmp(GwmBandwidt //取mX不含第一列的部分 mat mXnot1 = mX.cols(1, mX.n_cols - 1); //主循环 - int current = 0; + // int current = 0; #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -359,9 +359,11 @@ 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); - current++; + // if(selector.counter<10) + // emit tick(selector.counter*10 + current * 10 / n, 100); + if (i % std::max(1, n / 10) == 0) + emit tick(i * 100 / n, 100); + // current++; } } //yhat赋值 @@ -552,12 +554,12 @@ bool GwmLocalCollinearityGWRAlgorithm::isValid() { if (GwmGeographicalWeightedRegressionAlgorithm::isValid()) { - gwm::BandwidthWeight* bandwidth = static_cast(mSpatialWeight.weight()); + gwm::BandwidthWeight& bandwidth = mSpatialWeight.weight();//static_cast(mSpatialWeight.weight()); if(!mIsAutoselectBandwidth) { - if(bandwidth->adaptive()){ - if (bandwidth->bandwidth() <= mIndepVars.size()) return false; + if(bandwidth.adaptive()){ + if (bandwidth.bandwidth() <= mIndepVars.size()) return false; }else{ } diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h index 1e24c60..04e6534 100644 --- a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h +++ b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h @@ -108,7 +108,7 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA double mCnThresh; - gwm::BandwidthSelector selector; + //gwm::BandwidthSelector selector; bool mHasHatmatix = false; diff --git a/src/TaskThread/gwmmultiscalegwralgorithm.cpp b/src/TaskThread/gwmmultiscalegwralgorithm.cpp index 28fd875..02d3ed4 100644 --- a/src/TaskThread/gwmmultiscalegwralgorithm.cpp +++ b/src/TaskThread/gwmmultiscalegwralgorithm.cpp @@ -174,17 +174,13 @@ void GwmMultiscaleGWRAlgorithm::run() gwm::SpatialWeight sw(bw, dist); // 设置距离参数(坐标数据已经在 initPoints 中准备好了) - if (dist->type() == gwm::Distance::CRSDistance) { - auto *d = sw.distance(); - if (d) { - d->makeParameter({ mRegressionPoints, mDataPoints }); - } + if (dist->type() == gwm::Distance::DistanceType::CRSDistance) { + auto &d = sw.distance(); + d.makeParameter({ mRegressionPoints, mDataPoints }); } - else if (dist->type() == gwm::Distance::MinkwoskiDistance) { - auto *d2 = sw.distance(); - if (d2) { - d2->makeParameter({ mRegressionPoints, mDataPoints }); - } + else if (dist->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { + auto &d2 = sw.distance(); + d2.makeParameter({ mRegressionPoints, mDataPoints }); } spatialWeights.push_back(sw); @@ -254,13 +250,14 @@ void GwmMultiscaleGWRAlgorithm::run() { for (size_t i = 0; i < ws.size(); i++) { - gwm::BandwidthWeight* gwmBw = ws[i].weight(); - if (gwmBw) + const auto& coreW = ws[i].weight(); + if (coreW) { + gwm::BandwidthWeight& gwmBw = ws[i].weight(); // 从库的带宽权重中提取参数 - double bandwidth = gwmBw->bandwidth(); - bool adaptive = gwmBw->adaptive(); - gwm::BandwidthWeight::KernelFunctionType gwmKernel = gwmBw->kernel(); + double bandwidth = gwmBw.bandwidth(); + bool adaptive = gwmBw.adaptive(); + gwm::BandwidthWeight::KernelFunctionType gwmKernel = gwmBw.kernel(); // 转换为应用层的类型 GwmBandwidthWeight::KernelFunctionType kernel = convertKernelTypeBack(gwmKernel); diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index fe9e9e1..af35c89 100644 --- a/src/TaskThread/gwmrobustgwralgorithm.cpp +++ b/src/TaskThread/gwmrobustgwralgorithm.cpp @@ -446,22 +446,22 @@ mat GwmRobustGWRAlgorithm::regressionHatmatrixCuda(const mat &x, const vec &y, m bool longlat = false; if (mSpatialWeight.distance()->type() == GwmDistance::MinkwoskiDistance) { - GwmMinkwoskiDistance* d = mSpatialWeight.distance(); - p = d->poly(); - theta = d->theta(); + gwm::MinkwoskiDistance& d = mSpatialWeight.distance(); + p = d.poly(); + theta = d.theta(); } else if (mSpatialWeight.distance()->type() == GwmDistance::CRSDistance) { - GwmCRSDistance* d = mSpatialWeight.distance(); - longlat = d->geographic(); + gwm::CRSDistance& d = mSpatialWeight.distance(); + longlat = d.geographic(); } - GwmBandwidthWeight* bw = mSpatialWeight.weight(); - bool adaptive = bw->adaptive(); + gwm::BandwidthWeight& bw = mSpatialWeight.weight(); + bool adaptive = bw.adaptive(); for(int i=0;iSetWeightMask(i,mWeightMask(i)); } - bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw->bandwidth(), bw->kernel(), adaptive, mGroupSize, mGpuId); + bool gwrStatus = cuda->Regression(true, p, theta, longlat, bw.bandwidth(), bw.kernel(), adaptive, mGroupSize, mGpuId); mat betas(nVar, nDp, fill::zeros); betasSE = mat(nVar, nDp, fill::zeros); shat = vec(2, fill::zeros); diff --git a/src/TaskThread/gwmscalablegwralgorithm.cpp b/src/TaskThread/gwmscalablegwralgorithm.cpp index 8aa5716..1a15d91 100644 --- a/src/TaskThread/gwmscalablegwralgorithm.cpp +++ b/src/TaskThread/gwmscalablegwralgorithm.cpp @@ -224,7 +224,7 @@ void GwmScalableGWRAlgorithm::run() // findDataPointNeighbours(); } - qDebug() << "Bandwidth:" << mSpatialWeight.weight()->bandwidth(); + qDebug() << "Bandwidth:" << mSpatialWeight.weight().bandwidth(); qDebug() << "Before mSGWRCore->fit()"; arma::mat betas = mSGWRCore->fit(); qDebug() << "After mSGWRCore->fit(), betas size:" << betas.n_rows << betas.n_cols; @@ -312,8 +312,8 @@ void GwmScalableGWRAlgorithm::run() void GwmScalableGWRAlgorithm::findDataPointNeighbours() { - gwm::BandwidthWeight* bandwidth = mDpSpatialWeight.weight(); - uword nDp = mDataPoints.n_rows, nBw = bandwidth->bandwidth() < nDp ? bandwidth->bandwidth() : nDp; + gwm::BandwidthWeight& bandwidth = mDpSpatialWeight.weight(); + uword nDp = mDataPoints.n_rows, nBw = bandwidth.bandwidth() < nDp ? bandwidth.bandwidth() : nDp; if (mParameterOptimizeCriterion == ParameterOptimizeCriterionType::CV) { nBw -= 1; @@ -344,10 +344,10 @@ void GwmScalableGWRAlgorithm::findDataPointNeighbours() mat GwmScalableGWRAlgorithm::findNeighbours(const gwm::SpatialWeight &spatialWeight, umat &nnIndex) { - gwm::BandwidthWeight* bandwidth = spatialWeight.weight(); + 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; + uword nBw = bandwidth.bandwidth() < nDp ? bandwidth.bandwidth() : nDp; umat index(nBw, nRp, fill::zeros); mat dists(nBw, nRp, fill::zeros); for (uword i = 0; i < nRp && !checkCanceled(); i++) @@ -388,7 +388,7 @@ double scagwr_aic_multimin_function0(const gsl_vector* vars, void* params) double GwmScalableGWRAlgorithm::optimize(const mat &Mx0, const mat &My0, double& b_tilde, double& alpha) { - GwmBandwidthWeight* bandwidth = mSpatialWeight.weight(); + gwm::BandwidthWeight& bandwidth = mSpatialWeight.weight(); gsl_multimin_fminimizer* minizer = gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex, 2); gsl_vector* target = gsl_vector_alloc(2); gsl_vector_set(target, 0, b_tilde); @@ -396,7 +396,7 @@ double GwmScalableGWRAlgorithm::optimize(const mat &Mx0, const mat &My0, double& gsl_vector* step = gsl_vector_alloc(2); gsl_vector_set(step, 0, 0.01); gsl_vector_set(step, 1, 0.01); - LoocvParams params = { &mX, &mY, (int)bandwidth->bandwidth(), mPolynomial, &Mx0, &My0 }; + LoocvParams params = { &mX, &mY, (int)bandwidth.bandwidth(), mPolynomial, &Mx0, &My0 }; gsl_multimin_function function = { mParameterOptimizeCriterion == CV ? &scagwr_loocv_multimin_function0 : &scagwr_aic_multimin_function0, 2, ¶ms }; double cv = DBL_MAX; int status = gsl_multimin_fminimizer_set(minizer, &function, target, step); @@ -471,13 +471,13 @@ void GwmScalableGWRAlgorithm::prepare() mat GwmScalableGWRAlgorithm::regressionSerial(const arma::mat &x, const arma::vec &y) { - gwm::BandwidthWeight* bandwidth = mSpatialWeight.weight(); - arma::uword nDp = mDataPoints.n_rows, nRp = mRegressionPoints.n_rows, nVar = mX.n_cols, nBw = bandwidth->bandwidth(); + 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; umat rpNNIndex; mat rpNNDists = findNeighbours(mSpatialWeight, rpNNIndex); - switch (bandwidth->kernel()) + switch (bandwidth.kernel()) { case gwm::BandwidthWeight::KernelFunctionType::Gaussian: band0 = median(rpNNDists.col(qMin(50, nBw) - 1)) / sqrt(3); @@ -572,8 +572,8 @@ mat GwmScalableGWRAlgorithm::regressionSerial(const arma::mat &x, const arma::ve arma::mat GwmScalableGWRAlgorithm::regressionHatmatrixSerial(const arma::mat &x, const arma::vec &y) { - GwmBandwidthWeight* bandwidth = mSpatialWeight.weight(); - int bw = bandwidth->bandwidth(); + gwm::BandwidthWeight& bandwidth = mSpatialWeight.weight(); + int bw = bandwidth.bandwidth(); int n = x.n_rows, k = x.n_cols, poly1 = mPolynomial + 1; double b = mScale, a = mPenalty; mat XtX = x.t() * x, XtY = x.t() * y; @@ -582,13 +582,13 @@ arma::mat GwmScalableGWRAlgorithm::regressionHatmatrixSerial(const arma::mat &x, double band0 = 0.0; umat dpNNIndex; mat dpNNDists = findNeighbours(mDpSpatialWeight, dpNNIndex); - switch (bandwidth->kernel()) + switch (bandwidth.kernel()) { - case GwmBandwidthWeight::KernelFunctionType::Gaussian: + case gwm::BandwidthWeight::KernelFunctionType::Gaussian: band0 = median(dpNNDists.col(qMin(50, bw) - 1)) / sqrt(3); mG0 = exp(-pow(dpNNDists / band0, 2)); break; - case GwmBandwidthWeight::KernelFunctionType::Exponential: + case gwm::BandwidthWeight::KernelFunctionType::Exponential: band0 = median(dpNNDists.col(qMin(50, bw) - 1)) / 3; mG0 = exp(-pow(dpNNDists / band0, 2)); break; @@ -694,23 +694,17 @@ arma::mat GwmScalableGWRAlgorithm::regressionHatmatrixSerial(const arma::mat &x, void GwmScalableGWRAlgorithm::initPoints() { GwmGeographicalWeightedRegressionAlgorithm::initPoints(); - if (mDpSpatialWeight.distance()->type() == gwm::Distance::CRSDistance || mDpSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + if (mDpSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance || mDpSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - if (mDpSpatialWeight.distance()->type() == gwm::Distance::CRSDistance) + if (mDpSpatialWeight.distance()->type() == gwm::Distance::DistanceType::CRSDistance) { - auto* d = mDpSpatialWeight.distance(); - if (d) - { - d->makeParameter({ mDataPoints, mDataPoints }); - } + auto& d = mDpSpatialWeight.distance(); + d.makeParameter({ mDataPoints, mDataPoints }); } - else if (mDpSpatialWeight.distance()->type() == gwm::Distance::MinkwoskiDistance) + else if (mDpSpatialWeight.distance()->type() == gwm::Distance::DistanceType::MinkwoskiDistance) { - auto* d2 = mDpSpatialWeight.distance(); - if (d2) - { - d2->makeParameter({ mDataPoints, mDataPoints }); - } + auto& d2 = mDpSpatialWeight.distance(); + d2.makeParameter({ mDataPoints, mDataPoints }); } } } @@ -836,11 +830,11 @@ bool GwmScalableGWRAlgorithm::isValid() { if (GwmGeographicalWeightedRegressionAlgorithm::isValid()) { - gwm::BandwidthWeight* bandwidth = mSpatialWeight.weight(); - if (!(bandwidth->kernel() == gwm::BandwidthWeight::Gaussian || bandwidth->kernel() == gwm::BandwidthWeight::Exponential)) + gwm::BandwidthWeight& bandwidth = mSpatialWeight.weight(); + if (!(bandwidth.kernel() == gwm::BandwidthWeight::Gaussian || bandwidth.kernel() == gwm::BandwidthWeight::Exponential)) return false; - if (bandwidth->bandwidth() <= mIndepVars.size()) + if (bandwidth.bandwidth() <= mIndepVars.size()) return false; return true;