3. 微积分符号推导基础

微积分是 SymPy 最成熟、也最能体现“符号计算”价值的模块。与数值库只给出一个浮点数不同,SymPy 的 limit、diff、integrate、series 返回的是精确表达式:可能是分数、根式、π、e,也可能是一个含参数的闭式解。本节围绕这四类运算,讲清它们的调用方式、返回结果的解读方法,以及如何用 evalf() 或 lambdify 把符号结果转成数值做交叉验证。

一、极限:先看方向,再看是否存在

SymPy 的极限入口是 sympy.limit(expr, x, x0),默认求双侧极限。当左右极限不一致时,双侧极限返回 AccumBounds 或 zoo(复无穷),此时必须用 dir='+' 或 dir='-' 分别求单侧极限。例如 limit(sin(x)/x, x, 0) 返回 1;而 limit(1/x, x, 0) 返回 oo 并不严谨,正确做法是分别求 dir='+' 得 oo、dir='-' 得 -oo,从而判断双侧极限不存在。无穷远处的极限用 x, oo 表示,例如 limit((1+1/x)**x, x, oo) 返回 E,这是自然常数 e 的符号化定义。

二、导数:从一阶到高阶,从显式到隐式

导数用 diff(expr, x),高阶导数写成 diff(expr, x, n)。SymPy 会套用乘积法则、链式法则和商法则,返回化简后的表达式。例如对 f = x**3*exp(x) 求二阶导,得到 (x**3 + 6*x**2 + 6*x)*exp(x)。若函数以方程形式隐式给出,可用 idiff(sympy.geometry 或 sympy.core.function 中的 idiff)对 F(x,y)=0 求 dy/dx。求导结果常用于找驻点:solve(diff(f,x), x) 给出临界点,再结合二阶导符号判断极大极小。

三、积分:不定积分与定积分

不定积分用 integrate(expr, x),定积分用 integrate(expr, (x, a, b))。SymPy 会尝试初等函数、换元、分部积分和特殊函数。例如 integrate(exp(-x**2), (x, -oo, oo)) 返回 sqrt(pi),这是高斯积分的精确结果;integrate(1/x, (x, 1, E)) 返回 1。当原函数无法用初等函数表示时,SymPy 可能返回 Integral(...) 未求值对象,此时可用 .doit() 强制求值,或改用 .evalf() 得到数值近似。定积分遇到奇点时应拆分区间或加 conds='none' 观察条件收敛性。

四、级数展开:泰勒、洛朗与渐近

级数用 series(expr, x, x0, n),表示在 x0 处展开到 O(x**n)。例如 series(sin(x), x, 0, 8) 返回 x - x**3/6 + x**5/120 - x**7/5040 + O(x**8)。若展开点存在极点,SymPy 会自动给出洛朗级数(含负幂项),例如 series(exp(x)/x, x, 0, 3) 返回 1/x + 1 + x/2 + O(x**2)。去掉余项用 .removeO(),把级数转成普通多项式便于后续代入或绘图。

符号推导 → 精确结果 → 数值验证 的闭环 符号计算(SymPy) limit() sin(x)/x → 1 (1+1/x)^x → E diff() x³eˣ 二阶导 → (x³+6x²+6x)eˣ integrate() ∫e^(−x²)dx (−∞,∞) → √π series() sin(x) 展开到 O(x⁸) → x−x³/6+x⁵/120−… 精确符号结果 分数 / 根式 / π / e 含参数闭式解 O(·) 余项 Integral 未求值对象 可 .removeO() / .doit() 保留结构信息 数值验证 evalf(n) √π → 1.7724538509 E → 2.7182818285 lambdify() 转 NumPy 函数 批量采样绘图 数值积分对照 quad 与 √π 比对 误差 < 1e−10 级数截断误差 x=0.5 时余项量级 判断展开阶数是否够 不一致时回查假设、分支与奇点

五、符号结果与数值近似的对比方法

符号结果的价值在于“精确”,但工程上常需要数值确认。最直接的方式是 expr.evalf(15),把 sqrt(pi) 变成 1.77245385090552。若要对整条表达式批量求值,用 lambdify(x, expr, 'numpy') 生成可调用函数,再传入数组。对比时建议固定一个参照点,例如验证 integrate(exp(-x**2),(x,-oo,oo)) 的结果,可用 scipy.integrate.quad 在 [-10,10] 上数值积分,两者差值应在 1e-10 量级;若差异明显,优先怀疑符号推导中的分支条件或积分区间奇点,而不是数值方法本身。

六、典型函数分析案例:f(x)=x·e^(−x)

以 f = x*exp(-x) 为例走一遍完整流程。先求极限:limit(f, x, oo) 返回 0,说明右侧有水平渐近线 y=0;limit(f, x, -oo) 返回 -oo。再求导:diff(f,x) 得 (1-x)*exp(-x),令其为零得 x=1,且 x<1 时导数为正、x>1 时为负,故 x=1 是极大值点,极大值 f(1)=e^(-1)≈0.3679。接着求积分:integrate(f,(x,0,oo)) 返回 1,说明该函数在正半轴上的总面积为 1。最后做级数展开:series(f, x, 0, 5) 得 x - x² + x³/2 - x⁴/6 + O(x⁵),在 x=0.1 处截断到四阶的近似值与真值误差约 1e-7,可据此判断展开阶数是否满足精度要求。

做符号推导时,先声明符号的假设(如 x = symbols('x', real=True, positive=True)),能显著减少分段函数和绝对值分支,让 integrate 与 simplify 返回更干净的结果。
不要用 float(expr) 直接转换含 π、e 或根式的符号表达式,它可能因精度丢失或类型错误失败;统一用 evalf()。另外,integrate 返回未求值的 Integral 对象并不代表算错,而是原函数不在初等函数范围内,此时应转向数值积分或特殊函数表达。

把上述四类运算串起来,就形成“符号推导给出结构、数值验证给出可信度”的工作习惯:极限判断渐近行为,导数定位极值,积分量化累积量,级数提供局部近似,四者互相印证,才是 SymPy 微积分模块的正确用法。