# How to create CNOT from an entangling gate and arbitrary single-qubit gates?

I am working on the classical simulation of quantum circuits. I know how to efficiently implement the following entangling gate, which -- in the following paper: https://arxiv.org/pdf/1803.02118 -- was declared to be an entangling gate that is sufficient to realize arbitrary quantum circuits together with 1-qubit gates. The gate is given by

$$U_\text{entangle}=\frac{1}{2}\begin{pmatrix} ie^{i\pi/4} & e^{i\pi/4} & e^{i\pi/4} & -ie^{i\pi/4} \\ e^{-i\pi/4} & ie^{-i\pi/4} & -ie^{-i\pi/4} & e^{-i\pi/4} \\ e^{-i\pi/4} & -ie^{-i\pi/4} & ie^{-i\pi/4} & e^{-i\pi/4} \\ -ie^{i\pi/4} & e^{i\pi/4} & e^{i\pi/4} & ie^{i\pi/4} \end{pmatrix}.$$ I want to implement the CNOT gate, which is given by $$\text{CNOT}=\begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{pmatrix}.$$ I am looking for an expression of CNOT in terms of $$U_\text{entangle}$$. In the most general form, this is given by $$\text{CNOT} = A\: U_\text{entangle}\: B \:U_\text{entangle}\: C U_\text{entangle}\: D \dots U_\text{entangle} \: Z$$ where $$A,B,C,\dots,Z$$ are arbitrary combinations of 1-qubit gates. Hence even $$A$$ for instance can be composed of several 1-qubit gates.

I now want to find such matrices $$A,\dots$$ that give me a representation of $$U_\text{entangle}$$ in terms of CNOT and 1-qubit gates.

Is there an algorithm / a procedure to follow in order to determine the circuit that realizes CNOT? Is $$U_\text{entangle}$$ maybe a famous gate that has already been shown to produce CNOT with single-qubit unitaries? If the ''decomposing'' procedure doesn't follow a strict rule, are there at least any tips / rules of thumb you can give in order to find such a decomposition?

Any help is really appreciated! Many thanks in advance!

You can use the KAK decomposition method described here.

And if you are using Qiskit, this method is implemented in TwoQubitBasisDecomposer class.

z = cmath.rect(1, np.pi / 4) # e^(iπ/4)

# Your two-qubit entangling gate as numpy array:
basis_unitary = 0.5 * np.array([
[1j*z, z, z, -1j*z],
[1/z, 1j/z, -1j/z, 1/z],
[1/z, -1j/z, 1j/z, 1/z],
[-1j*z, z, z, 1j*z]
])

decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
circ = decomposer(CXGate().to_matrix())
circ.draw('mpl')

The resulting circuit: