You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

牛顿法实验收敛阶计算MATLAB代码异常问题求助

修正牛顿法/截断牛顿法收敛阶计算问题排查与修正

问题根源分析

你的代码计算收敛阶时出现p值异常,主要有以下几个原因:

  • 笔误问题:代码第一行的typex_min是无效变量名,应为x_min=[1;1];
  • 数值稳定性问题:当迭代接近极小值点时,误差ek会趋近于机器精度,此时log(ekp/ek)或log(ek/ekm)会出现数值震荡(比如误差过小导致的下溢、比值趋近0或无穷大),直接计算对数比值会得到异常值
  • 索引与数组初始化不匹配:
    • 当k<=100时,pseq初始化长度为k,但循环仅填充length(xseq)-2个元素,剩余元素为0,拉低平均值
    • 当k>100时,xseq_new取最后101个点,循环仅生成99个收敛阶值,但pseq初始化长度为100,最后一个元素为0,同样影响结果
  • 未筛选收敛阶段数据:初始迭代阶段算法还未进入局部收敛区域,此时计算的收敛阶不具备参考性,直接取所有值的平均会导致结果偏差

修正后的代码

x_min = [1;1];
% 一次性计算所有迭代点的误差
error_seq = vecnorm(xseq - x_min, 2, 1); 
% 找到进入收敛阶段的起始索引(误差小于1e-3,可根据需求调整阈值)
conv_idx = find(error_seq < 1e-3, 1, 'first'); 

if isempty(conv_idx) || length(error_seq) - conv_idx < 3
    error('迭代未进入收敛阶段,无法计算有效收敛阶');
end

% 仅使用收敛阶段的误差数据
valid_error = error_seq(conv_idx:end);
pseq = zeros(length(valid_error)-2, 1);

for i = 2:length(valid_error)-1
    ekm = valid_error(i-1);
    ek = valid_error(i);
    ekp = valid_error(i+1);
    
    % 避免数值异常:仅当误差在合理范围内时计算收敛阶
    if ek > eps && ekm > eps && ekp/ek > eps && ek/ekm > eps
        pseq(i-1) = log(ekp/ek) / log(ek/ekm);
    else
        pseq(i-1) = NaN; % 标记无效值
    end
end

% 剔除无效值后计算平均收敛阶
pseq = pseq(~isnan(pseq));
if ~isempty(pseq)
    p = mean(pseq);
else
    error('无有效收敛阶数据');
end

关键改进点

  • 预计算误差序列:用vecnorm一次性计算所有迭代点的误差,更高效且避免重复计算
  • 筛选收敛阶段:仅使用误差足够小之后的迭代点,确保计算的是算法的局部收敛阶
  • 数值异常防护:添加误差阈值判断,避免因误差过小导致的对数计算异常,用NaN标记无效值后剔除
  • 数组长度匹配:根据有效误差序列的长度初始化pseq,避免未赋值的0元素干扰平均值计算

内容的提问来源于stack exchange,提问作者Giuliana Paradiso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:15:05