Пример #1
0
def test_partial_trace_invalid_sys_arg():
    """The `sys` argument must be either a list or int."""
    with np.testing.assert_raises(ValueError):
        rho = np.array(
            [[1 / 2, 0, 0, 1 / 2], [0, 0, 0, 0], [0, 0, 0, 0], [1 / 2, 0, 0, 1 / 2]]
        )
        partial_trace(rho, "invalid_input")
Пример #2
0
def test_partial_trace_4_by_4():
    """Test for 4-by-4 matrix."""
    test_input_mat = np.arange(1, 17).reshape(4, 4)

    pt_1 = partial_trace(test_input_mat, [1], [2, 2])
    pt_2 = partial_trace(test_input_mat, [2], [2, 2])

    expected_pt_1 = np.array([[12, 14], [20, 22]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    expected_pt_2 = np.array([[7, 11], [23, 27]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)
    def probaPlayer(self, answer, question, playerId, playerPOVM):
        '''
        Calculate the probability p(a|t) with playersId's POVMs being cvxpy vars.
        '''

        IdPOVM = answer[0] + question[0]

        if playerId == 0:
            matrix = np.eye(self.dimension)
        else:
            matrix = self.POVM_Dict["0" + IdPOVM]

        for player in range(1, self.nbJoueurs):
            IdPOVM = answer[player] + question[player]

            if player == playerId:
                matrix = np.kron(matrix, np.eye(self.dimension))
            else:
                matrix = np.kron(matrix, self.POVM_Dict[str(player) + IdPOVM])

        matrix = self.rho @ matrix
        matrix = partial_trace(matrix, [
            player + 1
            for player in range(self.nbJoueurs) if player != playerId
        ], [self.dimension for _ in range(self.nbJoueurs)])
        trace = cp.trace(
            matrix @ playerPOVM[answer[playerId] + question[playerId]])
        return trace
Пример #4
0
def primal_problem(q_a: np.ndarray, pperm: np.ndarray, num_reps: int) -> float:
    """
    Primal problem for counterfeit attack.

    As the primal problem takes longer to solve than the dual problem (as
    the variables are of larger dimension), the primal problem is only here
    for reference.

    :return: The optimal value of performing a counterfeit attack.
    """
    num_spaces = 3

    sys = list(range(1, num_spaces * num_reps))
    sys = [elem for elem in sys if elem % num_spaces != 0]

    # The dimension of each subsystem is assumed to be of dimension 2.
    dim = 2 * np.ones((1, num_spaces * num_reps)).astype(int).flatten()
    dim = dim.tolist()

    x_var = cvxpy.Variable((8**num_reps, 8**num_reps), hermitian=True)
    if num_reps == 1:
        objective = cvxpy.Maximize(
            cvxpy.trace(cvxpy.real(q_a.conj().T @ x_var)))
    else:
        objective = cvxpy.Maximize(
            cvxpy.trace(
                cvxpy.real(pperm @ q_a.conj().T @ pperm.conj().T @ x_var)))
    constraints = [
        partial_trace(x_var, sys, dim) == np.identity(2**num_reps),
        x_var >> 0,
    ]
    problem = cvxpy.Problem(objective, constraints)

    return problem.solve()
Пример #5
0
    def min_prob_outcome_a_primal(self) -> float:
        r"""
        Compute the minimal probability for calculating outcome "a".

        The primal problem for the minimal probability of "a" is given as:

        .. math::

            \begin{equation}
                \begin{aligned}
                    \text{minimize:} \quad & \langle Q_{a_1} \otimes \ldots
                                             \otimes Q_{a_n}, X \rangle \\
                \text{subject to:} \quad & \text{Tr}_{\mathcal{Y}_1 \otimes
                                            \ldots \otimes \mathcal{Y}_n}(X) =
                                            I_{\mathcal{X}_1 \otimes \ldots
                                            \otimes \mathcal{X}_n},\\
                                            & X \in \text{Pos}(\mathcal{Y}_1
                                            \otimes \mathcal{X}_1 \otimes \ldots
                                            \otimes \mathcal{Y}_n \otimes
                                            \mathcal{X}_n)
                \end{aligned}
            \end{equation}

        :return: The optimal minimal probability for obtaining outcome "a".
        """
        x_var = cvxpy.Variable((4**self._num_reps, 4**self._num_reps),
                               PSD=True)
        objective = cvxpy.Minimize(cvxpy.trace(self._q_a.conj().T @ x_var))
        constraints = [
            partial_trace(x_var, self._sys,
                          self._dim) == np.identity(2**self._num_reps)
        ]
        problem = cvxpy.Problem(objective, constraints)

        return problem.solve()
Пример #6
0
def test_partial_trace_16_by_16_subsystems_4_4():
    """Test for 16-by-16 matrix for subsystems 4 x 4."""
    test_input_mat = np.arange(1, 257).reshape(16, 16)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [4, 4])
    expected_pt_1 = np.array([[412, 416, 420, 424], [476, 480, 484, 488],
                              [540, 544, 548, 552], [604, 608, 612, 616]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [4, 4])
    expected_pt_2 = np.array([[106, 122, 138, 154], [362, 378, 394, 410],
                              [618, 634, 650, 666], [874, 890, 906, 922]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #7
0
def test_partial_trace_8_by_8():
    """Test for 8-by-8 matrix."""
    test_input_mat = np.arange(1, 65).reshape(8, 8)
    res = partial_trace(test_input_mat, [1, 2], [2, 2, 2])

    expected_res = np.array([[112, 116], [144, 148]])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #8
0
def test_partial_trace_64_by_64():
    """Test for 64-by-64 matrix."""
    test_input_mat = np.arange(1, 4097).reshape(64, 64)
    res = partial_trace(test_input_mat, [1, 2, 3], [4, 4, 4])

    expected_res = np.array([[131104]])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #9
0
def test_partial_trace_8_by_8_2():
    """Test for 8-by-8 matrix."""
    test_input_mat = np.arange(1, 65).reshape(8, 8)
    res = partial_trace(test_input_mat, [1], [2, 2, 2])

    expected_res = np.array([[38, 40, 42, 44], [54, 56, 58, 60],
                             [70, 72, 74, 76], [86, 88, 90, 92]])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #10
0
def test_partial_trace_8_by_8_3():
    """Test for 8-by-8 matrix."""
    test_input_mat = np.arange(1, 65).reshape(8, 8)
    res = partial_trace(test_input_mat, 3, [2, 2, 2])

    expected_res = np.array([[11, 15, 19, 23], [43, 47, 51, 55],
                             [75, 79, 83, 87], [107, 111, 115, 119]])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #11
0
def test_partial_trace_9_by_9_subsystems_3_3():
    """Test for 9-by-9 matrix for subsystems 3 x 3"""
    test_input_mat = np.arange(1, 82).reshape(9, 9)

    # Partial trace on first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [3, 3])
    expected_pt_1 = np.array([[93, 96, 99], [120, 123, 126], [147, 150, 153]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Partial trace on second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [3, 3])
    expected_pt_2 = np.array([[33, 42, 51], [114, 123, 132], [195, 204, 213]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Partial trace on first and second subsystems:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [3, 3])
    expected_pt_1_2 = np.array([[369]])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #12
0
def test_partial_trace_6_by_6_subsystems_3_2():
    """Test for 6-by-6 matrix for subsystems 3 x 2"""
    test_input_mat = np.arange(1, 37).reshape(6, 6)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [3, 2])
    expected_pt_1 = np.array([[45, 48], [63, 66]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [3, 2])
    expected_pt_2 = np.array([[9, 13, 17], [33, 37, 41], [57, 61, 65]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and second subsystem:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [3, 2])
    expected_pt_1_2 = np.array([[111]])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #13
0
def test_partial_trace_6_by_6_subsystems_2_3():
    """Test for 6-by-6 matrix for subsystems 2 x 3"""
    test_input_mat = np.arange(1, 37).reshape(6, 6)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [2, 3])
    expected_pt_1 = np.array([[23, 25, 27], [35, 37, 39], [47, 49, 51]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [2, 3])
    expected_pt_2 = np.array([[24, 33], [78, 87]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and second subsystem:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [2, 3])
    expected_pt_1_2 = np.array([[111]])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #14
0
def test_partial_trace_16_by_16():
    """Test for 16-by-16 matrix."""
    test_input_mat = np.arange(1, 257).reshape(16, 16)
    res = partial_trace(test_input_mat, [1, 3], [2, 2, 2, 2])

    expected_res = np.array([
        [344, 348, 360, 364],
        [408, 412, 424, 428],
        [600, 604, 616, 620],
        [664, 668, 680, 684],
    ])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #15
0
def test_partial_trace_64_by_64_2():
    """Test for 64-by-64 matrix."""
    test_input_mat = np.arange(1, 4097).reshape(64, 64)
    res = partial_trace(test_input_mat, [1, 2], [4, 4, 4])

    expected_res = np.array([
        [31216, 31232, 31248, 31264],
        [32240, 32256, 32272, 32288],
        [33264, 33280, 33296, 33312],
        [34288, 34304, 34320, 34336],
    ])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #16
0
def test_partial_trace_16_by_16_2():
    """Test for 16-by-16 matrix."""
    test_input_mat = np.arange(1, 257).reshape(16, 16)
    res = partial_trace(test_input_mat, [1, 2], [2, 2, 2, 2])

    expected_res = np.array([
        [412, 416, 420, 424],
        [476, 480, 484, 488],
        [540, 544, 548, 552],
        [604, 608, 612, 616],
    ])

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #17
0
def test_partial_trace_sys():
    """
    Specify the `sys` argument.

    By specifying the `sys` argument, you can perform the partial trace
    the first subsystem instead:
    """
    test_input_mat = np.arange(1, 17).reshape(4, 4)

    expected_res = np.array([[12, 14], [20, 22]])

    res = partial_trace(test_input_mat, 1)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #18
0
def test_partial_trace():
    """
    Standard call to partial_trace.

    By default, the partial_trace function takes the trace over the second
    subsystem.
    """
    test_input_mat = np.arange(1, 17).reshape(4, 4)

    expected_res = np.array([[7, 11], [23, 27]])

    res = partial_trace(test_input_mat)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #19
0
def test_partial_trace_sys_int_dim_int_2():
    """
    Default second subsystem.

    By default, the partial_transpose function takes the trace over
    the second subsystem.
    """
    test_input_mat = np.arange(1, 17).reshape(4, 4)

    expected_res = 34

    res = partial_trace(test_input_mat, 2, 1)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #20
0
def test_partial_trace_sys_int_dim_int_2():
    """
    Default second subsystem.

    By default, the partial_transpose function takes the trace over
    the second subsystem.
    """
    test_input_mat = np.array(
        [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
    )

    expected_res = 34

    res = partial_trace(test_input_mat, 2, 1)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #21
0
def test_partial_trace():
    """
    Standard call to partial_trace.

    By default, the partial_trace function takes the trace over the second
    subsystem.
    """
    test_input_mat = np.array(
        [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
    )

    expected_res = np.array([[7, 11], [23, 27]])

    res = partial_trace(test_input_mat)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #22
0
def test_partial_trace_sys():
    """
    Specify the `sys` argument.

    By specifying the `sys` argument, you can perform the partial trace
    the first subsystem instead:
    """
    test_input_mat = np.array(
        [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
    )

    expected_res = np.array([[12, 14], [20, 22]])

    res = partial_trace(test_input_mat, 1)

    bool_mat = np.isclose(expected_res, res)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #23
0
def partial_trace_cvx(rho, sys=None, dim=None):
    """
    Perform the partial trace on a :code:`cvxpy` variable.

    Adapted from [CVXPtrace]_.

    References
    ==========
    .. [CVXPtrace] Partial trace for CVXPY variables
        https://github.com/cvxgrp/cvxpy/issues/563

    :param rho: A square matrix.
    :param sys: Scalar or vector specifying the size of the subsystems.
    :param dim: Dimension of the subsystems. If :code:`None`, all dimensions
                are assumed to be equal.
    :return: The partial trace of matrix :code:`input_mat`.
    """
    rho_np = expr_as_np_array(rho)
    traced_rho = partial_trace(rho_np, sys, dim)
    traced_rho = np_array_as_expr(traced_rho)
    return traced_rho
Пример #24
0
def test_partial_trace_8_by_8():
    """Test for 8-by-8 matrix."""
    test_input_mat = np.arange(1, 65).reshape(8, 8)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [2, 2, 2])
    expected_pt_1 = np.array([[38, 40, 42, 44], [54, 56, 58, 60],
                              [70, 72, 74, 76], [86, 88, 90, 92]])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [2, 2, 2])
    expected_pt_2 = np.array([[20, 22, 28, 30], [36, 38, 44, 46],
                              [84, 86, 92, 94], [100, 102, 108, 110]])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out third subsystem:
    pt_3 = partial_trace(test_input_mat, [3], [2, 2, 2])
    expected_pt_3 = np.array([[11, 15, 19, 23], [43, 47, 51, 55],
                              [75, 79, 83, 87], [107, 111, 115, 119]])
    bool_mat = np.isclose(expected_pt_3, pt_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and second subsystem:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [2, 2, 2])
    expected_pt_1_2 = np.array([[112, 116], [144, 148]])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and third subsystem:
    pt_1_3 = partial_trace(test_input_mat, [1, 3], [2, 2, 2])
    expected_pt_1_3 = np.array([[94, 102], [158, 166]])
    bool_mat = np.isclose(expected_pt_1_3, pt_1_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second and third subsystem:
    pt_2_3 = partial_trace(test_input_mat, [2, 3], [2, 2, 2])
    expected_pt_2_3 = np.array([[58, 74], [186, 202]])
    bool_mat = np.isclose(expected_pt_2_3, pt_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #25
0
def entanglement_of_formation(rho: np.ndarray,
                              dim: Union[List[int], int] = None) -> float:
    r"""
    Compute entanglement-of-formation of a bipartite quantum state [WikEOF]_.

    Entanglement-of-formation is the entropy of formation of the bipartite
    quantum state :code:`rho`. Note that this function currently only supports
    :code:`rho` being a pure state or a 2-qubit state: it is not known how to
    compute the entanglement-of-formation of higher-dimensional mixed states.

    This function was adapted from QETLAB.

    Examples
    ==========

    Compute the entanglement-of-formation of a Bell state.

    Let :math:`u = \frac{1}{\sqrt{2}} \left(|00\rangle + |11\rangle \right)`
    and let

    .. math::
        \rho = uu^* = \frac{1}{2}\begin{pmatrix}
                                    1 & 0 & 0 & 1 \\
                                    0 & 0 & 0 & 0 \\
                                    0 & 0 & 0 & 0 \\
                                    1 & 0 & 0 & 1
                                 \end{pmatrix}.

    The entanglement-of-formation of :math:`\rho` is equal to 1.

    >>> from toqito.state_props import entanglement_of_formation
    >>> from toqito.states import bell
    >>>
    >>> u_vec = bell(0)
    >>> rho = u_vec * u_vec.conj().T
    >>> entanglement_of_formation(rho)
    1

    References
    ==========
    .. [WikEOF] Quantiki: Entanglement-of-formation
        https://www.quantiki.org/wiki/entanglement-formation

    :param rho: A matrix or vector.
    :param dim: The default has both subsystems of equal dimension.
    :return: A value between 0 and 1 that corresponds to the
             entanglement-of-formation of :code:`rho`.
    """
    dim_x, dim_y = rho.shape
    round_dim = int(np.round(np.sqrt(max(dim_x, dim_y))))
    eps = np.finfo(float).eps

    if dim is None:
        dim = round_dim

    # User can specify dimension as integer.
    if isinstance(dim, int):
        dim = np.array([dim, max(dim_x, dim_y) / dim], dtype=int)
        if abs(dim[1] - np.round(dim[1])) >= 2 * max(dim_x, dim_y) * eps:
            raise ValueError("Invalid dimension: If `dim` is provided as a "
                             "scalar, `dim` must evenly divide `len(rho)`.")
        dim[1] = np.round(dim[1])

    if np.prod(dim) != max(dim_x, dim_y):
        raise ValueError("Invalid dimension: Please provide local dimensions "
                         "that match the size of `rho`.")

    # If :code:`rho` is a rank-1 density matrix, turn it into a vector instead
    # so we can compute the entanglement-of-formation easily.
    tmp_rho = scipy.linalg.orth(rho)
    if dim_x == dim_y and tmp_rho.shape[1] == 1:
        rho = tmp_rho
        dim_y = 1

    # Start computing entanglement-of-formation.
    if min(dim_x, dim_y) == 1:
        rho = rho[:]
        return von_neumann_entropy(partial_trace(rho * rho.conj().T, 2, dim))

    # Case: :code:`rho` is a density matrix.
    if dim_x == dim_y:
        # In the two-qubit case, we know how to compute the
        # entanglement-of-formation exactly.
        if dim_x == 4:
            rho_c = concurrence(rho)

            rho_c1 = (1 + np.sqrt(1 - rho_c**2)) / 2
            rho_c2 = (1 - np.sqrt(1 - rho_c**2)) / 2

            rho_c1_log2 = 0 if rho_c1 == 0 else np.log2(rho_c1)
            rho_c2_log2 = 0 if rho_c2 == 0 else np.log2(rho_c2)

            return -rho_c1 * rho_c1_log2 - rho_c2 * rho_c2_log2
        raise ValueError(
            "Invalid dimension: It is presently only known how to compute "
            "the entanglement-of-formation for two-qubit states and pure "
            "states.")
    raise ValueError("Invalid dimension: `rho` must be either a vector or "
                     "square matrix.")
Пример #26
0
def test_partial_trace_non_square_matrix_dim_2():
    """Matrix must be square for partial trace."""
    with np.testing.assert_raises(ValueError):
        rho = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
        partial_trace(rho, 2, [2])
Пример #27
0
def test_partial_trace_64_by_64_subsystems_4_4_4():
    """Test for 64-by-64 matrix for subsystems 4 x 4 x 4."""
    test_input_mat = np.arange(1, 4097).reshape(64, 64)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [4, 4, 4])
    expected_pt_1 = np.array([
        [
            6244,
            6248,
            6252,
            6256,
            6260,
            6264,
            6268,
            6272,
            6276,
            6280,
            6284,
            6288,
            6292,
            6296,
            6300,
            6304,
        ],
        [
            6500,
            6504,
            6508,
            6512,
            6516,
            6520,
            6524,
            6528,
            6532,
            6536,
            6540,
            6544,
            6548,
            6552,
            6556,
            6560,
        ],
        [
            6756,
            6760,
            6764,
            6768,
            6772,
            6776,
            6780,
            6784,
            6788,
            6792,
            6796,
            6800,
            6804,
            6808,
            6812,
            6816,
        ],
        [
            7012,
            7016,
            7020,
            7024,
            7028,
            7032,
            7036,
            7040,
            7044,
            7048,
            7052,
            7056,
            7060,
            7064,
            7068,
            7072,
        ],
        [
            7268,
            7272,
            7276,
            7280,
            7284,
            7288,
            7292,
            7296,
            7300,
            7304,
            7308,
            7312,
            7316,
            7320,
            7324,
            7328,
        ],
        [
            7524,
            7528,
            7532,
            7536,
            7540,
            7544,
            7548,
            7552,
            7556,
            7560,
            7564,
            7568,
            7572,
            7576,
            7580,
            7584,
        ],
        [
            7780,
            7784,
            7788,
            7792,
            7796,
            7800,
            7804,
            7808,
            7812,
            7816,
            7820,
            7824,
            7828,
            7832,
            7836,
            7840,
        ],
        [
            8036,
            8040,
            8044,
            8048,
            8052,
            8056,
            8060,
            8064,
            8068,
            8072,
            8076,
            8080,
            8084,
            8088,
            8092,
            8096,
        ],
        [
            8292,
            8296,
            8300,
            8304,
            8308,
            8312,
            8316,
            8320,
            8324,
            8328,
            8332,
            8336,
            8340,
            8344,
            8348,
            8352,
        ],
        [
            8548,
            8552,
            8556,
            8560,
            8564,
            8568,
            8572,
            8576,
            8580,
            8584,
            8588,
            8592,
            8596,
            8600,
            8604,
            8608,
        ],
        [
            8804,
            8808,
            8812,
            8816,
            8820,
            8824,
            8828,
            8832,
            8836,
            8840,
            8844,
            8848,
            8852,
            8856,
            8860,
            8864,
        ],
        [
            9060,
            9064,
            9068,
            9072,
            9076,
            9080,
            9084,
            9088,
            9092,
            9096,
            9100,
            9104,
            9108,
            9112,
            9116,
            9120,
        ],
        [
            9316,
            9320,
            9324,
            9328,
            9332,
            9336,
            9340,
            9344,
            9348,
            9352,
            9356,
            9360,
            9364,
            9368,
            9372,
            9376,
        ],
        [
            9572,
            9576,
            9580,
            9584,
            9588,
            9592,
            9596,
            9600,
            9604,
            9608,
            9612,
            9616,
            9620,
            9624,
            9628,
            9632,
        ],
        [
            9828,
            9832,
            9836,
            9840,
            9844,
            9848,
            9852,
            9856,
            9860,
            9864,
            9868,
            9872,
            9876,
            9880,
            9884,
            9888,
        ],
        [
            10084,
            10088,
            10092,
            10096,
            10100,
            10104,
            10108,
            10112,
            10116,
            10120,
            10124,
            10128,
            10132,
            10136,
            10140,
            10144,
        ],
    ])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:

    # Trace out third subsystem:

    # Trace out first and second subsystem:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [4, 4, 4])
    expected_pt_1_2 = np.array([
        [31216, 31232, 31248, 31264],
        [32240, 32256, 32272, 32288],
        [33264, 33280, 33296, 33312],
        [34288, 34304, 34320, 34336],
    ])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and third subsystem:
    pt_1_3 = partial_trace(test_input_mat, [1, 3], [4, 4, 4])
    expected_pt_1_3 = np.array([
        [26536, 26600, 26664, 26728],
        [30632, 30696, 30760, 30824],
        [34728, 34792, 34856, 34920],
        [38824, 38888, 38952, 39016],
    ])
    bool_mat = np.isclose(expected_pt_1_3, pt_1_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second and third subsystem:
    pt_2_3 = partial_trace(test_input_mat, [2, 3], [4, 4, 4])
    expected_pt_2_3 = np.array([
        [7816, 8072, 8328, 8584],
        [24200, 24456, 24712, 24968],
        [40584, 40840, 41096, 41352],
        [56968, 57224, 57480, 57736],
    ])
    bool_mat = np.isclose(expected_pt_2_3, pt_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first, second, and third subsystems:
    pt_1_2_3 = partial_trace(test_input_mat, [1, 2, 3], [4, 4, 4])
    expected_pt_1_2_3 = np.array([[131104]])

    bool_mat = np.isclose(expected_pt_1_2_3, pt_1_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #28
0
def test_partial_trace_16_by_16_subsystems_2_2_4():
    """Test for 16-by-16 matrix for subsystems 2 x 4."""
    test_input_mat = np.arange(1, 257).reshape(16, 16)

    # Trace out first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [2, 2, 4])
    expected_pt_1 = np.array([
        [138, 140, 142, 144, 146, 148, 150, 152],
        [170, 172, 174, 176, 178, 180, 182, 184],
        [202, 204, 206, 208, 210, 212, 214, 216],
        [234, 236, 238, 240, 242, 244, 246, 248],
        [266, 268, 270, 272, 274, 276, 278, 280],
        [298, 300, 302, 304, 306, 308, 310, 312],
        [330, 332, 334, 336, 338, 340, 342, 344],
        [362, 364, 366, 368, 370, 372, 374, 376],
    ])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [2, 2, 4])
    expected_pt_2 = np.array([
        [70, 72, 74, 76, 86, 88, 90, 92],
        [102, 104, 106, 108, 118, 120, 122, 124],
        [134, 136, 138, 140, 150, 152, 154, 156],
        [166, 168, 170, 172, 182, 184, 186, 188],
        [326, 328, 330, 332, 342, 344, 346, 348],
        [358, 360, 362, 364, 374, 376, 378, 380],
        [390, 392, 394, 396, 406, 408, 410, 412],
        [422, 424, 426, 428, 438, 440, 442, 444],
    ])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out third subsystem:
    pt_3 = partial_trace(test_input_mat, [3], [2, 2, 4])
    expected_pt_3 = np.array([[106, 122, 138, 154], [362, 378, 394, 410],
                              [618, 634, 650, 666], [874, 890, 906, 922]])
    bool_mat = np.isclose(expected_pt_3, pt_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and second subsystem:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [2, 2, 4])
    expected_pt_1_2 = np.array([
        [412, 416, 420, 424],
        [476, 480, 484, 488],
        [540, 544, 548, 552],
        [604, 608, 612, 616],
    ])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first and third subsystem:
    pt_1_3 = partial_trace(test_input_mat, [1, 3], [2, 2, 4])
    expected_pt_1_3 = np.array([[756, 788], [1268, 1300]])
    bool_mat = np.isclose(expected_pt_1_3, pt_1_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out second and third subsystem:
    pt_2_3 = partial_trace(test_input_mat, [2, 3], [2, 2, 4])
    expected_pt_2_3 = np.array([[484, 548], [1508, 1572]])
    bool_mat = np.isclose(expected_pt_2_3, pt_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #29
0
def test_partial_trace_64_by_64_subsystems_4_4_2_2():
    """Test for 64-by-64 matrix for subsystems 4 x 4 x 2 x 2."""
    test_input_mat = np.arange(1, 4097).reshape(64, 64)

    # Trace out first subsystem:
    # Trace out second subsystem:
    # Trace out third subsystem:
    # Trace out fourth subsystem:

    # Trace out first and second subsystem:
    # Trace out first and third subsystem:
    # Trace out first and fourth subsystem:

    # Trace out second and third subsystem:
    # Trace out second and fourth subsystem:

    # Trace out third and fourth subsystem:
    pt_3_4 = partial_trace(test_input_mat, [3, 4], [4, 4, 2, 2])
    expected_pt_3_4 = np.array([
        [
            394, 410, 426, 442, 458, 474, 490, 506, 522, 538, 554, 570, 586,
            602, 618, 634
        ],
        [
            1418,
            1434,
            1450,
            1466,
            1482,
            1498,
            1514,
            1530,
            1546,
            1562,
            1578,
            1594,
            1610,
            1626,
            1642,
            1658,
        ],
        [
            2442,
            2458,
            2474,
            2490,
            2506,
            2522,
            2538,
            2554,
            2570,
            2586,
            2602,
            2618,
            2634,
            2650,
            2666,
            2682,
        ],
        [
            3466,
            3482,
            3498,
            3514,
            3530,
            3546,
            3562,
            3578,
            3594,
            3610,
            3626,
            3642,
            3658,
            3674,
            3690,
            3706,
        ],
        [
            4490,
            4506,
            4522,
            4538,
            4554,
            4570,
            4586,
            4602,
            4618,
            4634,
            4650,
            4666,
            4682,
            4698,
            4714,
            4730,
        ],
        [
            5514,
            5530,
            5546,
            5562,
            5578,
            5594,
            5610,
            5626,
            5642,
            5658,
            5674,
            5690,
            5706,
            5722,
            5738,
            5754,
        ],
        [
            6538,
            6554,
            6570,
            6586,
            6602,
            6618,
            6634,
            6650,
            6666,
            6682,
            6698,
            6714,
            6730,
            6746,
            6762,
            6778,
        ],
        [
            7562,
            7578,
            7594,
            7610,
            7626,
            7642,
            7658,
            7674,
            7690,
            7706,
            7722,
            7738,
            7754,
            7770,
            7786,
            7802,
        ],
        [
            8586,
            8602,
            8618,
            8634,
            8650,
            8666,
            8682,
            8698,
            8714,
            8730,
            8746,
            8762,
            8778,
            8794,
            8810,
            8826,
        ],
        [
            9610,
            9626,
            9642,
            9658,
            9674,
            9690,
            9706,
            9722,
            9738,
            9754,
            9770,
            9786,
            9802,
            9818,
            9834,
            9850,
        ],
        [
            10634,
            10650,
            10666,
            10682,
            10698,
            10714,
            10730,
            10746,
            10762,
            10778,
            10794,
            10810,
            10826,
            10842,
            10858,
            10874,
        ],
        [
            11658,
            11674,
            11690,
            11706,
            11722,
            11738,
            11754,
            11770,
            11786,
            11802,
            11818,
            11834,
            11850,
            11866,
            11882,
            11898,
        ],
        [
            12682,
            12698,
            12714,
            12730,
            12746,
            12762,
            12778,
            12794,
            12810,
            12826,
            12842,
            12858,
            12874,
            12890,
            12906,
            12922,
        ],
        [
            13706,
            13722,
            13738,
            13754,
            13770,
            13786,
            13802,
            13818,
            13834,
            13850,
            13866,
            13882,
            13898,
            13914,
            13930,
            13946,
        ],
        [
            14730,
            14746,
            14762,
            14778,
            14794,
            14810,
            14826,
            14842,
            14858,
            14874,
            14890,
            14906,
            14922,
            14938,
            14954,
            14970,
        ],
        [
            15754,
            15770,
            15786,
            15802,
            15818,
            15834,
            15850,
            15866,
            15882,
            15898,
            15914,
            15930,
            15946,
            15962,
            15978,
            15994,
        ],
    ])
    bool_mat = np.isclose(expected_pt_3_4, pt_3_4)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first, second, and third subsystem:
    pt_1_2_3 = partial_trace(test_input_mat, [1, 2, 3], [4, 4, 2, 2])
    expected_pt_1_2_3 = np.array([[64512, 64544], [66560, 66592]])
    bool_mat = np.isclose(expected_pt_1_2_3, pt_1_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first, third, and fourth subsystem:
    pt_1_3_4 = partial_trace(test_input_mat, [1, 3, 4], [4, 4, 2, 2])
    expected_pt_1_3_4 = np.array([
        [26536, 26600, 26664, 26728],
        [30632, 30696, 30760, 30824],
        [34728, 34792, 34856, 34920],
        [38824, 38888, 38952, 39016],
    ])
    bool_mat = np.isclose(expected_pt_1_3_4, pt_1_3_4)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out first, second, third, and fourth subsystem:
    pt_1_2_3_4 = partial_trace(test_input_mat, [1, 2, 3, 4], [4, 4, 2, 2])
    expected_pt_1_2_3_4 = np.array([[131104]])
    bool_mat = np.isclose(expected_pt_1_2_3_4, pt_1_2_3_4)
    np.testing.assert_equal(np.all(bool_mat), True)
Пример #30
0
def test_partial_trace_16_by_16_subsystems_4_2_2():
    """Test for 16-by-16 matrix for subsystems 4 x 2."""
    test_input_mat = np.arange(1, 257).reshape(16, 16)

    # Trace out the first subsystem:
    pt_1 = partial_trace(test_input_mat, [1], [4, 2, 2])
    expected_pt_1 = np.array([
        [412, 416, 420, 424],
        [476, 480, 484, 488],
        [540, 544, 548, 552],
        [604, 608, 612, 616],
    ])
    bool_mat = np.isclose(expected_pt_1, pt_1)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out the second subsystem:
    pt_2 = partial_trace(test_input_mat, [2], [4, 2, 2])
    expected_pt_2 = np.array([
        [36, 38, 44, 46, 52, 54, 60, 62],
        [68, 70, 76, 78, 84, 86, 92, 94],
        [164, 166, 172, 174, 180, 182, 188, 190],
        [196, 198, 204, 206, 212, 214, 220, 222],
        [292, 294, 300, 302, 308, 310, 316, 318],
        [324, 326, 332, 334, 340, 342, 348, 350],
        [420, 422, 428, 430, 436, 438, 444, 446],
        [452, 454, 460, 462, 468, 470, 476, 478],
    ])
    bool_mat = np.isclose(expected_pt_2, pt_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out the third subsystem:
    pt_3 = partial_trace(test_input_mat, [3], [4, 2, 2])
    expected_pt_3 = np.array([
        [19, 23, 27, 31, 35, 39, 43, 47],
        [83, 87, 91, 95, 99, 103, 107, 111],
        [147, 151, 155, 159, 163, 167, 171, 175],
        [211, 215, 219, 223, 227, 231, 235, 239],
        [275, 279, 283, 287, 291, 295, 299, 303],
        [339, 343, 347, 351, 355, 359, 363, 367],
        [403, 407, 411, 415, 419, 423, 427, 431],
        [467, 471, 475, 479, 483, 487, 491, 495],
    ])
    bool_mat = np.isclose(expected_pt_3, pt_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out the first and second subsystems:
    pt_1_2 = partial_trace(test_input_mat, [1, 2], [4, 2, 2])
    expected_pt_1_2 = np.array([[960, 968], [1088, 1096]])
    bool_mat = np.isclose(expected_pt_1_2, pt_1_2)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out the first and third subsystems:
    pt_1_3 = partial_trace(test_input_mat, [1, 3], [4, 2, 2])
    expected_pt_1_3 = np.array([[892, 908], [1148, 1164]])
    bool_mat = np.isclose(expected_pt_1_3, pt_1_3)
    np.testing.assert_equal(np.all(bool_mat), True)

    # Trace out the second and third subsystems:
    pt_2_3 = partial_trace(test_input_mat, [2, 3], [4, 2, 2])
    expected_pt_2_3 = np.array([[106, 122, 138, 154], [362, 378, 394, 410],
                                [618, 634, 650, 666], [874, 890, 906, 922]])
    bool_mat = np.isclose(expected_pt_2_3, pt_2_3)
    np.testing.assert_equal(np.all(bool_mat), True)