如何在python中使用可变宽度的高斯函数执行卷积?

如何在python中使用可变宽度的高斯函数执行卷积?,python,signal-processing,resolution,convolution,probability-density,Python,Signal Processing,Resolution,Convolution,Probability Density,我需要使用高斯函数进行卷积,但是高斯函数的宽度需要改变。我不是在做传统的信号处理,而是需要根据我的设备的分辨率,获取我的完美概率密度函数(PDF)并“涂抹”它 例如,假设我的PDF开始时是一个尖峰/δ函数。我将把它建模为一个非常窄的高斯函数。在我的设备中运行之后,它将根据一些高斯分辨率进行涂抹。我可以使用scipy.signal卷积函数来计算 import numpy as np import matplotlib.pylab as plt import scipy.s

我需要使用高斯函数进行卷积,但是高斯函数的宽度需要改变。我不是在做传统的信号处理,而是需要根据我的设备的分辨率,获取我的完美概率密度函数(PDF)并“涂抹”它

例如,假设我的PDF开始时是一个尖峰/δ函数。我将把它建模为一个非常窄的高斯函数。在我的设备中运行之后,它将根据一些高斯分辨率进行涂抹。我可以使用scipy.signal卷积函数来计算

    import numpy as np
    import matplotlib.pylab as plt

    import scipy.signal as signal
    import scipy.stats as stats

    # Create the initial function. I model a spike
    # as an arbitrarily narrow Gaussian
    mu = 1.0 # Centroid
    sig=0.001 # Width
    original_pdf = stats.norm(mu,sig)

    x = np.linspace(0.0,2.0,1000) 
    y = original_pdf.pdf(x)
    plt.plot(x,y,label='original')


    # Create the ``smearing" function to convolve with the
    # original function.
    # I use a Gaussian, centered at 0.0 (no bias) and
    # width of 0.5
    mu_conv = 0.0 # Centroid
    sigma_conv = 0.5 # Width
    convolving_term = stats.norm(mu_conv,sigma_conv)

    xconv = np.linspace(-5,5,1000)
    yconv = convolving_term.pdf(xconv)

    convolved_pdf = signal.convolve(y/y.sum(),yconv,mode='same')

    plt.plot(x,convolved_pdf,label='convolved')
    plt.ylim(0,1.2*max(convolved_pdf))
    plt.legend()
    plt.show()
这一切都没问题。但是现在假设我的原始PDF不是尖峰函数,而是更广泛的函数。例如,一个sigma=1.0的高斯函数。现在假设我的分辨率实际上在x上变化:在x=0.5时,涂抹函数是sigma_conv=0.5的高斯函数,但在x=1.5时,涂抹函数是sigma_conv=1.5的高斯函数。假设我知道我的涂抹高斯的x依赖函数形式。天真的,我想我会把上面的线改成

    convolving_term = stats.norm(mu_conv,lambda x: 0.2*x + 0.1)
但这不起作用,因为范数函数需要的是宽度值,而不是函数。在某种意义上,我需要我的卷积函数是一个2D数组,在原始PDF中,每个点都有一个不同的涂抹高斯分布,它仍然是一个1D数组


那么,有没有一种方法可以用Python中已经定义的函数来实现这一点呢?我自己编写了一些代码来实现这一点……但我想确保我并没有重新发明轮子

提前谢谢

马特

问题,简而言之:
如何与非平稳内核进行卷积,例如,改变数据中不同位置宽度的高斯核,Python是否是用于此的现有工具

答案有点像:
很难证明是否定的,但我不认为scipy或numpy中存在使用非平稳内核执行卷积的函数。不管怎样,正如您所描述的,它实际上无法很好地进行向量化,因此您可以执行循环或编写一些自定义C代码

一个可能适用于您的技巧是,与其用位置改变内核大小,不如用反比例拉伸数据(即,在您希望高斯分布为0.5基宽的地方,将数据拉伸到2x)。这样,您可以对数据执行单个扭曲操作,即使用固定宽度的高斯函数进行标准卷积,然后将数据取消扭曲到原始比例

这种方法的优点是非常容易编写,并且完全矢量化,因此运行起来可能相当快


扭曲数据(例如,使用插值方法)会导致一些精度损失,但如果您选择在初始扭曲操作中始终扩展而不减少数据,则损失应该最小。

您的xconv“步长”
(last-first)/(length-1)
与x“步长”不同,会使宽度缩放(也就是说,SIGMA不在同一个“单元”中),你真的想要吗?“我有一些代码来做这件事,我自己写的”=>你能给我们看看这些代码吗?可能会有帮助。