I have a block matrix with its elements as 2x2 matrices numpy array, for example
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])
I'm looking for a vectorised way(if it exists) where I could compute np.kron()
without having to loop through each of the block matrix's elements(who themselves are 2x2 matrices again). Right now I have something like
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
where tensored_seq
returns the original sequence with its block matrix element tensored and op_sum
returns the element-wise sum of all tensored matrix elements. Output for example could be
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]])]
The elements of tensored_seq
should be something like np.array([np.kron(X,X), np.kron(Y,Y), np.kron(Z,Z)])
. I'm looking for some function np.func()
or some way to vectorise this such that np.func(block_matrix, block_matrix)
would return np.array([np.kron(X,X), np.kron(Y,Y), np.kron(Z,Z)])
. Ideally, I want a vectorised way which also does
block_mat = np.array([[X, Y, Z], [X, Z, Y], [Z, Y, X]])
np.func(block_mat)
should return
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)]])
for example.