我有一个类型的卷积积分:
为了在数字上解决这个问题,我想使用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。
答案 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()
通过执行上述操作,如果a
和b
都有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
中的第一个样本对应于第一个重叠位置。在这种情况下,仅 a
和b
的第一个样本重叠。所有其余的都漂浮在未定义的空间中。 numpy.convolve
有效地用零替换了这个未定义的空间,如果你设置了第二个非零值,你可以看到它:
In [9]: b[1] = 1
In [10]: plot(numpy.convolve(a, b, mode='full'))
在这种情况下,绘图的第一个值是1,与之前一样(显示b
的第二个值根本没有贡献。)