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

Sympy牛顿法求复根报错ValueError:首个变量不能为数字

解决Sympy牛顿法求解多项式复根时的ValueError问题

错误原因

核心问题是变量名冲突:你在全局定义了符号变量x,但在newton_method函数里又用x = x0把它覆盖成了数值变量。当调用f.diff(x)时,这里的x是数值(比如第一次迭代的0),而Sympy的diff方法需要传入符号变量,因此触发ValueError: First variable cannot be a number: 0。

修复后的完整代码

import sympy as sp

# 定义符号变量
x = sp.symbols('x')

# 定义多项式
p = x**5 + 11*x**4 - 21*x**3 - 10*x**2 - 21*x - 5

# 牛顿法参数
tolerance = 1e-5
roots = []

# 修复后的牛顿法函数:迭代变量改用x_val,避免覆盖符号x
def newton_method(f, x0, tol, max_iter=100):
    x_val = x0  # 用x_val作为迭代数值变量,不与符号x冲突
    iteration = 0
    while iteration < max_iter:
        # 计算当前点的函数值和导数值
        f_val = f.subs(x, x_val)
        f_deriv_val = f.diff(x).subs(x, x_val)
        # 避免除以0的情况
        if abs(f_deriv_val) < 1e-10:
            return None
        x_next = x_val - f_val / f_deriv_val
        if abs(x_val - x_next) < tol:
            # 转换为浮点数,方便后续处理
            return float(x_next)
        x_val = x_next
        iteration += 1
    return None

# 寻找实根,同时去重
for i in range(-10, 10):  # 扩大初始值范围,避免漏根
    root = newton_method(p, i, tolerance)
    if root is not None:
        # 检查是否已经在roots列表中(考虑浮点误差)
        if not any(abs(root - r) < tolerance for r in roots):
            roots.append(root)

print("实根:", roots)

# 约简多项式求解复根
def reduce_polynomial(poly, root):
    # 用sp.div进行多项式除法,更可靠
    quotient, remainder = sp.div(poly, x - root)
    return quotient

complex_roots = []
for root in roots:
    reduced_poly = reduce_polynomial(p, root)
    # 求解约简后的多项式,获取所有根
    all_roots = sp.solve(reduced_poly, x)
    # 过滤掉已经找到的实根,只保留复根
    for r in all_roots:
        if isinstance(r, sp.ComplexNumber) or abs(r.imag) > tolerance:
            complex_roots.append(r)

# 去重复根
unique_complex_roots = []
for r in complex_roots:
    if not any(abs(r - cr) < tolerance for cr in unique_complex_roots):
        unique_complex_roots.append(r)

print("复根:", unique_complex_roots)

关键修复点说明

  1. 变量名分离:将迭代用的数值变量从x改为x_val,彻底避免与全局符号变量x冲突,这是解决报错的核心。
  2. 除以0防护:增加对导数值接近0的判断,避免牛顿法中出现除以0的异常。
  3. 实根去重:通过浮点误差判断,避免不同初始值收敛到同一个实根导致重复存储。
  4. 多项式除法优化:改用sp.div进行多项式除法,比直接除法更可靠,能自动处理余数(对于精确根余数为0)。
  5. 复根过滤与去重:过滤掉已找到的实根,同时对复根进行去重,避免重复输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:43:22