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

使用SymPy求解[-1,1]区间内函数极值的报错问题

报错原因与解决办法

报错原因

  1. 虚部过滤逻辑失效:原代码用sp.im(soln[i])!=0筛选复根,但SymPy求解一阶导数时,部分实际为实根的解会附带极小虚部(如-7.09593646502773 + 0.e-20*I),这一虚部不等于0,导致这些根未被过滤。后续用非严格实数做大小比较时,触发SymPy的类型错误。
  2. 函数表达式笔误:原代码将题目中的10ˣ写成了10*x,导致函数定义错误,导数计算也会偏离需求。
  3. 区间注释与需求不符:代码注释标注“0到1”,但实际需求是区间[-1,1],虽不直接引发报错,但需修正以匹配需求。

解决方法

  1. 修改复根过滤规则:判断根的虚部绝对值是否小于题目指定的阈值1×10⁻¹⁵,若满足则视为实根,提取其实部作为有效解。
  2. 修正函数表达式:将10*x改为10**x,匹配题目中的10ˣ。
  3. 统一数值形式比较:将处理后的实根转为数值后再做区间判断,避免SymPy符号对象的比较冲突。

修正后的代码

import sympy as sp
x = sp.symbols('x')

# 定义正确的函数表达式
y = x**4 - 100*x**2 + 10**x - 2

# 计算一阶导数
diff1 = sp.diff(y, x, 1)
# 计算二阶导数
diff2 = sp.diff(y, x, 2)

# 求解一阶导数的根
soln = sp.solve(diff1)

# 筛选区间[-1,1]内的有效实根
soln1 = []
threshold = 1e-15  # 题目指定的虚部忽略阈值
for root in soln:
    # 判断虚部是否可忽略
    imag_part = sp.im(root)
    if abs(imag_part) > threshold:
        continue
    # 提取实根并转为数值
    real_root = sp.re(root).evalf()
    # 判断是否在目标区间内
    if -1 <= real_root <= 1:
        soln1.append(real_root)

# 求解极大值与极小值
if soln1:
    for pt in soln1:
        # 计算二阶导数在该点的数值
        diff2_val = diff2.subs(x, pt).evalf()
        # 判断极大值
        if diff2_val < 0:
            max_val = y.subs(x, pt).evalf()
            print(f'函数在点 {pt} 处取得极大值:{max_val}')
        # 判断极小值
        elif diff2_val > 0:
            min_val = y.subs(x, pt).evalf()
            print(f'函数在点 {pt} 处取得极小值:{min_val}')
else:
    print("给定区间内无极大值或极小值。")

关键修改说明

  • 修正函数笔误:将10*x改为10**x,确保与题目中的函数一致。
  • 优化复根过滤:用abs(sp.im(root)) > threshold替代原逻辑,正确识别带有极小虚部的实根。
  • 数值化处理:将实根转为数值后再做区间判断,避免符号对象的比较错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:53:24