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

SymPy调用doit()后导数结果异常为0的原因咨询

Sympy链式求导subs后调用doit()结果异常问题

问题复现

首先执行以下代码实现链式求导:

from sympy import Function, symbols, diff, cos, sin
x,y = symbols('x y') 
f, g = symbols("f g", cls=Function)
g = g(x)
f = f(g)  # 定义复合函数
dfdx = diff(f, x)  # 应用链式法则

此时输出为链式求导的标准形式:Subs(Derivative(f(_xi), _xi), _xi, g(x))*Derivative(g(x), x)(即f’(g(x))·g’(x))。

接着执行替换操作:

xi = symbols('xi')
dfdx.subs([(xi, sin(x)), (f, cos(xi)),(g, sin(x))])

替换后的表达式为:Subs(Derivative(cos(xi), xi), xi, sin(x))*Derivative(sin(x), x)。

但调用doit()后结果为0:

dfdx.subs([(xi, sin(x)), (f, cos(xi)),(g, sin(x))]).doit()

这与手动计算的预期结果cos(x)*(-sin(sin(x)))不符。

问题原因

核心问题出在函数符号的覆盖和替换逻辑错误:

  1. 你最初定义f为Function类型的符号(代表任意函数),但随后执行f = f(g),这会把f从函数符号覆盖为复合函数表达式f(g(x))。
  2. 当你在subs中写(f, cos(xi))时,Sympy会把表达式f(g(x))整体替换成cos(xi),而非替换函数符号f本身。
  3. 替换后,dfdx中的Derivative(f(g(x)), x)变成Derivative(cos(xi), x)——此时cos(xi)里的xi和x是独立符号,对x求导结果自然为0,后续替换xi为sin(x)也无法改变这个结果。

解决方法

保留原始的函数符号,不要用表达式覆盖它:

from sympy import Function, symbols, diff, cos, sin
x,y = symbols('x y') 
f, g = symbols("f g", cls=Function)
g_expr = g(x)
f_expr = f(g_expr)  # 用新变量存储复合函数,保留f作为函数符号
dfdx = diff(f_expr, x)

xi = symbols('xi')
# 替换函数符号f为cos,同时替换g为sin(x)
result = dfdx.subs([(f, lambda t: cos(t)), (g, lambda t: sin(t))]).doit()
print(result)  # 输出:-sin(sin(x))*cos(x)

或者直接替换函数符号对应的表达式:

result = dfdx.subs([(f, cos), (g(x), sin(x))]).doit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 00:53:22