矩阵数组的克罗内克积
Kronecker product of matrix array
我有两个矩阵数组 A 和 B,它们的形状相同:
A.shape = B.shape = (M,N,P)
我想计算沿轴 0 的克罗内克积,因此:
KP[ii,:,:] = A[ii,:,:]⊗B[ii,:,:]
有没有办法在 numpy 中不使用 for 循环来做到这一点?
谢谢!
示例:
A = np.array([ [[1,0],
[0,1]],
[[1,0],
[0,1]]
])
B = np.array([ [[1,0],
[0,-1]],
[[0,1],
[1,0]]
])
KP = np.array( [
[[1,0,0,0],
[0,-1,0,0],
[0,0,1,0],
[0,0,0,-1]],
[[0,1,0,0],
[1,0,0,0],
[0,0,0,1],
[0,0,1,0]]
] )
相当于:
KP= np.zeros( (A.shape[0],
A.shape[1]**2,
A.shape[2]**2) )
for ii in range(A.shape[0]):
KP[ii,:,:] = np.kron(A[ii,:,:],B[ii,:,:])
您可以使用 einsum
,稍加练习就非常直观,或者使用经典的重塑和广播路线
A = np.array([ [[1,0],
[0,1]],
[[1,0],
[0,1]]
])
B = np.array([ [[1,0],
[0,-1]],
[[0,1],
[1,0]]
])
i,j,k = A.shape
i,l,m = B.shape
np.einsum("ijk,ilm->ijlkm",A,B).reshape(i,j*l,k*m)
# array([[[ 1, 0, 0, 0],
# [ 0, -1, 0, 0],
# [ 0, 0, 1, 0],
# [ 0, 0, 0, -1]],
#
# [[ 0, 1, 0, 0],
# [ 1, 0, 0, 0],
# [ 0, 0, 0, 1],
# [ 0, 0, 1, 0]]])
等效的非 einsum 表达式:
(A[:,:,None,:,None]*B[:,None,:,None,:]).reshape(i,j*l,k*m)
万一有人觉得这也有用(虽然可能效率不高)。
def give_kr_prod(matrices):
#matrices list of 2 (or more in principle) matrices
while len(matrices) != 1:
sm, smf=[],[]
for ind in range(len(matrices)):
sm.append(matrices[ind])
if ind%2==1 and ind>0:
smf.append(np.kron(*sm))
sm=[]
matrices = smf
return matrices[0]
matrices = np.random.randn(8,2,2)
我有两个矩阵数组 A 和 B,它们的形状相同: A.shape = B.shape = (M,N,P)
我想计算沿轴 0 的克罗内克积,因此:
KP[ii,:,:] = A[ii,:,:]⊗B[ii,:,:]
有没有办法在 numpy 中不使用 for 循环来做到这一点?
谢谢!
示例:
A = np.array([ [[1,0],
[0,1]],
[[1,0],
[0,1]]
])
B = np.array([ [[1,0],
[0,-1]],
[[0,1],
[1,0]]
])
KP = np.array( [
[[1,0,0,0],
[0,-1,0,0],
[0,0,1,0],
[0,0,0,-1]],
[[0,1,0,0],
[1,0,0,0],
[0,0,0,1],
[0,0,1,0]]
] )
相当于:
KP= np.zeros( (A.shape[0],
A.shape[1]**2,
A.shape[2]**2) )
for ii in range(A.shape[0]):
KP[ii,:,:] = np.kron(A[ii,:,:],B[ii,:,:])
您可以使用 einsum
,稍加练习就非常直观,或者使用经典的重塑和广播路线
A = np.array([ [[1,0],
[0,1]],
[[1,0],
[0,1]]
])
B = np.array([ [[1,0],
[0,-1]],
[[0,1],
[1,0]]
])
i,j,k = A.shape
i,l,m = B.shape
np.einsum("ijk,ilm->ijlkm",A,B).reshape(i,j*l,k*m)
# array([[[ 1, 0, 0, 0],
# [ 0, -1, 0, 0],
# [ 0, 0, 1, 0],
# [ 0, 0, 0, -1]],
#
# [[ 0, 1, 0, 0],
# [ 1, 0, 0, 0],
# [ 0, 0, 0, 1],
# [ 0, 0, 1, 0]]])
等效的非 einsum 表达式:
(A[:,:,None,:,None]*B[:,None,:,None,:]).reshape(i,j*l,k*m)
万一有人觉得这也有用(虽然可能效率不高)。
def give_kr_prod(matrices):
#matrices list of 2 (or more in principle) matrices
while len(matrices) != 1:
sm, smf=[],[]
for ind in range(len(matrices)):
sm.append(matrices[ind])
if ind%2==1 and ind>0:
smf.append(np.kron(*sm))
sm=[]
matrices = smf
return matrices[0]
matrices = np.random.randn(8,2,2)