def test_maximum_violation(self): def expectation_values(measurement, outcomes): exp_values = [] for k in range(len(measurement)): exp_value = 0 for j in range(len(measurement[k])): exp_value += outcomes[k][j] * measurement[k][j] exp_values.append(exp_value) return exp_values E = generate_operators('E', 8, hermitian=True) M, outcomes = [], [] for i in range(4): M.append([E[2 * i], E[2 * i + 1]]) outcomes.append([1, -1]) A = [M[0], M[1]] B = [M[2], M[3]] substitutions = projective_measurement_constraints(A, B) C = expectation_values(M, outcomes) chsh = -(C[0] * C[2] + C[0] * C[3] + C[1] * C[2] - C[1] * C[3]) sdpRelaxation = SdpRelaxation(E, verbose=0) sdpRelaxation.get_relaxation(1, objective=chsh, substitutions=substitutions) sdpRelaxation.solve() self.assertTrue(abs(sdpRelaxation.primal + 2*np.sqrt(2)) < 10e-5)
def test_maximum_violation(self): def expectation_values(measurement, outcomes): exp_values = [] for k in range(len(measurement)): exp_value = 0 for j in range(len(measurement[k])): exp_value += outcomes[k][j] * measurement[k][j] exp_values.append(exp_value) return exp_values E = generate_operators('E', 8, hermitian=True) M, outcomes = [], [] for i in range(4): M.append([E[2 * i], E[2 * i + 1]]) outcomes.append([1, -1]) A = [M[0], M[1]] B = [M[2], M[3]] substitutions = projective_measurement_constraints(A, B) C = expectation_values(M, outcomes) chsh = -(C[0] * C[2] + C[0] * C[3] + C[1] * C[2] - C[1] * C[3]) sdpRelaxation = SdpRelaxation(E, verbose=0) sdpRelaxation.get_relaxation(1, objective=chsh, substitutions=substitutions) sdpRelaxation.solve() self.assertTrue(abs(sdpRelaxation.primal + 2 * np.sqrt(2)) < 10e-5)
V1 = ncp.generate_operators('V1', 2, hermitian=False) V2 = ncp.generate_operators('V2', 2, hermitian=False) substitutions = {} moment_ineqs = [] moment_eqs = [] operator_eqs = [] operator_ineqs = [] # Projectors sum to identity # We can speed up the computation (for potentially worse rates) by imposing these # as moment equalities. moment_eqs += [A[0][0] + A[0][1] - 1] # Adding the constraints for the measurement operators substitutions.update(ncp.projective_measurement_constraints(A, B)) # Defining a system to generate a conditional distribution # We pick the system that maximizes the chsh score test_sys = [pi / 4, 0.0, pi / 2, pi / 4, -pi / 4, 0.0] test_eta = 0.99 # Get the monomial constraints score_cons = score_constraints(test_sys, A, B, test_eta) # CONDITIONS on V1 and V2 # Commute with all Alice and Bob operators for v in V1 + V2: for Ax in A: for a in Ax: substitutions.update({v * a: a * v}) substitutions.update({Dagger(v) * a: a * Dagger(v)})
def _relax(self): """ Creates the sdp relaxation object from ncpol2sdpa. """ if self.solver == None: self.solver = self.DEFAULT_SOLVER_PATH self._eq_cons = [] # equality constraints self._proj_cons = {} # projective constraints self._A_ops = [] # Alice's operators self._B_ops = [] # Bob's operators self._obj = 0 # Objective function self._obj_const = '' # Extra objective normalisation constant self._sdp = None # SDP object # Creating the operator constraints nrm = '' # Need as many decompositions as there are generating outcomes for k in range(np.prod(self.generation_output_size)): self._A_ops += [ ncp.generate_measurements(self.io_config[0], 'A' + str(k) + '_') ] self._B_ops += [ ncp.generate_measurements(self.io_config[1], 'B' + str(k) + '_') ] self._proj_cons.update( ncp.projective_measurement_constraints(self._A_ops[k], self._B_ops[k])) #Also building a normalisation string for next step nrm += '+' + str(k) + '[0,0]' # Adding the constraints # Normalisation constraint self._eq_cons.append(nrm + '-1') self._base_constraint_expressions = [] # Create the game expressions for game in self.games: tmp_expr = 0 for k in range(np.prod(self.generation_output_size)): tmp_expr += -ncp.define_objective_with_I( game._cgmatrix, self._A_ops[k], self._B_ops[k]) self._base_constraint_expressions.append(tmp_expr) # Specify the scores for these expressions including any shifts for i, game in enumerate(self.games): #We must account for overshifting in the score coming from the decomposition self._eq_cons.append(self._base_constraint_expressions[i] - game.score - game._cgshift * (np.prod(self.generation_output_size) - 1)) self._obj, self._obj_const = guessingProbabilityObjectiveFunction( self.io_config, self.generation_inputs, self._A_ops, self._B_ops) # Initialising SDP ops = [ ncp.flatten([self._A_ops[0], self._B_ops[0]]), ncp.flatten([self._A_ops[1], self._B_ops[1]]), ncp.flatten([self._A_ops[2], self._B_ops[2]]), ncp.flatten([self._A_ops[3], self._B_ops[3]]) ] self._sdp = ncp.SdpRelaxation(ops, verbose=self.verbose, normalized=False) self._sdp.get_relaxation(level=self._relaxation_level, momentequalities=self._eq_cons, objective=self._obj, substitutions=self._proj_cons, extraobjexpr=self._obj_const)
return exp_values # Number of Hermitian variables n_vars = 8 # Level of relaxation level = 1 # Get Hermitian variables E = generate_variables(n_vars, name='E', hermitian=True) # Define measurements and outcomes M, outcomes = [], [] for i in range(int(n_vars / 2)): M.append([E[2 * i], E[2 * i + 1]]) outcomes.append([1, -1]) # Define which measurements Alice and Bob have A = [M[0], M[1]] B = [M[2], M[3]] substitutions = projective_measurement_constraints(A, B) C = expectation_values(M, outcomes) chsh = -(C[0] * C[2] + C[0] * C[3] + C[1] * C[2] - C[1] * C[3]) sdpRelaxation = SdpRelaxation(E, verbose=2) sdpRelaxation.get_relaxation(level, objective=chsh, substitutions=substitutions) print(solve_sdp(sdpRelaxation))