I am having hard time figuring out how the CX (controlled-NOT) gate is represented in the matrix representation.
I understood that tensor product and the identity matrix are the keys, and I understood how the matrix representation works for single-qubit matrices. For example, if we have a circuit with a quantum register q composed of 3 qubits, the operation X q[1] has the matrix representation 1
$$I_2 \otimes X \otimes I_2 = \begin{pmatrix}
0&0&1&0&0&0&0&0 \\
0&0&0&1&0&0&0&0 \\
1&0&0&0&0&0&0&0 \\
0&1&0&0&0&0&0&0 \\
0&0&0&0&0&0&1&0 \\
0&0&0&0&0&0&0&1 \\
0&0&0&0&1&0&0&0 \\
0&0&0&0&0&1&0&0 \\
\end{pmatrix}.$$
Obviously, I am aware of the matrix representation of the CX gate: $$\begin{pmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&0&1\\ 0&0&1&0\\ \end{pmatrix}$$
Taking back our quantum register q, applying CX to the second (control) and third register (target) (CX q[1], q[2]) gives us the matrix representation 2
$$I_2 \otimes CX = \begin{pmatrix}
1&0&0&0&0&0&0&0\\
0&1&0&0&0&0&0&0\\
0&0&0&1&0&0&0&0\\
0&0&1&0&0&0&0&0\\
0&0&0&0&1&0&0&0\\
0&0&0&0&0&1&0&0\\
0&0&0&0&0&0&0&1\\
0&0&0&0&0&0&1&0\\
\end{pmatrix}$$
The problem comes when we try to apply the CX gate to other pairs of qubits:
I suspect the matrix representation of
CX q[2], q[1](applying aCXgate with the third qubit of the system as control and the second qubit of the system as target) to be $I_2 \otimes CX^r$ where $$CX^r = \begin{pmatrix} 0&1&0&0\\ 1&0&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{pmatrix}$$ but I am not sure.I really don't know how
CX q[0], q[2](applying aCXgate with the first qubit of the system as control and the third qubit of the system as target) would be represented.
To summarise, my question is "how does the CX (or more generally multi-qubit gates) is represented as a matrix when there are more than 2 qubits in the system?".
1 Computed with Python and numpy:
import numpy as np
X = np.array([[0, 1], [1, 0]])
ID2 = np.identity(2)
print(np.kron(np.kron(ID2, X), X))
2 Computed with Python and numpy:
import numpy as np
CX = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
ID2 = np.identity(2)
print(np.kron(ID2, CX))