コード例 #1
0
def test_partial_transpose_BC():

    cvx_sigma_BC = cp.Variable(shape=sigma_BC.shape)
    cvx_sigma_BC.value = sigma_BC

    obtained_sigma_BC_TB = nlg.partial_transpose(cvx_sigma_BC, [2, 2], (1, 0))
    obtained_sigma_BC_TC = nlg.partial_transpose(cvx_sigma_BC, [2, 2], (0, 1))

    np.testing.assert_allclose(obtained_sigma_BC_TB.value, sigma_BC_TB)
    np.testing.assert_allclose(obtained_sigma_BC_TC.value, sigma_BC_TB)
コード例 #2
0
def test_partial_transpose_ABC_as_2_subsystems_AB_C():

    cvx_sigma_ABC = cp.Variable(shape=sigma_ABC.shape)
    cvx_sigma_ABC.value = sigma_ABC

    obtained_sigma_ABC_TAB = nlg.partial_transpose(cvx_sigma_ABC, [4, 2],
                                                   (1, 0))
    obtained_sigma_ABC_TC = nlg.partial_transpose(cvx_sigma_ABC, [4, 2],
                                                  (0, 1))

    np.testing.assert_allclose(obtained_sigma_ABC_TAB.value, sigma_ABC_TB)
    np.testing.assert_allclose(obtained_sigma_ABC_TC.value, sigma_ABC_TB)
コード例 #3
0
    def PPT_constraints(self):

        # Create tuple of choices (0=no-PT and 1=PT), one for each subsystem (SS subsystem counts as one)
        PT_choice = (2, ) * (self.n1 + self.n2 + 1)

        # Create all possible combinations of PT and no-PT allowed by the cuts
        PT_list = np.array([
            np.concatenate((item[:-1], np.full(2, item[-1])))
            for item in nlg.indices_list(PT_choice)
        ])

        # Remove trivial cases (all 0's and all 1's)
        num_subs = self.n1 + self.n2 + 2
        bool_trivial = np.sum(PT_list, axis=1) % num_subs != 0
        PT_list = PT_list[bool_trivial]

        # Remove double cases and add PPT constraints
        used_PT_list = []

        for PT in PT_list:
            opposite_PT = (PT + 1) % 2
            is_PT_in = np.any([
                np.all(item == PT) or np.all(item == opposite_PT)
                for item in used_PT_list
            ])
            if not is_PT_in:
                used_PT_list.append(
                    PT
                )  # We use this to decide whether to add new constraints or not
                for i in map(self.StI, self.indices_A1Q1A2Q2_ext):
                    PPT_constr = nlg.partial_transpose(
                        self.rho_variable[i], self.subs_TTSS_ext, PT) >> 0
                    self.constraints.append(PPT_constr)
コード例 #4
0
    def __init__(self, level, answers, questions, dim_assistance,
                 rule_function, distributions):

        # Level of the SDP relaxation
        self.n1, self.n2 = level

        # Dimension of questions and answers for the game
        self.dimA1, self.dimA2 = answers
        self.dimQ1, self.dimQ2 = questions

        # Dimension of the assisting quantum system
        self.dimT = dim_assistance
        self.dimS = dim_assistance  # Copy due to swap-trick

        # Rules of the game
        self.rule = rule_function

        # Probability distribution of questions asked by referee
        self.probQ1, self.probQ2 = distributions

        # Useful variables for the methods of the class
        self.subs_A1Q1 = (self.dimA1, self.dimQ1)
        self.indices_A1Q1 = nlg.indices_list(self.subs_A1Q1)

        self.subs_A2Q2 = (self.dimA2, self.dimQ2)
        self.indices_A2Q2 = nlg.indices_list(self.subs_A2Q2)

        self.subs_A1Q1A2Q2 = self.subs_A1Q1 + self.subs_A2Q2
        self.indices_A1Q1A2Q2 = nlg.indices_list(self.subs_A1Q1A2Q2)

        self.subs_A1Q1A2Q2_ext = self.subs_A1Q1 * self.n1 + self.subs_A2Q2 * self.n2
        self.indices_A1Q1A2Q2_ext = nlg.indices_list(self.subs_A1Q1A2Q2_ext)

        self.subs_but_A1Q1A2Q2 = self.subs_A1Q1 * (
            self.n1 - 1) + self.subs_A2Q2 * (self.n2 - 1)
        self.indices_but_A1Q1A2Q2 = nlg.indices_list(self.subs_but_A1Q1A2Q2)

        self.subs_but_A1Q1 = self.subs_A1Q1 * (self.n1 -
                                               1) + self.subs_A2Q2 * self.n2
        self.indices_but_A1Q1 = nlg.indices_list(self.subs_but_A1Q1)

        self.subs_but_A2Q2 = self.subs_A1Q1 * self.n1 + self.subs_A2Q2 * (
            self.n2 - 1)
        self.indices_but_A2Q2 = nlg.indices_list(self.subs_but_A2Q2)

        self.subs_TTSS = (self.dimT, self.dimT, self.dimS, self.dimS)

        self.subs_TTSS_ext = (self.dimT, ) * (self.n1 + self.n2) + (self.dimS,
                                                                    self.dimS)
        self.dim_TTSS_ext = fc.reduce(mul, self.subs_TTSS_ext, 1)

        # Maximally-entangled states between TT|SS
        self.F_TTSS = cp.Constant(
            nlg.permutation_matrix((0, 1, 2, 3), (2, 3, 0, 1), self.subs_TTSS))
        self.Phi_TTSS = nlg.partial_transpose(self.F_TTSS, self.subs_TTSS,
                                              (0, 0, 1, 1))

        # Maximally-mixed state on T
        self.rhoT = np.identity(self.dimT) / self.dimT

        # Function mapping a sequence of indices to integers
        self.StI = lambda seq: nlg.seqtoint(seq, self.subs_A1Q1A2Q2_ext)

        # List of SDP variable
        self.rho_variable = []

        # Objective function of the problem
        self.object_function = 0

        # The list of constraints
        self.constraints = []