python numpy.convolve解决卷积积分,限制从0到t而不是-t到t

时间:2013-04-12 06:59:31

标签: python numpy numeric

我有一个类型的卷积积分:

convolution integral \int_0^t

为了在数字上解决这个问题,我想使用numpy.convolve()。现在,正如您在online help中看到的那样,卷积从-infinity到+ infinity正式完成,意味着数组完全相互移动以进行评估 - 这不是我需要的。我显然需要确保选择正确的卷积部分 - 你能否确认这是正确的方法,或者告诉我如何正确地做(也许更重要)为什么?

res = np.convolve(J_t, dF, mode="full")[:len(dF)]

J_t是一个分析函数,我可以根据需要评估多个点,dF是测量数据的衍生物。对于这种尝试,我选择len(J_t) = len(dF),因为根据我的理解,我不需要更多。

感谢您的想法,一如既往,感谢您的帮助!


背景资料(对于可能感兴趣的人)

如果您对此主题更熟悉,可以使用这些类型的积分来评估物体的粘弹性行为(或电压变化期间电路的响应)。对于粘弹性,J(t)是蠕变柔量函数,F(t)可以是随时间推移的偏应变,然后该积分将产生偏应力。 如果你现在有一个J(t)形式:

J_t = lambda p, t: p[0] + p[1]*N.exp(-t/p[2])

p = [J_elastic, J_viscous, tau]这将是“着名的”standard linear solid。积分限制是测量的开始t_0 = 0和感兴趣的时刻t。

3 个答案:

答案 0 :(得分:4)

为了做到对,我选择了以下两个功能:

a(t) = t
b(t) = t**2

很容易进行数学运算并发现它们在你的情况下定义的“卷积” 关于价值观:

c(t) = t**4 / 12

让我们试一试:

>>> delta = 0.001
>>> t = np.arange(1000) * delta
>>> a = t
>>> b = t**2
>>> c = np.convolve(a, b) * delta
>>> d = t**4 / 12
>>> plt.plot(np.arange(len(c)) * delta, c)
[<matplotlib.lines.Line2D object at 0x00000000025C37B8>]
>>> plt.plot(t[::50], d[::50], 'o')
[<matplotlib.lines.Line2D object at 0x000000000637AB38>]
>>> plt.show()

enter image description here

通过执行上述操作,如果ab都有n元素,则会在{{1}的第一个n元素中获得正确的卷积值}}

不确定下面的解释是否有意义,但是在这里......如果你认为卷积是沿着y轴镜像其中一个函数,那么沿着x轴滑动它并计算积分在每个点上的产品,很容易看出如何,因为在定义numpy区域之外将它们当作用零填充,你有效地设置从0到t的积分间隔,​​因为第一个函数是零以下零,第二个是零以上,因为它原来是零以下的零,但是已被镜像并向右移动。

答案 1 :(得分:1)

我正在解决同样的问题,并使用效率极低但功能正确的算法解决了这个问题:

def Jfunk(inz,t):

    c0 = inz[0]
    c1 = inz[1]
    c2 = inz[2]

    J = c0 - c1*np.exp(-t/c2)

    return J

def SLS_funk(inz, t, dl_dt):

    boltz_int = np.empty(shape=(0,))

    for i,v in enumerate(t, start=1):

        t_int = t[0:i]

        Jarg = v - t[0:i]

        J_int = Jfunk(inz,Jarg)

        dl_dt_int = dl_dt[0:i]

        inter_grand = np.multiply(J_int, dl_dt_int)

        boltz_int = np.append(boltz_int, simps (inter_grand, x=t_int) )

    return boltz_int

感谢这个问题及其答案,我能够基于上面提出的numpy卷积函数实现更好的解决方案。如果OP很好奇,我会对这两种方法进行时间比较。

对于具有20,000个时间点的SLS(三参数J函数):

使用Numpy卷积:~0.1秒

使用暴力法:~7.2秒

答案 2 :(得分:0)

如果有助于获得对齐的感觉,请尝试卷入一对冲动。使用matplotlib(使用ipython --pylab):

In [1]: a = numpy.zeros(20)
In [2]: b = numpy.zeros(20)
In [3]: a[0] = 1
In [4]: b[0] = 1
In [5]: c = numpy.convolve(a, b, mode='full')
In [6]: plot(c)

您可以从结果图中看到c中的第一个样本对应于第一个重叠位置。在这种情况下, ab的第一个样本重叠。所有其余的都漂浮在未定义的空间中。 numpy.convolve有效地用零替换了这个未定义的空间,如果你设置了第二个非零值,你可以看到它:

In [9]: b[1] = 1
In [10]: plot(numpy.convolve(a, b, mode='full'))

在这种情况下,绘图的第一个值是1,与之前一样(显示b的第二个值根本没有贡献。)

相关问题