为什么我需要将scipy卷积乘以步长?

flvtvl50  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(55)

所以我做了一些研究,包括分析两个函数之间的卷积。我一直在使用scipy的内置卷积函数,但我得到的结果与我手动计算卷积积分时不同。
具体来说,我发现增加输入向量的分辨率也会增加卷积函数的输出,也就是说,我必须将结果缩小dx倍。
例如,我想卷积这两个函数f(x)和g(x):


的数据
在手动计算和使用scipy的内置函数之后,我得到了这些曲线:



将scipy曲线乘以一个因子dx,使两者相互重叠:



为什么会这样呢?
下面是用于绘制图的代码:

import numpy as np
import scipy as sp
from matplotlib import pyplot as plt

def func(x):
    return a/(np.pi*w*(1+((x)/w)**2))

def gauss(x,mx,o,I):
    return I*np.exp(-(((x-mx)/(o))**2))

def weightSignal(x,mx,o,I):
    return gauss(x,mx,o,I)*func(x)

I = 1
o = 0.5

a = 1
w = 1

n = 1001

xi = -1
xf = 1
x = np.linspace(2*xi,2*xf,num=n)

dx = (2*xf-2*xi)/(n-1)

f = func(x)
g = gauss(x,0,o,I)

plt.figure(0)
plt.plot(x,f,label='f(x)')
plt.plot(x,g,label='g(x)')
plt.legend()

fg = sp.signal.convolve(f,g,'same')

fgm = np.zeros((len(x),1))
for i in range(len(fgm)):
    mx = x[i]
    avg = sp.integrate.quad(weightSignal,-np.inf,np.inf,args=(mx,o,I))
    fgm[i] = avg[0]

plt.figure(1)
plt.plot(x,fg,label='Convolution Function')
plt.plot(x,fgm,label='Manual')
plt.xlim([xi, xf])
plt.legend()

plt.figure(2)
plt.plot(x,fg*dx,label='Convolution Function')
plt.plot(x,fgm,label='Manual')
plt.xlim([xi, xf])
plt.ylim([0, 1])
plt.legend()
plt.show()

字符串

cedebl8k

cedebl8k1#

fg = sp.signal.convolve(f, g, 'same')不能自动校正dx的缩放的原因是卷积的连续定义和SciPy等计算库中使用的离散实现之间的差异。

连续卷积:卷积的数学定义是一种连续运算,涉及对两个函数的乘积在所有可能值上进行积分。
离散卷积:Scipy -不,实际上 * 你通过定义一个行空间 * -离散化函数。这意味着我们只在特定点上有值。

sp.signal.convolve(f, g, 'same')的情况下,“相同”模式意味着输出将具有与输入相同的大小。然而,结果将是每个点的乘积之和,并且它不会自动考虑这些点之间的间距。
由于SciPy中的卷积是一种离散运算,因此需要明确考虑数据点之间的间距(在您的情况下为dx)。这就是为什么您需要将结果乘以dx以匹配手动计算中的缩放比例。

相关问题