6

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

卷积积分 \int_0^t

为了数值求解这个积分,我想使用numpy.convolve(). 现在,正如您在在线帮助中看到的那样,卷积是从 -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]这将是“著名的”标准线性固体。积分限制是测量的开始 t_0 = 0 和感兴趣的时刻 t。

4

4 回答 4

6

为了让它正确,我选择了以下两个函数:

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获得正确的卷积值。nc

不确定下面的解释是否有意义,但它就在这里......如果你认为卷积是沿着 y 轴镜像函数之一,然后沿着 x 轴滑动它并计算乘积的积分每个点,很容易看出,由于在定义区域之外 numpy 将它们视为用零填充,因此您有效地设置了从 0 到 t 的积分区间,因为第一个函数为零低于零,而第二个函数在 t 之上为零,因为它最初在零之下为零,但已被镜像并向右移动 t。

于 2013-04-12T16:46:54.243 回答
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 秒

于 2016-12-13T16:08:21.233 回答
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根本没有贡献)。

于 2013-04-12T08:29:11.960 回答
0

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

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

我将考虑从 time 开始在同一时间序列上定义的时间序列数据。让这两个系列是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

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

于 2021-09-28T17:56:10.120 回答