用于动态时间规整的矢量化循环

Vectorized loop for dynamic time wrapping

我正在尝试通过矢量化来加速 https://github.com/pierre-rouanet/dtw/blob/master/dtw.py 处的 dtw(x, y, dist=lambda x, y: norm(x - y, ord=1))) 。第一个循环很简单,但我不知道如何向量化第二个循环:

for i in range(r):
    for j in range(c):
        D[i+1, j+1] += min(D[i, j], D[i, j+1], D[i+1, j])

主要问题是,即使我迭代 i,每个 D[i+1, j+1] 都依赖于 D[i+1, j]。

是否可以对其进行矢量化,还是我必须使用 Cython?

对于形状为1000x2的x和y,原来的代码需要15s,我现在的代码需要1.8s,主要是在第二个循环中。

编辑:最小工作示例

np.random.seed(0); A = np.random.randn(4, 3)
r, c = np.array(A.shape)-1
for i in range(r):
    for j in range(c):
        A[i+1, j+1] += min(A[i, j], A[i, j+1], A[i+1, j])
A

应该给:

array([[ 1.76405235,  0.40015721,  0.97873798],
       [ 2.2408932 ,  2.2677152 , -0.57712067],
       [ 0.95008842,  0.79873121, -0.68033952],
       [ 0.4105985 ,  0.55464207,  0.77393398]])

尝试以下操作:

D[1:,1:] += np.min(np.dstack((D[:-1,:-1],D[:-1,1:],D[1:,:-1])),axis=2)

我终于做到了!解决方案是遍历对角线。指数很难得到正确的。谢谢大家!

r, c = np.array(D.shape)-1
for a in range(1, r+c):
    # We have I>=0, I<r, J>0, J<c and J-I+1=a
    I = np.arange(max(0, a-c), min(r, a))
    J = I[::-1] + a - min(r, a) - max(0, a-c)
    # We have to use two np.minimum because np.minimum takes only two args.
    D[I+1, J+1] += np.minimum(np.minimum(D[I, J], D[I, J+1]), D[I+1, J])