[英]python numpy.convolve to solve convolution integral with limits from 0 to t instead -t to 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()
因此,通过执行上述操作,如果a
和b
都有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
中的第一个样本对应于第一个重叠位置。 在这种情况下, 只有 a
和b
的第一个样本重叠。 所有其余的都漂浮在未定义的空间中。 numpy.convolve
用零有效地替换了这个未定义的空间,如果你设置了第二个非零值,你可以看到它:
In [9]: b[1] = 1
In [10]: plot(numpy.convolve(a, b, mode='full'))
在这种情况下,绘图的第一个值是1,与之前一样(显示b
的第二个值根本没有贡献)。
在过去的两天里,我一直在为类似的问题而苦苦挣扎。 OP 可能已经继续,但我仍然在这里展示我的分析。 以下两个来源帮助了我:
我将考虑从时间开始在同一时间序列上定义的时间序列数据 . 设这两个系列为
A
和B
。 他们的(连续)卷积是
代入和
在上面的等式中,我们得到
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.