为何使用scipy.integrate.quad时出现积分发散/慢收敛提示?
Scipy quad积分提示发散/收敛过慢的原因分析
使用scipy.integrate.quad计算自定义积分integral2时收到提示:The integral is probably divergent, or slowly convergent,核心原因可从以下几点分析:
1. x=0处的奇点导致积分发散
当x趋近于0时,tan(x)≈x,代入被积函数拆解:
- 分母部分:
cos²x * tan²x = sin²x ≈x² - 分子贝塞尔函数项:
j0(r tanx)≈1,j1(R tanx)≈(R tanx)/2≈Rx/2,因此这部分比值约为(Rx/2)/x² = R/(2x) BZ项在x→0时趋近于常数(z=l/2>0,s=1,第二项sinh(tanx z)/tanx≈z=0.05,第一项趋近于0)
最终被积函数在x→0时近似为常数/x的形式,而∫0^a 1/x dx是发散积分(原函数lnx在x→0时趋向负无穷),这是触发提示的核心原因之一。
2. 积分上限靠近π/2引发的数值问题
积分上限设为(np.pi/2)-0.0274,接近π/2,此时tan(x)趋向正无穷:
B项中exp(2 tanx l)会指数爆炸,虽然后续BZ的第一项会因分母的指数项衰减,但第二项sinh(tanx z)/tanx在tanx→∞时近似为exp(tanx z)/(2 tanx),仍存在指数增长趋势- 贝塞尔函数
j0(r tanx)和j1(R tanx)会进入高频震荡区域,且震荡幅度衰减速度可能不足以让积分快速收敛,导致quad判定为“收敛过慢”
3. 数值计算中的精度隐患
- 代码中混合使用
math和mpmath库的函数(如math.tan与mpmath.j0),可能引发隐式类型转换的精度损失 - 当
tan(x)极大时,exp(2 tanx l)可能超出浮点数范围,导致数值溢出,进一步干扰积分计算
原代码
import math import numpy as np import scipy.integrate as spi import mpmath R = 0.05; l = 0.1; q0 = 200; alpha = 17.64; lambda1 = 67.9; def integral2(x, z, r): s = 0; if z > 0: s = 1 elif z == 0: s = 0.5 else: s = 0 B = ((lambda1*math.tan(x) - alpha) * math.exp(2 * math.tan(x) * l)) - ((lambda1*math.tan(x) + alpha) * math.exp((-2) * math.tan(x) * l)) BZ = ((math.cosh(z+l) * ((lambda1 * math.tan(x) * math.cosh(math.tan(x)*l)) - (alpha * math.sinh(math.tan(x)*l)))) / B) - ((math.sinh(math.tan(x)*z) * s) / math.tan(x)) result = ((mpmath.j0(r * math.tan(x)) * mpmath.j1(R * math.tan(x))) / (math.pow(math.cos(x),2) * math.pow(math.tan(x),2))) * BZ return result r = 0 resArr = []; rArr = []; while r < 1: r += 0.01 r = math.ceil(r*100)/100; res, _ = spi.quad(integral2, 0, (np.pi / 2) - 0.02741184711388415, args=(l/2, r)) resArr.append(res*R*q0/lambda1) rArr.append(r)
内容的提问来源于stack exchange,提问作者Jugennd
相关产品推荐
相关产品推荐

