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/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/gwmbasicgwralgorithm.cpp b/src/TaskThread/gwmbasicgwralgorithm.cpp index 54217f9..559ac2d 100644 --- a/src/TaskThread/gwmbasicgwralgorithm.cpp +++ b/src/TaskThread/gwmbasicgwralgorithm.cpp @@ -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 { @@ -826,6 +837,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 +866,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 +990,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 +1021,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++; } } @@ -1530,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/gwmgeneralizedgwralgorithm.cpp b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp index a281f0e..70ff44c 100644 --- a/src/TaskThread/gwmgeneralizedgwralgorithm.cpp +++ b/src/TaskThread/gwmgeneralizedgwralgorithm.cpp @@ -589,7 +589,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; @@ -818,7 +818,7 @@ double GwmGeneralizedGWRAlgorithm::bandwidthSizeGGWRCriterionCVSerial(GwmBandwid .arg(res); emit message(msg); return res; - } + } else return DBL_MAX; } @@ -829,6 +829,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++) { @@ -838,9 +839,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); @@ -857,8 +860,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++; } } @@ -883,7 +888,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); @@ -935,6 +940,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++) { @@ -943,8 +949,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++; } } @@ -959,8 +967,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++; } } @@ -1460,11 +1470,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)) { @@ -1476,7 +1486,7 @@ void GwmGeneralizedGWRAlgorithm::fTest(FTestParameters params) f3.append(f3i); continue; } - + GwmFTestResult f3i; f3i.s = (vk2(i) / g1) / sigma2delta1; f3i.df1 = numdf; @@ -1516,20 +1526,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 保持一致 @@ -1540,20 +1550,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 保持一致 @@ -1565,7 +1575,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/gwmgwaveragetaskthread.cpp b/src/TaskThread/gwmgwaveragetaskthread.cpp index 480c760..15a7ad1 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" @@ -45,6 +45,11 @@ 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) @@ -60,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); @@ -75,7 +88,31 @@ void GwmGWAverageTaskThread::run() try { mAlgorithm.setTelegram(make_unique(this)); + 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/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 2d7d216..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" @@ -860,6 +860,7 @@ double GwmGWPCATaskThread::bandwidthSizeCriterionCVOmp(GwmBandwidthWeight *weigh bool flag = true; vec score_all(mOmpThreadNum, fill::zeros); int current = 0; + const int selectorStep = static_cast(mSelector.bandwidthCriterion().size()); #pragma omp parallel for num_threads(mOmpThreadNum) for (int i = 0; i < n; i++) { @@ -886,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..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()) @@ -75,8 +85,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 +139,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)]; } @@ -326,6 +348,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 +382,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++; } } @@ -498,28 +523,12 @@ 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()) + if (mLCGWRCore && (type & mLCGWRCore->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; - } + mLCGWRCore->setParallelType(type); } } diff --git a/src/TaskThread/gwmlocalcollinearitygwralgorithm.h b/src/TaskThread/gwmlocalcollinearitygwralgorithm.h index 1e24c60..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 IOpenmpParallelable +class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionAlgorithm, public IBandwidthSizeSelectable, 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,14 +92,18 @@ 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: 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; @@ -127,7 +131,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 +140,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 +150,10 @@ class GwmLocalCollinearityGWRAlgorithm:public GwmGeographicalWeightedRegressionA inline int GwmLocalCollinearityGWRAlgorithm::parallelAbility() const { - return IParallelalbe::SerialOnly | IParallelalbe::OpenMP; + return mLCGWRCore ? mLCGWRCore->parallelAbility() : (gwm::SerialOnly | gwm::OpenMP); } -inline IParallelalbe::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const +inline gwm::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelType() const { return mParallelType; } @@ -157,6 +161,10 @@ inline IParallelalbe::ParallelType GwmLocalCollinearityGWRAlgorithm::parallelTyp inline void GwmLocalCollinearityGWRAlgorithm::setOmpThreadNum(const int threadNum) { mOmpThreadNum = threadNum; + if (mLCGWRCore) + { + mLCGWRCore->setOmpThreadNum(threadNum); + } } #endif // GWMLCRGWRTASKTHREAD_H diff --git a/src/TaskThread/gwmrobustgwralgorithm.cpp b/src/TaskThread/gwmrobustgwralgorithm.cpp index fe9e9e1..7ec099c 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()){ @@ -258,29 +269,7 @@ 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; - } - } + // GwmBasicGWRAlgorithm::setParallelType(type); } mat GwmRobustGWRAlgorithm::robustGWRCaliFirst(const mat &x, const vec &y, mat &betasSE, vec &shat, vec &qDiag, mat &S) 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 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 + 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 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()); } // 其他设置