-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchsh.py
160 lines (121 loc) · 5.13 KB
/
chsh.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#%%
import ncpol2sdpa
import numpy as np
from sympy import *
from ncpol2sdpa import SdpRelaxation, generate_measurements
import os
# %%
'''
This file calculates the tripartite winning probability of the CHSH game from Section III B of
Device independent security of quantum key distribution from arbitrary monogamy-of-entanglement games
Includes the constrained tripartite winning probabilities given Alice and Bob expected score
'''
# %%
os.mkdir('CHSH__Data')
# # # # # # # # # # # # # # # # # # # # # # # #
# Get projection operators and substitution
# # # # # # # # # # # # # # # # # # # # # # # #
def PVM():
P = ncpol2sdpa.generate_measurements([2]*2, 'P')
Q = ncpol2sdpa.generate_measurements([2]*2, 'Q')
F = ncpol2sdpa.generate_measurements([2]*4, 'F')
return P, Q, F
def PVM_substitutions(P,Q,F):
substitutions = ncpol2sdpa.projective_measurement_constraints((P,Q,F))
return substitutions
# # # # # # # # # # # # # # # # # # # # # # # #
# Objective functions
# # # # # # # # # # # # # # # # # # # # # # # #
'''Objective function for the three players'''
def objective_function(P,Q,F):
zero_zero = P[0][0] * Q[0][0] * F[0][0] + (1 - P[0][0]) * (1 - Q[0][0]) * (1 - F[0][0])
zero_one = P[0][0] * Q[1][0] * F[1][0] + (1 - P[0][0]) * (1 - Q[1][0]) * (1 - F[1][0])
one_zero = P[1][0] * Q[0][0] * F[2][0] + (1 - P[1][0]) * (1 - Q[0][0]) * (1 - F[2][0])
one_one = P[1][0] * (1 - Q[1][0]) * F[3][0] + (1 - P[1][0]) * Q[1][0] * (1 - F[3][0])
return (-zero_zero - zero_one - one_zero -one_one)/4
'''Objective function for Alice and Bob'''
def objective_function_AB(P,Q,eps):
constraint = -3/4 - eps
# constraint = eps - np.cos(np.pi/8)**2
x_zero = P[0][0] * (Q[0][0] + Q[1][0]) + (1 - P[0][0]) * ((1 - Q[0][0]) + (1 - Q[1][0]))
x_one = P[1][0] * (Q[0][0] + (1 - Q[1][0])) + (1 - P[1][0]) * ((1 - Q[0][0]) + Q[1][0])
return constraint + (x_zero + x_one)/4
# # # # # # # # # # # # # # # # # # # # # # # #
# We get the relaxation on the desired level
# # # # # # # # # # # # # # # # # # # # # # # #
def relaxation(level, eps, verbose=1, save=True):
if save:
dir = 'CHSH__Data/CHSH_data_for_level_%s' %level
if eps is not None:
dir += '_epsAB_equal_%s' %eps
os.mkdir(dir)
'''The variables'''
variables = PVM()
P = variables[0]
Q = variables[1]
F = variables[2]
variables = ncpol2sdpa.flatten([P,Q,F])
'''The substitions'''
substitutions = PVM_substitutions(P,Q,F)
'''The constraints'''
inequalities = [objective_function_AB(P,Q,eps)]
'''The objective function'''
objective = objective_function(P,Q,F)
'''Getting the relaxation'''
sdpRelaxation = SdpRelaxation(variables=variables, verbose = verbose)
sdpRelaxation.get_relaxation(level, objective=objective,
substitutions=substitutions,
momentinequalities=inequalities)
sdpRelaxation.solve(solver='mosek')
if save:
'''Getting the solved parameters'''
primal_mat = sdpRelaxation.x_mat[0]
primal_val = sdpRelaxation.primal
dual_mat = sdpRelaxation.y_mat[0]
dual_val = sdpRelaxation.dual
status = sdpRelaxation.status
time = sdpRelaxation.solution_time
monomial_sets = sdpRelaxation.monomial_sets[0]
'''Saving the solved parameters'''
np.savetxt(dir + '/primal_mat.csv', primal_mat)
np.savetxt(dir + '/dual_mat.csv', dual_mat)
np.save(dir + '/monomial_sets', monomial_sets)
sdpRelaxation.save_monomial_index(dir + '/monomial_index.txt')
primal_string = 'The primal objective value is %s. This is an upper bound on the CHSH quantum value.' %(-primal_val)
dual_string = '\n The dual objective value is %s.' %(-dual_val)
stat_string = '\n The status of level %s' %level
stat_string += ' is ' + status
stat_string += ' and it required %s' %time
stat_string += ' seconds.'
str_output = primal_string+dual_string+stat_string
output_file = open(dir + '/output_lvl%s.txt' %level, 'wt')
n = output_file.write(str_output)
output_file.close()
# print(str_output)
print('The optimum of level ', level,
'with AB winning probability at least ', eps+3/4,
' is: ', -sdpRelaxation.primal)
print('The sdp: ', sdpRelaxation.status)
"The following are returned for making a figure"
return -sdpRelaxation.primal, 3/4+eps
# %%
# # # # # # # # # # # # # # # # # # # # # # # #
# Collecting data
# # # # # # # # # # # # # # # # # # # # # # # #
ABC_win = []
AB_win = []
for eps in range(0,101,5):
out = relaxation(level=3, eps=eps/1000,verbose=0)
ABC_win.append(out[0])
AB_win.append(out[1])
out = relaxation(level=3, eps=(np.sqrt(2)+2)/4-3/4,verbose=0)
ABC_win.append(out[0])
AB_win.append(out[1])
np.savetxt('CHSH__Data/Pr_ABwin', AB_win)
np.savetxt('CHSH__Data/Pr_ABCwin', ABC_win)
import matplotlib.pyplot as plt
plt.scatter(AB_win, ABC_win, alpha=0.5)
plt.plot(AB_win, [(np.sqrt(2)+2)/8]*len(AB_win))
plt.xlabel('Pr[A,B win]')
plt.ylabel('Pr[A,B,C win | A,B win]')
plt.savefig(fname='CHSH__Data/chsh_constrained.png')