From 50f149970c31d7986fe3e3088402ddb00b900ac8 Mon Sep 17 00:00:00 2001 From: lvjunjie Date: Mon, 21 Sep 2026 15:54:49 +0800 Subject: [PATCH] =?UTF-8?q?refactor(nmNum):=20=E7=AE=80=E5=8C=96=20LM=20?= =?UTF-8?q?=E5=BD=A2=E7=8A=B6=E9=98=B6=E6=AE=B5=E8=81=94=E5=90=88=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E4=B8=8E=E5=81=9C=E6=BB=9E=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除时间窗口选参、三参数上限及子集枚举,每步联合调整全部有效非井储表皮参数 - 连续两次改善不足后刷新灵敏度,仅做一次全局联合确认,累计有效改善门槛设为 10% - 放宽形状扩步条件,取消实际与预测改善比值限制,保留预测下降、步长和边界约束 - 确认步求解失败时有限重试,避免将失败误判为收敛 - 同步拟合轨迹元数据、尝试次数日志及中文翻译 --- Bin/Config/Lang/cn/nmNum_cn.qm | Bin 147204 -> 147250 bytes Bin/Config/Lang/cn/nmNum_cn.ts | 20 +- .../nmCalculation/nmCalculationAutoFitLM.cpp | 303 +++++------------- 3 files changed, 83 insertions(+), 240 deletions(-) diff --git a/Bin/Config/Lang/cn/nmNum_cn.qm b/Bin/Config/Lang/cn/nmNum_cn.qm index 5fba495298f5119796643e552bffa0b41ea529e3..776d7652a03136f518578c753c99f83aeb04808f 100644 GIT binary patch delta 14262 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 delta 14194 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 ZNC1=`5E>R&eN>bAq2}~ZGdq3e{{ejY3bFtI diff --git a/Bin/Config/Lang/cn/nmNum_cn.ts b/Bin/Config/Lang/cn/nmNum_cn.ts index 104dcbea..6515933d 100644 --- a/Bin/Config/Lang/cn/nmNum_cn.ts +++ b/Bin/Config/Lang/cn/nmNum_cn.ts @@ -1281,20 +1281,20 @@ Reason: %1 进入联合形状调整时重建灵敏度 - Adaptive fitting counts: %1 completed shape rounds, %2 total-stage iterations, %3 total evaluations. - 自适应拟合统计:已完成 %1 轮形状搜索,整体阶段迭代 %2 次,累计评估 %3 次。 + Adaptive fitting counts: %1 shape attempts, %2 total-stage iterations, %3 total evaluations. + 自适应拟合统计:形状尝试 %1 次,整体阶段迭代 %2 次,累计评估 %3 次。 - LM stage 2: adaptive shape search; confirm stagnation after 2 complete rounds without significant improvement. - LM 阶段2:自适应形状搜索;连续两轮完整搜索无显著改善后确认停滞。 + LM stage 2: joint shape search; after 2 ineffective steps, refresh sensitivity and confirm with one global step. + LM 第二阶段:联合调整全部可调形状参数;连续两次改善不足后,刷新灵敏度并用一次全局联合调整确认。 LM starting point error: %1; independent total-stage evaluation budget: %2 LM 起点误差:%1;整体阶段独立评估预算:%2 - Shape search round %1: shape error=%2, improvement=%3, required=%4. - 形状搜索第 %1 轮:形状误差=%2,改善量=%3,所需改善量=%4。 + Shape search step %1: shape error=%2, accumulated improvement=%3, required=%4. + 形状尝试 %1:形状误差=%2,累计改善=%3,有效改善门槛=%4。 Total-stage budget starts now: %1 iterations, %2 evaluations; pre-adjustment is counted separately. @@ -1305,16 +1305,16 @@ Reason: %1 无法建立有效的形状灵敏度模型。 - confirm stagnation after 2 complete shape rounds - 完成两轮形状搜索后确认停滞 + confirm shape stagnation after 2 ineffective steps + 连续两次形状改善不足,刷新灵敏度确认停滞 full sensitivity at total-stage entry 进入整体阶段时建立完整灵敏度 - no significant improvement in a complete round after fresh sensitivity confirmation - 重建灵敏度确认后,完整一轮搜索仍无显著改善 + no significant shape improvement after fresh sensitivity and one global step + 刷新灵敏度并进行一次全局联合调整后,形状仍无显著改善 no valid early sensitivity model diff --git a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp index 402e5b38..78ab27e9 100644 --- a/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp +++ b/Src/nmNum/nmCalculation/nmCalculationAutoFitLM.cpp @@ -594,95 +594,6 @@ static QVector buildTrustRegionFisher( return information; } -static int nextTrustRegionWindow( - const QVector& windows, - const QVector& attempted) -{ - // 每次都按当前误差能量重新排序;本轮无效的窗口暂时跳过,-1 表示全局回退。 - int selected = -1; - double largestEnergy = 0.0; - for(int k = 0; k < windows.size(); ++k) { - if(!attempted[k] && isFiniteNumber(windows[k].energy) && - windows[k].energy > largestEnergy) { - largestEnergy = windows[k].energy; - selected = k; - } - } - return selected; -} - -static QVector selectTrustRegionFisherColumns( - const TrustRegionFisher& local, - const TrustRegionFisher& global, - const QVector& columnValid, - const QVector& coordinates, - double minimumStep) -{ - // g^2/F 衡量修正当前残差的潜力,避免仅按影响强度选中无助于降误差的参数。 - const int dimensions = columnValid.size(); - double maximumDiagonal = 0.0; - for(int p = 0; p < dimensions; ++p) { - if(columnValid[p] && isFiniteNumber(local.matrix[p][p])) { - maximumDiagonal = qMax(maximumDiagonal, local.matrix[p][p]); - } - } - const double diagonalFloor = qMax(1.0e-30, maximumDiagonal * 1.0e-12); - QVector scores(dimensions, 0.0); - double maximumScore = 0.0; - for(int p = 0; p < dimensions; ++p) { - if(!columnValid[p] || local.matrix[p][p] <= diagonalFloor || - !isFiniteNumber(local.matrix[p][p]) || - !isFiniteNumber(local.gradient[p]) || - !isFiniteNumber(global.gradient[p])) { - continue; - } - // 全局下降方向指向边界外时暂不选该参数,避免它挤占可移动参数的位置。 - if((coordinates[p] <= minimumStep && global.gradient[p] > 0.0) || - (coordinates[p] >= 1.0 - minimumStep && global.gradient[p] < 0.0)) { - continue; - } - double scaledGradient = local.gradient[p] / - qSqrt(local.matrix[p][p] + diagonalFloor); - double score = scaledGradient * scaledGradient; - if(isFiniteNumber(score)) { - scores[p] = score; - maximumScore = qMax(maximumScore, score); - } - } - - QVector selected; - for(int selection = 0; selection < qMin(3, dimensions); ++selection) { - int best = -1; - double bestScore = maximumScore * 1.0e-12; - for(int p = 0; p < dimensions; ++p) { - if(selected.contains(p) || scores[p] <= bestScore) { - continue; - } - // 沿用现有全局 0.995 共线限制,不因单个窗口内响应相似而冻结参数。 - bool correlated = false; - for(int i = 0; i < selected.size(); ++i) { - int q = selected[i]; - double denominator = qSqrt(global.matrix[p][p]) * - qSqrt(global.matrix[q][q]); - if(denominator > 0.0 && - qAbs(global.matrix[p][q]) / denominator > 0.995) { - correlated = true; - break; - } - } - if(!correlated) { - best = p; - bestScore = scores[p]; - } - } - if(best < 0) { - break; - } - selected.append(best); - } - return selected; -} - static bool buildTrustRegionFisherStep( const TrustRegionFisher& global, const QVector& selected, @@ -1212,7 +1123,7 @@ void nmCalculationAutoFitLM::writeTraceMetaFile() QTextStream out(&metaFile); out << "{\n"; - out << " \"schema_version\": 31,\n"; + out << " \"schema_version\": 36,\n"; out << " \"strategy\": \"permeability_height_then_shape_then_joint_lm\",\n"; out << " \"height_acceptance\": \"reliable_vertical_loss_decrease; no_shape_or_total_loss_constraint\",\n"; out << " \"shape_priority\": \"storage_then_skin_then_shape_without_wellbore_then_optional_wellbore_recheck\",\n"; @@ -1228,10 +1139,10 @@ void nmCalculationAutoFitLM::writeTraceMetaFile() out << " \"shape_stage_total_constraint\": false,\n"; out << " \"shape_wellbore_parameters_frozen\": true,\n"; out << " \"shape_sensitivity_refresh\": \"non_wellbore_columns_only at joint shape entry and stagnation confirmation; full Jacobian rebuilt at total-stage entry\",\n"; - out << " \"shape_expansion_policy\": \"one expansion per reliable shape direction, up to 2x when actual rho exceeds 0.75; retain ordinary step on failure\",\n"; - out << " \"shape_global_parameter_selection\": \"all_valid_non_wellbore_columns_with_positive_response\",\n"; - out << " \"stage2_budget\": \"adaptive, no fixed iteration or evaluation quota; full window/global rounds, 2 ineffective rounds then fresh-J confirmation\",\n"; - out << " \"shape_round_improvement_threshold\": \"max(0.0001, 1% of round entry shape loss)\",\n"; + out << " \"shape_expansion_policy\": \"one expansion per accepted shape direction, up to 2x with predicted descent and parameter bounds; no_rho_gate; retain ordinary step on failure\",\n"; + out << " \"shape_global_parameter_selection\": \"all_valid_non_wellbore_columns_with_positive_response_at_every_shape_step; no_window_selection\",\n"; + out << " \"stage2_budget\": \"adaptive, no fixed iteration or evaluation quota; 2 ineffective shape attempts then one fresh-J global confirmation\",\n"; + out << " \"shape_step_improvement_threshold\": \"max(0.0001, 10% of last effective shape loss); accumulate small improvements\",\n"; out << " \"iteration_count_scope\": \"max_iterations applies to total-stage LM; trace iteration remains cumulative\",\n"; out << " \"wellbore_recheck_trigger\": \"early loss exceeds initial early-stage exit by max(0.0001, 10%)\",\n"; out << " \"wellbore_recheck_acceptance\": \"early decrease with fixed entry shape limit max(0.0001, 5%); no_total_loss_constraint\",\n"; @@ -2033,7 +1944,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() const char* rebuildReason = QT_TR_NOOP("initial sensitivity model"); bool modelRebuiltAtMinimumRadius = false; bool stagnationConfirmationRequested = false; - QVector attemptedWindows(kAutoFitTimeWindowCount, false); bool globalFallbackAttempted = false; StopReasonLM stopReason = LM_MAX_ITERATIONS; @@ -2210,13 +2120,13 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() if(m_shouldStop) return LM_USER_STOPPED; - // 第二阶段不按迭代比例截断;普通形状按完整搜索轮次判断是否仍有显著改善。 + // 第二阶段不按迭代比例截断;连续两次改善不足后,刷新灵敏度并仅做一次全局联合确认。 // 普通形状调整冻结井储、表皮,只按形状验收;总误差达标只在第三阶段判断。 bool shapeStage = true; bool jointShapeStarted = false; - double shapeRoundBaseline = current.breakdown.shapeLoss; - int shapeRoundNumber = 0; - int ineffectiveShapeRounds = 0; + double shapeImprovementBaseline = current.breakdown.shapeLoss; + int shapeStepCount = 0; + int ineffectiveShapeSteps = 0; bool shapeConfirmationRequested = false; const int storageColumn = m_enabledParamIndices.indexOf(2); const int skinColumn = m_enabledParamIndices.indexOf(1); @@ -2283,7 +2193,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() restoreEvaluationState(current); }; emit logMessageGenerated(shapeStage - ? tr("LM stage 2: adaptive shape search; confirm stagnation after 2 complete rounds without significant improvement.") + ? tr("LM stage 2: joint shape search; after 2 ineffective steps, refresh sensitivity and confirm with one global step.") : tr("LM stage 3: original LM fitting; accept by total error only.")); if(earlyShapeStage) { emit logMessageGenerated(earlyShapeParameter == 2 @@ -2328,7 +2238,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() consecutivePoorPredictions = 0; modelRebuiltAtMinimumRadius = false; stagnationConfirmationRequested = false; - attemptedWindows.fill(false); globalFallbackAttempted = false; fullDataRejections = 0; effectiveImprovementBaseline = stageError(current); @@ -2357,7 +2266,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() consecutiveRejectedSteps = 0; consecutiveSolverFailures = 0; stagnationConfirmationRequested = false; - attemptedWindows.fill(false); globalFallbackAttempted = false; trustRadius = 0.12; damping = 0.01; @@ -2454,35 +2362,36 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() true, 0, "early_wellbore_to_shape", ¤t.breakdown); }; - auto completeShapeSearchRound = [&]() { - if(!shapeStage || earlyShapeStage || !globalFallbackAttempted) return; - if(m_shouldStop) return; - const double required = qMax(1.0e-4, 0.01 * shapeRoundBaseline); - const double improvement = shapeRoundBaseline - current.breakdown.shapeLoss; + auto completeShapeSearchStep = [&]() { + if(!shapeStage || earlyShapeStage || m_shouldStop) return; + // 改善相对上一次有效改善累计,避免单次小步被立即否定;不再等待完整窗口轮次。 + const double required = qMax(1.0e-4, 0.10 * shapeImprovementBaseline); + const double improvement = shapeImprovementBaseline - current.breakdown.shapeLoss; const bool improved = improvement >= required; - ++shapeRoundNumber; + ++shapeStepCount; + writeTraceRow(m_currentIteration, -1, "shape_step_end", current.parameters, current.fitness, + true, 0, QString(improved ? "improved_step_%1" : "ineffective_step_%1").arg(shapeStepCount), ¤t.breakdown); + emit logMessageGenerated(tr("Shape search step %1: shape error=%2, accumulated improvement=%3, required=%4.") + .arg(shapeStepCount).arg(current.breakdown.shapeLoss, 0, 'g', 6) + .arg(improvement, 0, 'g', 6).arg(required, 0, 'g', 6)); + // 每次形状调整都是全局联合步,结束后清除本次尝试标记。 + globalFallbackAttempted = false; if(improved) { - ineffectiveShapeRounds = 0; + shapeImprovementBaseline = current.breakdown.shapeLoss; + ineffectiveShapeSteps = 0; shapeConfirmationRequested = false; - } else ++ineffectiveShapeRounds; - writeTraceRow(m_currentIteration, -1, "shape_round_end", current.parameters, current.fitness, - true, 0, QString(improved ? "improved_round_%1" : "ineffective_round_%1").arg(shapeRoundNumber), ¤t.breakdown); - emit logMessageGenerated(tr("Shape search round %1: shape error=%2, improvement=%3, required=%4.") - .arg(shapeRoundNumber).arg(current.breakdown.shapeLoss, 0, 'g', 6) - .arg(improvement, 0, 'g', 6).arg(required, 0, 'g', 6)); - if(!improved && shapeConfirmationRequested) { - finishShapeStage(tr("no significant improvement in a complete round after fresh sensitivity confirmation")); return; } - // 下一轮重新覆盖窗口和全部有效参数的全局步;单步小改善不重置本轮进度。 - shapeRoundBaseline = current.breakdown.shapeLoss; - attemptedWindows.fill(false); - globalFallbackAttempted = false; - if(!improved && ineffectiveShapeRounds >= 2) { + ++ineffectiveShapeSteps; + if(shapeConfirmationRequested) { + finishShapeStage(tr("no significant shape improvement after fresh sensitivity and one global step")); + return; + } + if(ineffectiveShapeSteps >= 2) { jacobian.clear(); reuseSensitivityForNextStage(); rebuildRequested = true; - rebuildReason = QT_TR_NOOP("confirm stagnation after 2 complete shape rounds"); + rebuildReason = QT_TR_NOOP("confirm shape stagnation after 2 ineffective steps"); shapeConfirmationRequested = true; } }; @@ -2498,8 +2407,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() return false; } - // 有效改善后重新开放全部窗口,并按新工作点的能量排序。 - attemptedWindows.fill(false); + // 有效改善后更新累计基准,并清除停滞计数。 globalFallbackAttempted = false; effectiveImprovementBaseline = fitness; consecutiveIneffectiveSteps = 0; @@ -2507,11 +2415,11 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() return true; }; - // 无效尝试仍累计,但所有窗口及一次全局回退尝试完毕前,不触发停滞收敛。 - // 完整一轮仍无改善时沿用原有重建确认,避免某个难处理窗口提前终止拟合。 + // 普通形状按连续尝试判断停滞,并用新灵敏度下的全局联合步确认; + // 前期井储、表皮与整体 LM 沿用各自的无效次数处理。 auto recordIneffectiveStep = [&]() -> bool { if(shapeStage && !earlyShapeStage) { - completeShapeSearchRound(); + completeShapeSearchStep(); return false; } ++consecutiveIneffectiveSteps; @@ -2524,7 +2432,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() if(!globalFallbackAttempted) { return false; } - attemptedWindows.fill(false); globalFallbackAttempted = false; if(consecutiveIneffectiveSteps < maximumIneffectiveSteps) { return false; @@ -2771,7 +2678,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() enterTotalStage(tr("early shape error restored within tolerance")); if(shapeStage && !earlyShapeStage && !jointShapeStarted) { jointShapeStarted = true; - shapeRoundBaseline = current.breakdown.shapeLoss; + shapeImprovementBaseline = current.breakdown.shapeLoss; // 初调已改变井储/表皮,普通形状必须在新的工作点重测其余可调参数的响应。 jacobian.clear(); reuseSensitivityForNextStage(); @@ -2840,7 +2747,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() // 第三阶段独立计数;方向不可行也消耗一次局部尝试,不能无限缩步循环。 if(!shapeStage) ++totalIterations; - // 每轮从最新 J 和当前残差重算窗口 Fisher,包含有限差分与割线更新的变化。 + // 每次从最新 J 和当前阶段残差重算 Fisher,联合步使用全局信息。 const QVector objectiveResidual = earlyShapeStage ? current.breakdown.earlyParallelResiduals : (shapeStage ? current.breakdown.shapeResiduals : current.breakdown.residualVector); @@ -2854,10 +2761,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() objectiveCoordinates.clear(); for(int i = 0; i < 73; ++i) objectiveCoordinates.append((i + 4.0) / 80.0); } - const QVector objectiveWindows = shapeStage - ? calculateAutoFitTimeWindows(objectiveResidual, m_comparisonTimeMin, m_comparisonTimeMax, - objectiveCoordinates, autoFitLogTimeWeights(objectiveCoordinates)) - : current.breakdown.timeWindows; const QVector information = buildTrustRegionFisher( objectiveJacobian, objectiveResidual, jacobianColumnValid, objectiveCoordinates); const TrustRegionFisher& global = information[kAutoFitTimeWindowCount]; @@ -2870,18 +2773,35 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() QVector selectedColumns; QVector coordinateStep; double predictedReduction = 0.0; - int selectedWindow = -1; - - if(!shapeStage) { - // 整体阶段联合求解全部有效自由列,不按窗口得分、三参数上限或共线阈值删列。 - // 边界列也参与耦合求解,是否向内移动由联合解及其边界投影决定。 - for(int column = 0; column < dimensions; ++column) { - // 仅跳过完全没有总残差响应的列,保留弱敏感列及相互相关的列。 - if(stageColumnValid[column] && global.matrix[column][column] > 0.0) - selectedColumns.append(column); + const int selectedWindow = earlyShapeStage ? 0 : -1; + + // 前期只开放当前井储或表皮;普通形状和整体 LM 都联合求解全部有效自由列。 + // 保留弱敏感、相关及边界列,让参数相互配合;窗口只保留作误差诊断。 + for(int column = 0; column < dimensions; ++column) { + if(stageColumnValid[column] && (earlyShapeStage || global.matrix[column][column] > 0.0)) + selectedColumns.append(column); + } + if(earlyShapeStage) { + double earlyStepRadius = trustRadius; + if(!earlyShapeHasImproved && selectedColumns.size() == 1) { + // 首次调整沿用小步起调,形状变差时由后面的同向扩步循环处理。 + const int column = selectedColumns[0]; + const int parameterIndex = m_enabledParamIndices[column]; + const double lower = m_parameterLower[parameterIndex]; + const double upper = m_parameterUpper[parameterIndex]; + const double smallStep = useTrustRegionLogScale(parameterIndex, lower, upper) + ? qLn(1.05) / (qLn(upper) - qLn(lower)) + : (parameterIndex == 1 ? 0.02 * qMax(0.1, qAbs(current.parameters[column])) + : 0.05 * qMax(1.0e-8, qAbs(current.parameters[column]))) / (upper - lower); + earlyStepRadius = qMin(trustRadius, smallStep); + } + if(selectedColumns.isEmpty() || !buildEarlyGapGuidedStep( + stepInformation, selectedColumns, current.coordinates, earlyGapDirection, + damping, earlyStepRadius, minimumCoordinateStep, &coordinateStep, &predictedReduction)) { + selectedColumns.clear(); } - // 当前候选已使用全局信息,停滞判断无需再逐一尝试窗口子集。 - attemptedWindows.fill(true); + } else { + // 普通调整和停滞确认共用全局联合方向,不再遍历窗口或枚举三参数子集。 globalFallbackAttempted = true; if(selectedColumns.isEmpty() || !buildTrustRegionFisherStep( global, selectedColumns, current.coordinates, damping, @@ -2889,81 +2809,6 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() selectedColumns.clear(); } } - // 形状阶段先覆盖局部窗口,再用全部有效自由列求一次全局联合步。 - while(shapeStage && selectedColumns.isEmpty()) { - selectedWindow = earlyShapeStage ? 0 : nextTrustRegionWindow( - objectiveWindows, attemptedWindows); - if(selectedWindow >= 0) { - attemptedWindows[selectedWindow] = true; - } else { - globalFallbackAttempted = true; - } - const TrustRegionFisher& local = selectedWindow >= 0 - ? information[selectedWindow] : global; - QVector proposed; - if(earlyShapeStage) { - // 前期只开放当前的井储或表皮参数。 - for(int column = 0; column < dimensions; ++column) { - if(stageColumnValid[column]) proposed.append(column); - } - } else if(selectedWindow < 0) { - // 全局步保留弱敏感及相关列,避免参数长期被窗口前三名或共线筛选排除。 - for(int column = 0; column < dimensions; ++column) { - if(stageColumnValid[column] && global.matrix[column][column] > 0.0) - proposed.append(column); - } - } else { - proposed = selectTrustRegionFisherColumns( - local, global, stageColumnValid, - current.coordinates, minimumCoordinateStep); - } - // 局部窗口至多三列,比较非空子集;全局只求完整组合,不枚举全部参数子集。 - const bool fullJointStep = !earlyShapeStage && selectedWindow < 0; - const int combinationCount = proposed.isEmpty() ? 0 : (fullJointStep ? 1 : (1 << proposed.size()) - 1); - for(int combination = 1; combination <= combinationCount; ++combination) { - QVector columns; - if(fullJointStep) columns = proposed; - else { - for(int i = 0; i < proposed.size(); ++i) { - if(combination & (1 << i)) columns.append(proposed[i]); - } - } - QVector step; - double reduction = 0.0; - double earlyStepRadius = trustRadius; - if(earlyShapeStage && !earlyShapeHasImproved && columns.size() == 1) { - // 确定方向后先小步:井储最多 1.05 倍,表皮为局部尺度的 2%。 - // 首次形状变差由后面的扩步循环处理,首次接受后恢复正常 LM 幅度。 - const int column = columns[0]; - const int parameterIndex = m_enabledParamIndices[column]; - const double lower = m_parameterLower[parameterIndex]; - const double upper = m_parameterUpper[parameterIndex]; - const double smallStep = useTrustRegionLogScale(parameterIndex, lower, upper) - ? qLn(1.05) / (qLn(upper) - qLn(lower)) - : (parameterIndex == 1 ? 0.02 * qMax(0.1, qAbs(current.parameters[column])) - : 0.05 * qMax(1.0e-8, qAbs(current.parameters[column]))) / (upper - lower); - earlyStepRadius = qMin(trustRadius, smallStep); - } - // 井储、表皮沿间距确定的方向调整;其他阶段保持原来的 LM 求步。 - const bool stepBuilt = earlyShapeStage - ? buildEarlyGapGuidedStep(stepInformation, columns, current.coordinates, earlyGapDirection, - damping, earlyStepRadius, minimumCoordinateStep, &step, &reduction) - : buildTrustRegionFisherStep(stepInformation, columns, current.coordinates, - damping, trustRadius, minimumCoordinateStep, &step, &reduction); - if(!stepBuilt) continue; - const double tolerance = 1.0e-12 * qMax(predictedReduction, reduction); - if(selectedColumns.isEmpty() || reduction > predictedReduction + tolerance || - (qAbs(reduction - predictedReduction) <= tolerance && - columns.size() < selectedColumns.size())) { - selectedColumns = columns; - coordinateStep = step; - predictedReduction = reduction; - } - } - if(earlyShapeStage || selectedWindow < 0) { - break; - } - } // 当前阶段没有可行下降步时,收缩半径并进入原有重建/收敛处理。 if(selectedColumns.isEmpty()) { @@ -2974,7 +2819,7 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() continue; } if(shapeStage) { - completeShapeSearchRound(); + completeShapeSearchStep(); --iteration; continue; } @@ -3096,6 +2941,8 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() stopReason = LM_CONSECUTIVE_FAILURES; break; } + // 确认步求解失败不代表形状已收敛,沿用有限重试后按求解失败退出。 + if(shapeStage && !earlyShapeStage && shapeConfirmationRequested) continue; if(recordIneffectiveStep()) { if(promoteSampling(false)) continue; stopReason = LM_LOCAL_OPTIMUM; @@ -3104,16 +2951,12 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() continue; } - // 普通形状步真实表现可靠时,沿同一联合方向最多扩步试算一次,不区分参数类型。 + // 普通形状步真实改善后,沿同一联合方向最多扩步一次,不再用预测兑现比例拦截。 // 扩步只按整体形状验收,优于原步才替换,否则保留原候选。 if(shapeStage && !earlyShapeStage && acceptable(candidate, current) && processPauseAndStop()) { - const double ordinaryEnergy = 0.5 * trustRegionSquaredNorm(objectiveResidual); - const double ordinaryReduction = ordinaryEnergy - 0.5 * trustRegionSquaredNorm(candidate.breakdown.shapeResiduals); - const double predictionFloor = qMax(1.0e-14, ordinaryEnergy * 1.0e-8); QVector expandedStep; double expandedPrediction = 0.0; - if(predictedReduction > predictionFloor && ordinaryReduction / predictedReduction > 0.75 && - buildExpandedTrustRegionStep(stepInformation, current.coordinates, coordinateStep, + if(buildExpandedTrustRegionStep(stepInformation, current.coordinates, coordinateStep, maximumTrustRadius, &expandedStep, &expandedPrediction)) { writeTraceRow(m_currentIteration, -1, "shape_step_base", candidate.parameters, candidate.fitness, true, candidate.elapsedMs, "eligible_for_expansion", &candidate.breakdown); @@ -3291,8 +3134,8 @@ StopReasonLM nmCalculationAutoFitLM::runTrustRegionFitting() m_currentIteration = completedIterations - 1; } restoreEvaluationState(current); - emit logMessageGenerated(tr("Adaptive fitting counts: %1 completed shape rounds, %2 total-stage iterations, %3 total evaluations.") - .arg(shapeRoundNumber).arg(totalIterations).arg(m_totalEvaluations)); + emit logMessageGenerated(tr("Adaptive fitting counts: %1 shape attempts, %2 total-stage iterations, %3 total evaluations.") + .arg(shapeStepCount).arg(totalIterations).arg(m_totalEvaluations)); if(m_shouldStop) { return LM_USER_STOPPED;