Python中fsolve如何计算类似MATLAB resnorm的迭代误差
Python实现MATLAB fsolve的resnorm功能方案
结论
该需求完全可以实现,scipy.optimize的fsolve支持直接获取最终残差范数,也可以通过回调机制跟踪每一轮迭代的误差。
MATLAB中resnorm的本质是:将求解得到的根代入非线性方程组得到的残差向量的2范数,公式为resnorm = ||f(x)||₂。
1 快速获取最终resnorm
开启fsolve的full_output参数,即可直接获取求解完成后的残差向量,自行计算2范数即可得到和MATLAB一致的resnorm:
import numpy as np from scipy.optimize import fsolve # 示例非线性方程组 def func(x): return [ x[0]**2 + x[1]**2 - 4, x[0] * x[1] - 1 ] # 初始猜测值 x0 = [1, 2] # 开启full_output获取完整输出 x_sol, info, ier, mesg = fsolve(func, x0, full_output=True) # 计算resnorm:残差向量的2范数 resnorm = np.linalg.norm(info['fvec']) print(f"求解结果:{x_sol}") print(f"resnorm:{resnorm}")
2 跟踪每一轮迭代的误差
如果需要统计每一轮迭代的resnorm,可以通过fsolve的callback回调参数实现:
import numpy as np from scipy.optimize import fsolve def func(x): return [ x[0]**2 + x[1]**2 - 4, x[0] * x[1] - 1 ] # 存储每轮迭代的resnorm resnorm_history = [] def iteration_callback(x): # 计算当前迭代步的残差范数 current_res = func(x) resnorm_history.append(np.linalg.norm(current_res)) x0 = [1, 2] x_sol = fsolve(func, x0, callback=iteration_callback) print(f"求解结果:{x_sol}") print(f"每轮迭代resnorm:{resnorm_history}") print(f"最终resnorm:{resnorm_history[-1]}")
注意事项
- 若不想使用全局变量存储迭代历史,可以用闭包或类实例封装状态,避免全局命名空间污染
- 回调中计算残差使用的函数必须和传入
fsolve的目标函数完全一致,否则会出现误差计算偏差 - 回调方式得到的最终resnorm和
full_output输出的残差计算结果完全一致,可以交叉校验
内容的提问来源于stack exchange,提问作者every1
相关产品推荐
相关产品推荐

