Exemple #1
0
def choi_map(a_var: int = 1, b_var: int = 1, c_var: int = 0) -> np.ndarray:
    """
    Produce the Choi map or one of its generalizations.

    The Choi map is a positive map on 3-by-3 matrices that is capable
    of detecting some entanglement that the transpose map is not.

    The standard Choi map defined with `a=1`, `b=1`, and `c=0` is the
    Choi matrix of the positive map defined in [1]. Many of these
    maps are capable of detecting PPT entanglement.

    :param a_var: Default integer for standard Choi map.
    :param b_var: Default integer for standard Choi map.
    :param c_var: Default integer for standard Choi map.

    References:
        [1] S. J. Cho, S.-H. Kye, and S. G. Lee,
        Linear Alebr. Appl. 171, 213
        (1992).
    """
    psi = max_entangled(3, False, False)
    return (np.diag([
        a_var + 1, c_var, b_var, b_var, a_var + 1, c_var, c_var, b_var,
        a_var + 1
    ]) - psi * psi.conj().T)
    def test_max_ent_2_0_0(self):
        """Generate maximally entangled state: `|00> + |11>`."""
        e_0, e_1 = ket(2, 0), ket(2, 1)
        expected_res = 1 * (np.kron(e_0, e_0) + np.kron(e_1, e_1))
        res = max_entangled(2, False, False)

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
    def test_max_ent_2(self):
        """Generate maximally entangled state: `1/sqrt(2) * (|00> + |11>)`."""
        e_0, e_1 = ket(2, 0), ket(2, 1)
        expected_res = 1 / np.sqrt(2) * (np.kron(e_0, e_0) + np.kron(e_1, e_1))
        res = max_entangled(2)

        bool_mat = np.isclose(res, expected_res)
        self.assertEqual(np.all(bool_mat), True)
    def test_schmidt_decomp_max_ent(self):
        """Schmidt decomposition of the 3-D maximally entangled state."""
        singular_vals, u_mat, vt_mat = schmidt_decomposition(max_entangled(3))

        expected_u_mat = np.identity(3)
        expected_vt_mat = np.identity(3)
        expected_singular_vals = 1 / np.sqrt(3) * np.array([[1], [1], [1]])

        bool_mat = np.isclose(expected_u_mat, u_mat)
        self.assertEqual(np.all(bool_mat), True)

        bool_mat = np.isclose(expected_vt_mat, vt_mat)
        self.assertEqual(np.all(bool_mat), True)

        bool_mat = np.isclose(expected_singular_vals, singular_vals)
        self.assertEqual(np.all(bool_mat), True)
def random_state_vector(dim: Union[List[int], int],
                        is_real: bool = False,
                        k_param: int = 0) -> np.ndarray:
    """Generate a random pure state vector.

    :param dim: The number of rows (and columns) of the unitary matrix.
    :param is_real: Boolean denoting whether the returned matrix has real
                    entries or not. Default is `False`.
    :param k_param: Default 0.
    :return: A `dim`-by-`dim` random unitary matrix.
    """
    # Schmidt rank plays a role.
    if 0 < k_param < np.min(dim):
        # Allow the user to enter a single number for dim.
        if isinstance(dim, int):
            dim = [dim, dim]

        # If you start with a separable state on a larger space and multiply
        # the extra `k_param` dimensions by a maximally entangled state, you
        # get a Schmidt rank `<= k_param` state.
        psi = max_entangled(k_param, True, False).toarray()

        a_param = np.random.rand(dim[0] * k_param, 1)
        b_param = np.random.rand(dim[1] * k_param, 1)

        if not is_real:
            a_param = a_param + 1j * np.random.rand(dim[0] * k_param, 1)
            b_param = b_param + 1j * np.random.rand(dim[1] * k_param, 1)

        mat_1 = np.kron(psi.conj().T, np.identity(int(np.prod(dim))))
        mat_2 = swap(
            np.kron(a_param, b_param),
            sys=[2, 3],
            dim=[k_param, dim[0], k_param, dim[1]],
        )

        ret_vec = mat_1 * mat_2
        return np.divide(ret_vec, np.linalg.norm(ret_vec))

    # Schmidt rank is full, so ignore it.
    ret_vec = np.random.rand(dim, 1)
    if not is_real:
        ret_vec = ret_vec + 1j * np.random.rand(dim, 1)
    return np.divide(ret_vec, np.linalg.norm(ret_vec))
Exemple #6
0
def reduction_map(dim: int, k: int = 1) -> np.ndarray:
    r"""
    Produce the reduction map.

    If `k = 1`, this returns the Choi matrix of the reduction map which is a
    positive map on `dim`-by-`dim` matrices. For a different value of `k`, this
    yields the Choi matrix of the map defined by:

    .. math::
        R(X) = k * \text{Tr}(X) * I - X.

    This map is :math:`k`-positive.

    :param dim: A positive integer (the dimension of the reduction map).
    :param k:  If this positive integer is provided, the script will instead
               return the Choi matrix of the following linear map:
               Phi(X) := K * Tr(X)I - X.
    :return: The reduction map.
    """
    psi = max_entangled(dim, True, False)
    return k * identity(dim ** 2) - psi * psi.conj().T
def depolarizing_channel(dim: int, param_p: int = 0) -> np.ndarray:
    """
    Produce the depolarizng channel.

    The depolarizng channel is the Choi matrix of the completely depolarizng
    channel that acts on `dim`-by-`dim` matrices.

    Produces the partially depolarizng channel `(1-P)*D + P*ID` where `D` is
    the completely depolarizing channel and `ID` is the identity channel.

    References:
        [1] Wikipedia: Quantum depolarizing channel
        https://en.wikipedia.org/wiki/Quantum_depolarizing_channel

    :param dim: The dimensionality on which the channel acts.
    :param param_p: Default 0.
    """
    # Compute the Choi matrix of the depolarizng channel.

    # Gives a sparse non-normalized state.
    psi = max_entangled(dim=dim, is_sparse=False, is_normalized=False)
    return (1 - param_p) * identity(dim ** 2) / dim + param_p * (psi * psi.conj().T)
Exemple #8
0
def isotropic(dim: int, alpha: float) -> np.ndarray:
    r"""
    Produce a isotropic state.

    Returns the isotropic state with parameter `alpha` acting on
    (`dim`-by-`dim`)-dimensional space. More specifically, the state is the
    density operator defined by `(1-alpha)*I(dim)/dim**2 + alpha*E`, where I is
    the identity operator and E is the projection onto the standard
    maximally-entangled pure state on two copies of `dim`-dimensional space.

    The isotropic state has the following form

    .. math::

        \begin{equation}
            \rho_{\alpha} = \frac{1 - \alpha}{d^2} \mathbb{I} \otimes
            \mathbb{I} + \alpha |\psi_+ \rangle \langle \psi_+ | \in
            \mathbb{C}^d \otimes \mathbb{C}^2
        \end{equation}

    where :math:`|\psi_+ \rangle = \frac{1}{\sqrt{d}} \sum_j |j \rangle \otimes
    |j \rangle` is the maximally entangled state.

    References:
        [1] Horodecki, Michał, and Paweł Horodecki.
        "Reduction criterion of separability and limits for a class of
        distillation protocols." Physical Review A 59.6 (1999): 4206.

    :param dim: The local dimension.
    :param alpha: The parameter of the isotropic state.
    :return: Isotropic state.
    """
    # Compute the isotropic state.
    psi = max_entangled(dim, True, False)
    return (1 - alpha) * identity(
        dim**2) / dim**2 + alpha * psi * psi.conj().T / dim