Python:两个具有np.convolve的高斯卷积结果函数的大小

时间:2019-02-07 21:16:47

标签: python numpy convolution gaussian

我有兴趣优化一个函数,它是两个函数的卷积。主要问题是我得到的函数完全是可缩放的,并且我不了解np.convolve的实际作用。

我写了一个小脚本,应该对两个高斯进行卷积,但是生成的高斯比输入函数要大得多。

from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
import numpy as np


# https://stackoverflow.com/questions/18088918/combining-two-gaussians-into-another-guassian
def gauss(x, p): # p[0]==mean, p[1]==stdev, p[2]==heightg, p[3]==baseline                   
    a = p[2]
    mu = p[0]
    sig = p[1]
    #base = p[3]
    return a * np.exp(-1.0 * ((x - mu)**2.0) / (2.0 * sig**2.0)) #+ base

p0 = [0, 0.3, 1] # Inital guess is a normal distribution
p02 = [0, 0.2, 0.5]


xp = np.linspace(-4, 4, 2000)
convolved = np.convolve(gauss(xp, p0),gauss(xp, p02), mode="same")


fig = plt.figure()



plt.subplot(2, 1, 1)

plt.plot(xp, gauss(xp, p0), lw=3, alpha=2.5)
plt.plot(xp, gauss(xp, p02), lw=3, alpha=2.5)
plt.xlim([-2, 2])

plt.subplot(2, 1, 2)
plt.plot(xp, gauss(xp, p0), lw=3, alpha=2.5)
plt.plot(xp, gauss(xp, p02), lw=3, alpha=2.5)
plt.plot(xp, convolved, lw=3, alpha=2.5,label="too damn high?")
plt.legend()
plt.xlim([-2, 2])

plt.tight_layout()
plt.show()

卷积后得到的高斯要高得多

Result

超出我的预期(维基百科):

convolution convolution1

1 个答案:

答案 0 :(得分:2)

您必须对两个x刻度之间的dx重新进行归一化。

Numpy用积分代替总和,但是由于函数仅采用Y值,因此它并不关心积分轴上需要手动添加的体积元素。
我也不得不处理这个问题,当您开始使用dx = 1进行操作时会很痛苦,但是突然之间,由于x轴的分布不同,您会得到错误的结果。

xp = np.linspace(-4, 4, 2000)
dx = xp[1] - xp[0]
convolved = np.convolve(gauss(xp, p0),gauss(xp, p02), mode="same") * dx

!!注意:不要将重归一化放在函数定义中。由于积分求和,因此dx仅应计数一次。如果将其放在函数中,则实际上会被计数两次,因为使用它会生成bot高斯。

enter image description here

PS:为更好地理解这一点,您可以尝试生成具有不同间距的x轴数据,而无需重新归一化,您会发现卷积的高度会有所不同(间距越小,高度越大)

fig = plt.figure()
ax = fig.add_subplot(111)
for spacing in (100,500,1000,2000):
    spacing += 1
    xp = np.linspace(-4, 4, spacing)
    dx = xp[1] - xp[0]
    convolved = np.convolve(gauss(xp, p01),gauss(xp, p02), mode="same") * dx
    ax.plot(xp, convolved, lw=3, alpha=2.5,label="spacing = {:g}".format(8/spacing))

ax.set_title("Convolution with different x spacing. With renormalization")
fig.legend()
plt.show()

enter code here enter image description here