def concurrence(rho: np.ndarray) -> float:
    r"""
    Calculate the concurrence of a bipartite state.

    The concurrence of a bipartite state :math:`\rho` is defined as

    .. math::
        \max(0, \lambda_1 - \lambda_2 - \lambda_3 - \lambda_4),

    where :math:`\lambda_1, \ldots, \lambda_4` are the eigenvalues in
    decreasing order of the matrix.

    References:
        [1] Wikipedia page for concurrence (quantum computing)
        https://en.wikipedia.org/wiki/Concurrence_(quantum_computing)

    :param rho: The bipartite system specified as a matrix.
    :return: The concurrence of the bipartite state :math:`\rho`.
    """
    if rho.shape != (4, 4):
        raise ValueError(
            "InvalidDim: Concurrence is only defined for bipartite"
            " systems.")

    sigma_y = pauli("Y", False)
    sigma_y_y = np.kron(sigma_y, sigma_y)

    rho_hat = np.matmul(np.matmul(sigma_y_y, rho.conj().T), sigma_y_y)

    eig_vals = np.linalg.eigvalsh(np.matmul(rho, rho_hat))
    eig_vals = np.sort(np.sqrt(eig_vals))[::-1]
    return max(0, eig_vals[0] - eig_vals[1] - eig_vals[2] - eig_vals[3])
Beispiel #2
0
    def test_pauli_3(self):
        """Pauli-Z operator with argument 3."""
        expected_res = np.array([[1, 0], [0, -1]])
        res = pauli(3)

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
Beispiel #3
0
    def test_pauli_2(self):
        """Pauli-Y operator with argument 2."""
        expected_res = np.array([[0, -1j], [1j, 0]])
        res = pauli(2)

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
Beispiel #4
0
    def test_pauli_1(self):
        """Pauli-X operator with argument 1."""
        expected_res = np.array([[0, 1], [1, 0]])
        res = pauli(1)

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
Beispiel #5
0
    def test_pauli_str_list(self):
        """Test with list of Paulis of str."""
        expected_res = np.array(
            [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]
        )
        res = pauli(["x", "x"])

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
Beispiel #6
0
    def test_pauli_int_sparse(self):
        """Pauli-I operator with argument "I"."""
        res = pauli(0, True)

        self.assertEqual(scipy.sparse.issparse(res), True)