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

使用SciPy quad积分时遭遇ZeroDivisionError问题求助

问题描述

原本用SymPy做积分计算速度太慢,切换到SciPy的quad后性能提升,但运行代码时触发ZeroDivisionError。

原代码如下:

from scipy.integrate import quad
import sympy as S

x = S.Symbol('x')
y = S.Symbol('y')
xi = 0.75
a = 10; b = 10; f1 = 0.5; f2 = 0.5; f0 = f1+f2; al = -f1/f0; be = -f2/f0 
F0 = f0*(al*(x**2/a**2)*xi+be*(y*2/b**2)**xi+1)
j2 = F0.diff(y,2)
jj2 = S.lambdify([y],j2,'scipy')
J2_ = quad(jj2,-a,a)
J2 = (J2_[0]*a**2)/f0

错误信息:

File "C:\Users\Mikhail\Desktop\robpy\cyc.py", line 60, in raschet
J2_ = quad(jj2,-a,a)
File "C:\Users\Mikhail\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_quadpack_py.py", line 463, in quad
retval = _quad(func, a, b, args, full_output, epsabs, epsrel, limit,
File "C:\Users\Mikhail\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_quadpack_py.py", line 575, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
File "<lambdifygenerated-2>", line 2, in _lambdifygenerated
ZeroDivisionError: float division by zero

F0对y的二阶导数表达式为:
-0.0118585412256314*(y**2)**0.75/y**2

推测错误源于分母y²,但用SymPy直接积分S.integrate(j2,(y,-a,a))能正常得到结果-0.15。需求是支持用户输入不同初始数据,无法直接用浮点数重构F0,需要解决除零问题。

解决方案

方法1:用SymPy化简表达式后再lambdify

原二阶导数表达式可以通过SymPy化简消除分母的y²,因为(y²)^0.75 = |y|^1.5,化简后表达式变为-0.011858... / |y|^0.5,避免除零。

修改代码如下:

from scipy.integrate import quad
import sympy as S

x = S.Symbol('x')
y = S.Symbol('y')
xi = 0.75
a = 10; b = 10; f1 = 0.5; f2 = 0.5; f0 = f1+f2; al = -f1/f0; be = -f2/f0 
F0 = f0*(al*(x**2/a**2)*xi+be*(y*2/b**2)**xi+1)
j2 = F0.diff(y,2)
# 化简表达式
j2_simplified = S.simplify(j2)
jj2 = S.lambdify([y], j2_simplified, 'scipy')
J2_ = quad(jj2, -a, a)
J2 = (J2_[0]*a**2)/f0

方法2:自定义包装函数处理奇点

由于原函数在y=0处是可积奇点(SymPy能正常积分),可以写一个包装函数,当y接近0时用极限值代替,避免除零。

修改代码如下:

from scipy.integrate import quad
import sympy as S
import numpy as np

x = S.Symbol('x')
y = S.Symbol('y')
xi = 0.75
a = 10; b = 10; f1 = 0.5; f2 = 0.5; f0 = f1+f2; al = -f1/f0; be = -f2/f0 
F0 = f0*(al*(x**2/a**2)*xi+be*(y*2/b**2)**xi+1)
j2 = F0.diff(y,2)
# 计算y→0时的极限值
limit_val = float(S.limit(j2, y, 0))
# 生成原函数的lambda
jj2_raw = S.lambdify([y], j2, 'scipy')
# 包装函数处理奇点
def jj2(y_val):
    if np.abs(y_val) < 1e-10:
        return limit_val
    return jj2_raw(y_val)

J2_ = quad(jj2, -a, a)
J2 = (J2_[0]*a**2)/f0

方法3:利用SciPy quad的奇点处理参数

quad支持通过points参数指定积分区间内的奇点,让积分器专门处理该点,避免除零错误。

修改代码如下:

from scipy.integrate import quad
import sympy as S

x = S.Symbol('x')
y = S.Symbol('y')
xi = 0.75
a = 10; b = 10; f1 = 0.5; f2 = 0.5; f0 = f1+f2; al = -f1/f0; be = -f2/f0 
F0 = f0*(al*(x**2/a**2)*xi+be*(y*2/b**2)**xi+1)
j2 = F0.diff(y,2)
jj2 = S.lambdify([y], j2, 'scipy')
# 指定奇点位置为0
J2_ = quad(jj2, -a, a, points=[0])
J2 = (J2_[0]*a**2)/f0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:30:57