【问题标题】:Element-wise tensor product for block matrices whos elements are 2x2 matrices元素为 2x2 矩阵的块矩阵的逐元素张量积
【发布时间】:2020-03-01 15:57:13
【问题描述】:

我有一个块矩阵,其元素为 2x2 矩阵 numpy 数组,例如

X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)

block_matrix = np.array([X,Y,Z])

我正在寻找一种矢量化方式(如果存在),我可以在其中计算 np.kron() 而不必遍历块矩阵的每个元素(它们本身又是 2x2 矩阵)。现在我有类似的东西

def pl_rep_operation(matrix):

    op_sum = np.zeros((4,4), dtype=complex)
    tensored_seq = []
    for i in range(len(matrix)):
        tensored = np.kron(matrix[i], matrix[i].conj()) 
        op_sum += tensored
        tensored_seq.append(tensored)
    return op_sum, tensored_seq

其中tensored_seq 返回原始序列及其块矩阵元素张量,op_sum 返回所有张量矩阵元素的元素总和。例如输出可以是

op_sum, tensored_seq = pl_rep_operation(np.array([X,Y,Z]))
In[47]: op_sum
Out[47]: 
array([[ 1.+0.j,  0.+0.j,  0.+0.j,  2.+0.j],
       [ 0.+0.j, -1.+0.j,  0.+0.j,  0.+0.j],
       [ 0.+0.j,  0.+0.j, -1.+0.j,  0.+0.j],
       [ 2.+0.j,  0.+0.j,  0.+0.j,  1.+0.j]])

In[48]: tensored_seq
Out[48]: 
[array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]]),
 array([[ 0.+0.j, -0.+0.j, -0.+0.j,  1.+0.j],
        [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j],
        [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j],
        [ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j]]),
 array([[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
        [ 0.+0.j, -1.-0.j,  0.+0.j,  0.-0.j],
        [ 0.+0.j,  0.+0.j, -1.+0.j,  0.+0.j],
        [ 0.+0.j,  0.-0.j,  0.+0.j,  1.+0.j]])]

tensored_seq 的元素应该类似于np.array([np.kron(X,X), np.kron(Y,Y), np.kron(Z,Z)])。我正在寻找一些函数np.func() 或某种方式来矢量化它,以便np.func(block_matrix, block_matrix) 将返回np.array([np.kron(X,X), np.kron(Y,Y), np.kron(Z,Z)])。理想情况下,我想要一种矢量化的方式,它也可以

block_mat = np.array([[X, Y, Z], [X, Z, Y], [Z, Y, X]])
np.func(block_mat)

应该返回

np.array([[np.kron(X,X), np.kron(Y,Y), np.kron(Z,Z)],
          [np.kron(X,X), np.kron(Z,Z), np.kron(Y,Y)],
          [np.kron(Z,Z), np.kron(Y,Y), np.kron(X,X)]])

例如。

【问题讨论】:

  • np.kron 在它的“矢量化”中也不例外,我刚刚在最近的一个回答中证明它做了一个outer,然后是元素重新排列(重塑和转置)
  • 如果 X 是 (2,2),那么 block_matrix 是 (3,2,2)。第二个版本是 (3,3,2,2),你的伪 kron 扩展为 (3,3,4,4)。由于您没有做kron(X,Z) 之类的事情,我认为最直接的方法是只计算 3 克朗,然后从中组装目标。这对于基本的numpy 代码来说过于专业化了。

标签: python numpy


【解决方案1】:

根据我最近的回答

Why is numpy's kron so fast?

In [472]: X = np.array([[0, 1], [1, 0]], dtype=complex) 
     ...: Y = np.array([[0, -1j], [1j, 0]], dtype=complex) 
     ...: Z = np.array([[1, 0], [0, -1]], dtype=complex) 
     ...:  
     ...: block_matrix = np.array([X,Y,Z])                                                     
In [473]: block_matrix.shape                                                                   
Out[473]: (3, 2, 2)
In [474]: temp=block_matrix[:,:,:,None]*block_matrix.conj()[:,:,None,:]                        
In [475]: temp.shape                                                                           
Out[475]: (3, 2, 2, 2)                                                                         
In [477]: temp = block_matrix.ravel()                                                          
In [478]: temp = block_matrix.reshape(3,4)                                                     
In [479]: temp = temp[:,:,None]*temp.conj()[:,None,:]                                          
In [480]: temp.shape                                                                           
Out[480]: (3, 4, 4)
In [481]: nz = temp.shape                                                                      
In [482]: temp = temp.reshape(3,2,2,2,2)                                                       
In [483]: temp = temp.transpose(0,1,3,2,4).reshape(nz)                                         
In [484]: temp.shape                                                                           
Out[484]: (3, 4, 4)
In [485]: temp                                                                                 
Out[485]: 
array([[[ 0.+0.j,  0.+0.j,  0.+0.j,  1.+0.j],
        [ 0.+0.j,  0.+0.j,  1.+0.j,  0.+0.j],
        [ 0.+0.j,  1.+0.j,  0.+0.j,  0.+0.j],
        [ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j]],

       [[ 0.+0.j, -0.+0.j, -0.+0.j,  1.+0.j],
        [ 0.+0.j,  0.+0.j, -1.+0.j, -0.+0.j],
        [ 0.+0.j, -1.+0.j,  0.+0.j, -0.+0.j],
        [ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j]],

       [[ 1.+0.j,  0.+0.j,  0.+0.j,  0.+0.j],
        [ 0.+0.j, -1.-0.j,  0.+0.j,  0.-0.j],
        [ 0.+0.j,  0.+0.j, -1.+0.j,  0.+0.j],
        [ 0.+0.j,  0.-0.j,  0.+0.j,  1.+0.j]]])

与您的tensored_seq 匹配。如果放在一个函数中,它应该比你的 3 kron 更快。但我不知道它是否足以扩展。在相对复杂的任务上进行 3 次迭代的时间损失并不大。

我会尝试构造最后一个矩阵:

In [486]: res = np.array([[temp[0], temp[1], temp[2]], 
     ...:                 [temp[0], temp[2],...   

假设您想要 (3,3,4,4) 结果。这并不比构建更多的工作

np.array([[X,Y,Z],[X,Z...])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2016-06-04
    • 2016-08-11
    相关资源
    最近更新 更多