如何利用前序导数高效计算函数在x₀处的多阶导数及兼容任意单变量函数?
问题分析
你遇到的'Add' object is not callable错误,核心原因是:第一次求导后,f从可调用的Python函数变成了SymPy的表达式对象(比如Add类型),这时候再尝试用f(x)或f(w)调用它自然会报错——表达式不是可调用的函数。下面分两部分解决你的需求:
一、正确实现复用前阶导数的多阶求导
我们需要始终操作SymPy表达式,而不是把表达式当成函数调用。每次求导都基于前一阶的导数表达式,避免重复计算原函数的高阶导数。
修正后的代码
from sympy import symbols, diff import numpy as np def deri(f, x0, N): # 初始化变量与初始表达式 x = symbols('x') current_deriv = f(x) # 将输入函数转为SymPy表达式 # 存储各阶结果,A[0]是原函数在x0处的值 results = np.zeros(N + 1) results[0] = current_deriv.subs(x, x0) for i in range(1, N + 1): # 复用前一阶导数,求当前阶导数 current_deriv = diff(current_deriv, x) # 代入x0计算结果 results[i] = current_deriv.subs(x, x0) return results
测试示例
def f(x): return x**5 + 2*x**3 # 计算x=1处的0到3阶导数 print(deri(f, 1, 3)) # 输出:[ 3. 11. 36. 120.] 对应f(1)=3, f'(1)=11, f''(1)=36, f'''(1)=120
二、支持任意单变量函数(不受变量名限制)
上面的代码假设变量是x,如果用户传入的是用y/t等其他变量的函数,就会失效。我们可以通过自动提取函数的自由变量来解决这个问题:
通用版本代码
from sympy import symbols, diff import numpy as np def deri(f, x0, N): # 生成临时符号,用来获取函数的表达式结构 temp_sym = symbols('temp') temp_expr = f(temp_sym) # 提取函数的自由变量(单变量函数,取第一个即可) var = next(iter(temp_expr.free_symbols)) # 替换临时符号为真实变量,生成初始表达式 current_deriv = temp_expr.subs(temp_sym, var) results = np.zeros(N + 1) results[0] = current_deriv.subs(var, x0) for i in range(1, N + 1): current_deriv = diff(current_deriv, var) results[i] = current_deriv.subs(var, x0) return results
测试不同变量的函数
# 用y作为变量的函数 def h(y): return y**5 + 2*y**2 # 计算y=2处的0到2阶导数 print(deri(h, 2, 2)) # 输出:[ 40. 88. 248.] 对应h(2)=40, h'(2)=88, h''(2)=248
额外提示
- 如果你的输入本身就是SymPy表达式(而非Python函数),可以跳过临时符号的步骤,直接提取表达式的
free_symbols即可。 - 该代码仅支持单变量函数,如果是多变量函数,需要额外添加变量指定逻辑,或者对
free_symbols的数量做判断。
内容的提问来源于stack exchange,提问作者Overkill123
相关产品推荐
相关产品推荐

