使用来自 scipy.integrate 的四边形数值积分结果中的虚假缺口
Spurious notches in numerical integration results using quad from scipy.integrate
我正在尝试使用 NumPy 和 scipy.integrate
中的 quad
对以下积分进行数值求解。代码有点工作,但我在结果数据中得到了虚假的缺口:
有人知道它们为什么会发生以及如何获得正确的平滑结果吗?
这里是Python中的原始代码:
#!/usr/bin/env python
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as pl
numpts = 300
t_min = -4
t_max = 100
tt = np.linspace(t_min, t_max, numpts)
mean = 0. # ps
fwhm = .05 # ps
def gaussian(x, mean, fwhm):
return 1. / np.sqrt(np.pi) / fwhm * np.exp(-1. * (x - mean)**2 / fwhm**2)
def integrand(t_, t, mean, fwhm):
denum = np.sqrt(t - t_)
r = gaussian(t_, mean, fwhm) / denum
return r
def integrate(t, mean, fwhm, tmin):
return quad(integrand, tmin, t - 1e-9, args=(t, mean, fwhm))[0]
if __name__ == '__main__':
vec_int = np.vectorize(integrate)
y = vec_int(tt, mean, fwhm, tt.min())
fig = pl.figure()
ax = fig.add_subplot(111)
ax.plot(tt, y, 'bo-', mec='none')
ax.set_xlim(-5, 101)
pl.show()
我怀疑可积奇点正在扰乱 quad(pack) 的内部运作。然后我会尝试(按此顺序):在 quad 中使用 weights="cauchy";加减奇点;看看告诉quadpack积分有难点的方法
所以我通过使用 tanh-sinh
方法切换到 mpmath
库及其自身的集成 quad
解决了我的问题。我还必须拆分积分,以便数据单调。输出如下所示:
我不是 100% 确定为什么会这样,但这可能与数值精度和积分方法的行为有关。
这是工作代码:
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as pl
import mpmath as mp
numpts = 3000
t_min = -4
t_max = 100
tt = np.linspace(t_min, t_max, numpts)
mean = mp.mpf('0') # ps
fwhm = mp.mpf('.05') # ps
def gaussian(x, mean, fwhm):
return 1. / mp.sqrt(np.pi) / fwhm * mp.exp(-1. * (x - mean)**2 / fwhm**2)
def integrand(t_, t, mean, fwhm):
denum = np.sqrt(t - t_)
g = gaussian(t_, mean, fwhm)
r = g / denum
return r
def integrate(t, mean, fwhm, tmin):
t = mp.mpf(t)
tmin = mp.mpf(tmin)
# split the integral because it can only handle smooth functions
res = mp.quad(lambda t_: integrand(t_, t, mean, fwhm),
[tmin, mean],
method='tanh-sinh') + \
mp.quad(lambda t_: integrand(t_, t, mean, fwhm),
[mean, t],
method='tanh-sinh')
ans = res
return ans
if __name__ == '__main__':
mp.mp.dps = 15
mp.mp.pretty = True
vec_int = np.vectorize(integrate)
y = vec_int(tt, mean, fwhm, tt.min())
fig = pl.figure()
ax = fig.add_subplot(111)
# make sure we plot the real part
ax.plot(tt, map(mp.re, y), 'bo-', mec='none')
ax.set_xlim(-5, 101)
pl.show()
我正在尝试使用 NumPy 和 scipy.integrate
中的 quad
对以下积分进行数值求解。代码有点工作,但我在结果数据中得到了虚假的缺口:
有人知道它们为什么会发生以及如何获得正确的平滑结果吗?
这里是Python中的原始代码:
#!/usr/bin/env python
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as pl
numpts = 300
t_min = -4
t_max = 100
tt = np.linspace(t_min, t_max, numpts)
mean = 0. # ps
fwhm = .05 # ps
def gaussian(x, mean, fwhm):
return 1. / np.sqrt(np.pi) / fwhm * np.exp(-1. * (x - mean)**2 / fwhm**2)
def integrand(t_, t, mean, fwhm):
denum = np.sqrt(t - t_)
r = gaussian(t_, mean, fwhm) / denum
return r
def integrate(t, mean, fwhm, tmin):
return quad(integrand, tmin, t - 1e-9, args=(t, mean, fwhm))[0]
if __name__ == '__main__':
vec_int = np.vectorize(integrate)
y = vec_int(tt, mean, fwhm, tt.min())
fig = pl.figure()
ax = fig.add_subplot(111)
ax.plot(tt, y, 'bo-', mec='none')
ax.set_xlim(-5, 101)
pl.show()
我怀疑可积奇点正在扰乱 quad(pack) 的内部运作。然后我会尝试(按此顺序):在 quad 中使用 weights="cauchy";加减奇点;看看告诉quadpack积分有难点的方法
所以我通过使用 tanh-sinh
方法切换到 mpmath
库及其自身的集成 quad
解决了我的问题。我还必须拆分积分,以便数据单调。输出如下所示:
我不是 100% 确定为什么会这样,但这可能与数值精度和积分方法的行为有关。
这是工作代码:
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as pl
import mpmath as mp
numpts = 3000
t_min = -4
t_max = 100
tt = np.linspace(t_min, t_max, numpts)
mean = mp.mpf('0') # ps
fwhm = mp.mpf('.05') # ps
def gaussian(x, mean, fwhm):
return 1. / mp.sqrt(np.pi) / fwhm * mp.exp(-1. * (x - mean)**2 / fwhm**2)
def integrand(t_, t, mean, fwhm):
denum = np.sqrt(t - t_)
g = gaussian(t_, mean, fwhm)
r = g / denum
return r
def integrate(t, mean, fwhm, tmin):
t = mp.mpf(t)
tmin = mp.mpf(tmin)
# split the integral because it can only handle smooth functions
res = mp.quad(lambda t_: integrand(t_, t, mean, fwhm),
[tmin, mean],
method='tanh-sinh') + \
mp.quad(lambda t_: integrand(t_, t, mean, fwhm),
[mean, t],
method='tanh-sinh')
ans = res
return ans
if __name__ == '__main__':
mp.mp.dps = 15
mp.mp.pretty = True
vec_int = np.vectorize(integrate)
y = vec_int(tt, mean, fwhm, tt.min())
fig = pl.figure()
ax = fig.add_subplot(111)
# make sure we plot the real part
ax.plot(tt, map(mp.re, y), 'bo-', mec='none')
ax.set_xlim(-5, 101)
pl.show()