A 2-qubit state's density matrix can be written in Pauli representation as:
$$ \rho = \frac{1}{4} \sum_{i, j = 0}^{3} c_{i, j}\; \sigma_i \otimes \sigma_j $$
For a given $\rho$, to compute the factors $c_{i, j}$, we construct the tensor product of the Pauli matrices, multiply that with the density matrix, and compute the trace, which is then the factor $c_{i, j}$. In Python (with '*' being the tensor product):
paulis = [ops.Identity(), ops.PauliX(), ops.PauliY(), ops.PauliZ()]
c = np.zeros((4, 4), dtype=np.complex64)
for i in range(4):
for j in range(4):
tprod = paulis[i] * paulis[j]
c[i][j] = np.trace(rho @ tprod)
Here is the question: To test for entanglement, add up the absolute values of the lower three diagonal elements (exclude $c_{0, 0}$). If this sum is < 1.0, then the state is separable, else it is entangled. I don't understand where this comes from? (Thanks for any pointers).
An example: For the entangled state $|\psi\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$ the density matrix $\rho$ is
$$\rho = \begin{bmatrix} \frac{1}{2} & 0 & 0 & \frac{1}{2} \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0\\ \frac{1}{2} & 0 & 0 & \frac{1}{2}\end{bmatrix}$$
with a trace of 1. However, we are talking about the Pauli representation of this matrix. The coefficient matrix computed with the Python snippet above is:
$$ c = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & -1 & 0\\ 0 & 0 & 0 & 1\end{bmatrix}$$
This corresponds to a Pauli representation of:
$$ \rho = \sigma_0 \otimes \sigma_0 + \sigma_1 \otimes \sigma_1 - \sigma_2 \otimes \sigma_2 + \sigma_3 \otimes \sigma_3 $$
We add the absolute values of elements $c_{1, 1}$, $c_{2, 2}$, $c_{3, 3}$, which is 3, which is 3.0 > 1.0, showing that the state was entangled. I don't understand where this last derivation comes from.