有效地计算1xM倍MxM时间Mx1,N次

时间:2016-10-06 12:46:13

标签: performance numpy

我需要计算N行的点积;假设每行我需要计算1xM倍MxM乘以Mx1。如果我只看一行,我会从这个计算得到1x1。我有N行,所以我想我会堆叠行,并将它提供给点积;但是我得到了NxN矩阵。我需要的结果是在对角线上,但有没有更快的方法来进行这种计算,这也不会浪费空间?理想情况下,我最终会得到一个Nx1向量,而不是NxN矩阵。

实施例

单行

r = np.array([[1,2]]).T
R = np.array([[2,2],[2,2]])

给出

[[18]]

多行

rs = np.array([[1,2],[4,4]]).T
R = np.array([[2,2],[2,2]])
print np.dot(np.dot(rs.T,R), rs)

[[ 18  48]
 [ 48 128]]

1 个答案:

答案 0 :(得分:4)

使用np.einsum和内部点积,如此 -

np.einsum('ij,ji->i',np.dot(rs.T,R),rs)

示例运行 -

In [215]: rs = np.random.rand(3,4)
     ...: R = np.random.rand(3,3)
     ...: out = np.dot(np.dot(rs.T,R), rs)
     ...: 

In [216]: np.diag(out)  # Diagonal elems is the expected o/p
Out[216]: array([ 1.11476081,  1.05112902,  0.32136029,  0.31318894])

In [217]: np.einsum('ij,ji->i',np.dot(rs.T,R),rs)
Out[217]: array([ 1.11476081,  1.05112902,  0.32136029,  0.31318894])

运行时测试 -

In [233]: rs = np.random.rand(300,400)

In [234]: R = np.random.rand(300,300)

In [235]: %timeit np.diag(np.dot(np.dot(rs.T,R), rs))# Original soln
10 loops, best of 3: 84 ms per loop

In [236]: %timeit np.einsum('ij,kj,ki->j', rs, rs, R)# @DSM's soln
10 loops, best of 3: 65.2 ms per loop

In [237]: %timeit np.einsum('ij,ji->i',np.dot(rs.T,R),rs)
10 loops, best of 3: 37.2 ms per loop