使用来自scipy.integrate的quad的数值积分结果中的虚假凹口

时间:2017-02-17 03:56:32

标签: python numpy scipy numerical-methods numerical-integration

我正在尝试使用来自quad的NumPy和scipy.integrate以数字方式解决以下积分。代码有点工作,但我在结果数据中得到虚假的缺口:

Output

任何人都知道它们为什么会发生以及如何获得正确的平滑结果?

以下是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()

2 个答案:

答案 0 :(得分:1)

我怀疑是一个可积的奇点搞乱了四(包)的内部运作。我然后尝试(按此顺序):使用权重="柯西"在四边形;加上和减去奇点;看看告诉quadpack积分有一个难点的方法。

答案 1 :(得分:0)

所以我通过使用mpmath方法切换到quad库及其自己的集成tanh-sinh来解决我的问题。我还必须拆分积分,以便数据单调。输出如下:

Output

我不是百分之百确定为什么会这样,但它可能与数值精度和积分方法的行为有关。

这是工作代码:

#!/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()