我正在尝试使用来自quad
的NumPy和scipy.integrate
以数字方式解决以下积分。代码有点工作,但我在结果数据中得到虚假的缺口:
任何人都知道它们为什么会发生以及如何获得正确的平滑结果?
以下是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()
答案 0 :(得分:1)
我怀疑是一个可积的奇点搞乱了四(包)的内部运作。我然后尝试(按此顺序):使用权重="柯西"在四边形;加上和减去奇点;看看告诉quadpack积分有一个难点的方法。
答案 1 :(得分:0)
所以我通过使用mpmath
方法切换到quad
库及其自己的集成tanh-sinh
来解决我的问题。我还必须拆分积分,以便数据单调。输出如下:
我不是百分之百确定为什么会这样,但它可能与数值精度和积分方法的行为有关。
这是工作代码:
#!/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()