Decomposition of CNOT Gate
The CNOT gate is a conditional two-qubit gate.
This is a 4x4 matrix. In quantum circuits, it can also be rewritten as a four-armed tensor.
import numpy as np
a = np.array([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
print(a)
[[1 0 0 0]
[0 1 0 0]
[0 0 0 1]
[0 0 1 0]]
The above matrix is calculated by mapping 00,01,10,11 to the input/output states of 2 qubits when there are 2 qubits.
When dealing with input/output one qubit at a time, without inputting 2 qubits at the same time, it can be decomposed into a tensor.
b = a.reshape(2,2,2,2)
print(b)
[[[[1 0]
[0 0]]
[[0 1]
[0 0]]]
[[[0 0]
[0 1]]
[[0 0]
[1 0]]]]
We have changed from a matrix to a tensor. From here, it can be further divided into two tensors with three arms. The operations corresponding to each of the control and target bits are described as tensors, and the arms of each tensor are connected to form a tangle. I'm going to use Google's library for a moment.
!pip install tensornetwork
Requirement already satisfied: tensornetwork in /opt/conda/lib/python3.9/site-packages (0.4.6)
Requirement already satisfied: graphviz>=0.11.1 in /opt/conda/lib/python3.9/site-packages (from tensornetwork) (0.20)
Requirement already satisfied: numpy>=1.17 in /opt/conda/lib/python3.9/site-packages (from tensornetwork) (1.21.0)
Requirement already satisfied: scipy>=1.1 in /opt/conda/lib/python3.9/site-packages (from tensornetwork) (1.8.1)
Requirement already satisfied: opt-einsum>=2.3.0 in /opt/conda/lib/python3.9/site-packages (from tensornetwork) (3.3.0)
Requirement already satisfied: h5py>=2.9.0 in /opt/conda/lib/python3.9/site-packages (from tensornetwork) (3.6.0)
First, convert to a tensor object
c = tn.Node(b)
SVD with arms specified. s is automatically assigned.
U, V, trun_error = tn.split_node(c, [c[0],c[1]], [c[2],c[3]])
Tensor on top
print(U.tensor)
[[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]]
[[ 0. 0. 0. -1.]
[ 0. 0. -1. 0.]]]
Lower tensor
print(V.tensor)
[[[ 1. 0.]
[ 0. 0.]]
[[ 0. 1.]
[ 0. 0.]]
[[-0. -0.]
[-1. -0.]]
[[-0. -0.]
[-0. -1.]]]
I'll see if I can get it back to normal.
d = U@V
print(d.tensor.reshape(4,4))
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 0. 1.]
[0. 0. 1. 0.]]
We're back on track! This is a notation that is not often seen in ordinary quantum computers, but by using it, you can compute without being limited by the direction of time evolution, so use it!