Пример #1
0
    def linear_constraint_Alice(self):

        # Create dimension tuple for the partial tracing
        sub_dim = (self.dimT,
                   self.dimT**(self.n1 + self.n2 - 1) * self.dimS**2)

        for q1 in range(self.dimQ1):
            for index_else in self.indices_but_A1Q1:
                indices_A1q1a2q2_ext = [
                    np.append(np.array([a1, q1]), index_else)
                    for a1 in range(self.dimA1)
                ]
                indices_A1Q1a2q2_ext = [
                    np.append(index_A1Q1, index_else)
                    for index_A1Q1 in self.indices_A1Q1
                ]

                lhs = sum([
                    self.rho_variable[self.StI(index)]
                    for index in indices_A1q1a2q2_ext
                ])

                rhs_variable = sum([
                    self.rho_variable[self.StI(index)]
                    for index in indices_A1Q1a2q2_ext
                ])
                rhs_partial = nlg.partial_trace(rhs_variable, sub_dim)
                rhs = self.probQ1[q1] * cp.kron(self.rhoT, rhs_partial)

                self.constraints.append(lhs - rhs == 0)
Пример #2
0
def test_partial_trace():

    cvx_rho_ABC = cp.Variable(shape=rho_ABC.shape, complex=True)
    cvx_rho_AB = cp.Variable(shape=rho_AB.shape, complex=True)
    cvx_rho_AC = cp.Variable(shape=rho_AC.shape, complex=True)

    cvx_rho_ABC.value = rho_ABC
    cvx_rho_AB.value = rho_AB
    cvx_rho_AC.value = rho_AC

    obtained_rho_AB = nlg.partial_trace(cvx_rho_ABC, [4, 3, 2], axis=2)
    obtained_rho_AC = nlg.partial_trace(cvx_rho_ABC, [4, 3, 2], axis=1)

    obtained_rho_A = nlg.partial_trace(cvx_rho_AB, [4, 3], axis=1)
    obtained_rho_B = nlg.partial_trace(cvx_rho_AB, [4, 3])
    obtained_rho_C = nlg.partial_trace(cvx_rho_AC, [4, 2])

    np.testing.assert_allclose(obtained_rho_AB.value, rho_AB)
    np.testing.assert_allclose(obtained_rho_AC.value, rho_AC)

    np.testing.assert_allclose(obtained_rho_A.value, rho_A)
    np.testing.assert_allclose(obtained_rho_B.value, rho_B)
    np.testing.assert_allclose(obtained_rho_C.value, rho_C)
Пример #3
0
    def linear_constraint_Bob(self):

        # Permutation matrix (T1...Tn1)(T1...Tn2)(SS) -> (Tn2...T1)(T1...Tn1)(SS)
        order = np.arange(self.n1 + self.n2 + 2)

        maskA = order[:self.n1]
        maskB = np.flip(order[self.n1:self.n1 + self.n2])
        maskS = order[self.n1 + self.n2:]
        mask = np.concatenate((maskB, maskA, maskS))

        P = cp.Constant(nlg.permutation_matrix(order, mask,
                                               self.subs_TTSS_ext))

        # Create dimension tuple for the partial tracing
        sub_dim = (self.dimT,
                   self.dimT**(self.n1 + self.n2 - 1) * self.dimS**2)

        for q2 in range(self.dimQ2):
            for index_else in self.indices_but_A2Q2:
                indices_a1q1A2q2_ext = [
                    np.append(index_else, np.array([a2, q2]))
                    for a2 in range(self.dimA2)
                ]
                indices_a1q1A2Q2_ext = [
                    np.append(index_else, index_A2Q2)
                    for index_A2Q2 in self.indices_A2Q2
                ]

                lhs_variable = sum([
                    self.rho_variable[self.StI(index)]
                    for index in indices_a1q1A2q2_ext
                ])
                lhs = P @ lhs_variable @ P.T

                rhs_variable = sum([
                    self.rho_variable[self.StI(index)]
                    for index in indices_a1q1A2Q2_ext
                ])
                rhs_permuted = P @ rhs_variable @ P.T
                rhs_partial = nlg.partial_trace(rhs_permuted, sub_dim)
                rhs = self.probQ2[q2] * cp.kron(self.rhoT, rhs_partial)

                self.constraints.append(lhs - rhs == 0)
Пример #4
0
    def rho_TTSS(self, a1, q1, a2, q2):

        # Build the indices for the extended state
        index_a1q1 = np.array([[a1, q1]])
        index_a2q2 = np.array([[a2, q2]])

        indices_but_a2q2 = nlg.fuse_arrays(index_a1q1,
                                           self.indices_but_A1Q1A2Q2)
        indices_a1q1a2q2_ext = nlg.fuse_arrays(indices_but_a2q2, index_a2q2)

        # Reduce the classical part
        rho_reduced = sum([
            self.rho_variable[self.StI(index)]
            for index in indices_a1q1a2q2_ext
        ])

        # Reduce the quanutm part
        if self.n1 != 1 or self.n2 != 1:
            dim_subsys = (self.dimT, self.dimT**(self.n1 + self.n2 - 2),
                          self.dimT * self.dimS**2)
            rho_reduced = nlg.partial_trace(rho_reduced, dim_subsys, axis=1)

        return rho_reduced
Пример #5
0
def test_partial_trace_no_squared_matrix():

    wrong_input = cp.bmat([[1., 2., 3.], [4., 5., 6.]])

    with assert_raises(ValueError):
        nlg.partial_trace(wrong_input, [3])
Пример #6
0
def test_partial_trace_no_cvx_expression():

    wrong_input = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])

    with assert_raises(TypeError):
        nlg.partial_trace(wrong_input, [3])