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

牛顿迭代法自定义函数陷入死循环无输出,求代码排查

牛顿迭代法死循环与变量问题排查

核心问题分析

  1. 死循环根源
    原代码的循环条件while np.absolute(xi_1) > min完全错误。牛顿迭代的终止逻辑应该是当前点的函数值足够接近0(说明找到根),或者两次迭代的差值足够小。而你判断的是迭代点本身的绝对值,目标函数的根在1.3左右,这个值的绝对值远大于1e-6,所以循环永远不会停止。

  2. eval的不合理使用
    用字符串传递函数再通过eval执行的方式,不仅存在安全风险,还容易引发变量作用域问题(之前的变量未定义报错就是这个原因)。直接传递函数对象是更简单可靠的方式。

  3. 其他细节问题

  • 硬编码初始猜测值guess=2,忽略了调用时传入的参数,逻辑冗余
  • 数值微分步长0.01过大,导数计算精度不足,可能影响迭代收敛
  • 没有处理导数接近0的情况,可能导致除以0报错

修正后的代码实现

牛顿迭代函数

import numpy as np

def fnewton(func, df_func, initial_guess, tol=1e-6):
    xi_1 = initial_guess
    n = 0
    # 终止条件:函数值绝对值小于设定的容差
    while np.abs(func(xi_1)) > tol:
        n += 1
        df_val = df_func(xi_1)
        # 避免导数为0导致除以0错误
        if np.abs(df_val) < 1e-10:
            raise ValueError("导数接近0,无法继续迭代")
        # 牛顿迭代公式
        x = xi_1 - func(xi_1) / df_val
        xi_1 = x
    print(f"根的位置:{x}")
    print(f"迭代次数:{n}")
    return x

目标函数与导数函数

def a(x):
    return np.exp(np.exp(-x)) - x**2 + x

def dadx(x):
    h = 1e-4  # 缩小步长提升数值微分精度
    return (a(x + h) - a(x)) / h

调用方式

fnewton(a, dadx, 2)

修改说明

  • 移除eval,直接传递函数对象,彻底解决变量作用域问题
  • 修正循环终止条件为判断函数值绝对值,符合牛顿迭代的收敛逻辑
  • 增加导数接近0的判断,避免运行时错误
  • 使用传入的初始值作为迭代起点,逻辑更合理
  • 缩小数值微分步长,提升导数计算的准确性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:45:38