繁体   English   中英

python numpy.convolve 求解从 0 到 t 的卷积积分,而不是 -t 到 t

[英]python numpy.convolve to solve convolution integral with limits from 0 to t instead -t to t

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

卷积积分\int_0^t

为了在数值上求解这个积分,我想使用numpy.convolve() 现在,正如您在联机帮助中看到的那样,卷积正式从 -infinity 到 +infinity 完成,这意味着 arrays 完全相互移动以进行评估 - 这不是我需要的。 我显然需要确保选择卷积的正确部分——你能确认这是正确的方法吗,或者告诉我如何正确地做它以及(可能更重要)为什么?

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

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

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


背景信息(对于那些可能感兴趣的人)

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

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

p = [J_elastic, J_viscous, tau]这将是“著名的”标准线性固体 积分限制是测量的开始 t_0 = 0 和感兴趣的时刻 t。

为了做到这一点,我选择了以下两个功能:

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()

在此输入图像描述

因此,通过执行上述操作,如果ab都有n元素,则在c的前n元素中得到正确的卷积值。

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

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

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秒

如果有助于获得对齐的感觉,请尝试卷积一对冲动。 使用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的第二个值根本没有贡献)。

在过去的两天里,我一直在为类似的问题而苦苦挣扎。 OP 可能已经继续,但我仍然在这里展示我的分析。 以下两个来源帮助了我:

  1. 关于stackoverflow的讨论
  2. 这些笔记

我将考虑从时间开始在同一时间序列上定义的时间序列数据 . 设这两个系列为AB 他们的(连续)卷积是

代入 在上面的等式中,我们得到np.convolve(A,B)返回的内容:

你想要的是

再次进行相同的替换,我们得到

这与上面是因为负指数的A外推为零,而i > ( j + m ) B[j - i + m]为零。

如果您查看上面引用的注释,您会发现对应时间对于我们的时间序列。 列表中的下一个值将对应于 等等。 因此,正确答案将是

等于np.convolve(A,B)[0:M] ,其中M = len(A) = len(B)

请记住M*dt = T ,其中T是时间数组的最后一个元素。

免责声明:我不是程序员、数学家或工程师。 我不得不在某个地方使用卷积,并从我自己与问题的斗争中得出这些结论。 如果有人能指出,我很乐意引用任何有这种分析的书。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM