假设我有两组n个向量由3xn数组V和W表示,一组n个矩阵用3x3xn数组Q表示。如何向量化操作以给我
a)范围(n)中k的n个向量Q[:,:,k]*V[:,k]
的集合
b)范围(n)中k的n个标量W[:,k].T*Q[:,:,k]*V[:,k]
的集合
这里的乘法被解释为矩阵乘法。无法理解我认为应该使用的einsum文档。任何澄清/解决方案将不胜感激。
答案 0 :(得分:3)
a)范围(n)中k的n个向量Q [:,:,k] * V [:,k]的集合
np.einsum('ijk,jk->ik', Q, v)
应生成(3,n)数组。矩阵乘积和总和超过j
。
b)n个标量的集合W [:,k] .T * Q [:,:,k] * V [:,k]表示范围(n)中的k
np.einsum('ik,ijk,jk->k', W, Q, V)
我在记忆中工作,我最好的猜测你需要什么。所以我的'ij'表达可能需要调整。但试一试,让我知道它是如何工作的。
测试
In [180]: V=W=np.arange(3*n).reshape(3,n)
In [181]: Q=np.arange(3*3*n).reshape(3,3,n)
In [182]: np.einsum('ijk,jk->ik',Q,V)
Out[182]:
array([[ 80, 107, 140, 179],
[224, 287, 356, 431],
[368, 467, 572, 683]])
In [183]: np.einsum('ik,ijk,jk',W,Q,V)
Out[183]: 28788 # summation over k
In [184]: np.einsum('ik,ijk,jk->k',W,Q,V)
Out[184]: array([ 3840, 5745, 8136, 11067])
有时将einsum
分成几个步骤会更快,因为它会使迭代空间变得太大。我认为这不是这种情况,但这就是看起来的样子。
In [185]: np.einsum('jk,jk->k',np.einsum('ik,ijk->jk',W,Q),V)
Out[185]: array([ 3840, 5745, 8136, 11067])
并使用Jaime的评论:
In [186]: np.einsum('i...,ij...,j...',W,Q,V)
Out[186]: array([ 3840, 5745, 8136, 11067])
In [187]: np.einsum('ij...,j...->i...',Q,V)
Out[187]:
array([[ 80, 107, 140, 179],
[224, 287, 356, 431],
[368, 467, 572, 683]])