如何判断牛顿法收敛性?验证初始猜测遍历代码有效性
代码有效性分析与牛顿法收敛性检查方案
一、你的代码存在的核心问题
你当前的代码逻辑依赖于newton函数返回None来判断收敛失败,但scipy.optimize.newton函数在迭代不收敛时(比如耗尽maxiter)并不会返回None——它会返回最后一次迭代的估计值,同时抛出RuntimeWarning(disp=False时不会中断程序,但警告依然存在)。因此你写的if t_end is not None: break和if t_end is None: continue完全起不到判断收敛的作用,属于无效逻辑。
二、修正后的代码实现
要实现“收敛则存储结果,不收敛则尝试下一个初始值”的需求,你可以通过以下两种可靠方式实现:
方式1:捕获收敛警告判断状态
利用scipy.newton在收敛失败时抛出RuntimeWarning的特性,通过捕获警告来判断迭代是否成功:
import warnings from scipy.optimize import newton converged_t_end = None for guess in initial_guess: # 捕获迭代过程中的所有警告 with warnings.catch_warnings(record=True) as w_list: warnings.simplefilter("always") # 调用牛顿法求解 t_end = newton( self.ray_param_eq, guess, fprime=self.ray_param_eq_prime, fprime2=self.ray_param_eq_second_prime, args=(self.c, self.k, ray.z_0, ray.y_0, ray.theta, self.A, self.B), maxiter=100, tol=1.48e-5, disp=False ) # 检查是否存在收敛失败的警告 has_failed_warning = any( issubclass(w.category, RuntimeWarning) and "Failed to converge" in str(w.message) for w in w_list ) if not has_failed_warning: converged_t_end = t_end break # 收敛成功,跳出循环 if converged_t_end is not None: # 存储收敛结果 print(f"收敛结果:{converged_t_end}") else: print("所有初始猜测值均未收敛")
方式2:手动验证残差判断收敛
直接计算迭代结果对应的函数值(残差),判断是否小于设定的精度阈值:
from scipy.optimize import newton converged_t_end = None tolerance = 1.48e-5 # 和newton函数的tol参数保持一致 for guess in initial_guess: t_end = newton( self.ray_param_eq, guess, fprime=self.ray_param_eq_prime, fprime2=self.ray_param_eq_second_prime, args=(self.c, self.k, ray.z_0, ray.y_0, ray.theta, self.A, self.B), maxiter=100, tol=tolerance, disp=False ) # 计算残差:|f(t_end)| residual = abs(self.ray_param_eq(t_end, self.c, self.k, ray.z_0, ray.y_0, ray.theta, self.A, self.B)) if residual < tolerance: converged_t_end = t_end break # 收敛成功,跳出循环 if converged_t_end is not None: # 存储收敛结果 print(f"收敛结果:{converged_t_end}") else: print("所有初始猜测值均未收敛")
三、牛顿法收敛性的通用检查方法
除了针对scipy.newton的方案,通用的收敛性判断可以从以下几个维度入手:
- 残差条件:迭代后函数的绝对值
|f(x)| < tol,这是最常用的判断标准,tol为你设定的精度阈值。 - 迭代步长条件:相邻两次迭代的解的差值
|x_{n+1} - x_n| < tol,说明解的变化已经足够小。 - 混合条件:同时满足残差和步长条件,避免单一条件出现误判(比如函数值很小但解还在大幅波动)。
- 迭代次数限制:如果迭代次数超过预设的maxiter,直接判定为收敛失败。
如果需要更精细的控制,你可以手动实现牛顿法迭代过程,全程跟踪每一步的残差、步长和迭代次数,完全自主控制收敛判断逻辑。
内容的提问来源于stack exchange,提问作者Euronymous
相关产品推荐
相关产品推荐

