
本文探讨了在使用 SciPy 的 quad 函数积分包含指示函数的复杂函数时可能遇到的问题,即由于 quad 的自适应性质,可能导致积分结果不准确。文章提供了问题分析,并介绍了使用 qmc_quad 函数的解决方案,该函数通过增加采样点数量来提高积分精度,并给出了详细的代码示例。
在使用 SciPy 的 quad 函数进行数值积分时,如果被积函数包含指示函数(indicator function),可能会遇到一些问题。指示函数在特定区间内取值为 1,在其他区间取值为 0,这可能导致 quad 函数的自适应积分算法失效,从而得到不准确的结果。
问题分析
scipy.integrate.quad 采用自适应求积方法,它会根据被积函数的性质动态调整采样点。如果指示函数定义的区间非常小,并且初始采样点恰好都落在指示函数值为 0 的区域,quad 可能会过早地认为积分已经收敛,从而返回不正确的结果(例如 0)。
以下代码展示了这个问题:
import numpy as np
from scipy.integrate import quad
def indac(x, xc, rad):
if xc - rad <= x <= xc + rad:
return 1
else:
return 0
phi = lambda ii, x: np.sin(ii * x)
xc = 0.1586663
rad = 0.01 * np.pi
result, _ = quad(lambda x: phi(1, x) * indac(x, xc, rad), 0., np.pi)
print(result) # 0.0
a, b = xc - rad, xc + rad
result, _ = quad(lambda x: phi(1, x) * indac(x, xc, rad), a, b)
print(result) # 0.009925887836572549在上面的代码中,直接在 [0, np.pi] 区间上积分,得到的结果是 0。但是,如果我们指定积分区间为指示函数非零的区间 [a, b],就能得到正确的结果。
解决方案:使用 qmc_quad
为了解决这个问题,可以使用 scipy.integrate.qmc_quad 函数。该函数使用拟蒙特卡洛(Quasi-Monte Carlo, QMC)方法进行积分,它通过在积分区间内均匀分布采样点来更准确地估计积分值。
以下是使用 qmc_quad 函数的示例代码:
import numpy as np
from scipy import integrate
def indac(x, xc, rad):
return (xc - rad <= x) & (x <= xc + rad)
phi = lambda ii, x: np.sin(ii * x)
xc = 0.1586663
rad = 0.01 * np.pi
# The integrand callable needs to be vectorized to evaluate
# the integrand at `n_points` points in a single call.
# Increase `n_points` for more accurate results.
res = integrate.qmc_quad(lambda x: phi(1, x) * indac(x, xc, rad),
0., np.pi, n_points=10000)
print(res)
# QMCQuadResult(integral=0.009904273812591187, standard_error=1.5619537172522532e-05代码解释
注意事项
总结
当使用 scipy.integrate.quad 积分包含指示函数的复杂函数时,可能会遇到精度问题。scipy.integrate.qmc_quad 函数提供了一种更可靠的解决方案,通过增加采样点数量来提高积分精度。在使用 qmc_quad 函数时,需要注意被积函数的向量化以及 n_points 参数的选择。
以上就是使用 SciPy quad 积分指示函数:问题与解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号