def f(rho1,sig2,beta,cov=True,GP=True): ## rho -> sigma under CPTP/ GP/ GPC/ Cov map? ## output \approx 1 --> yes, output < 1 --> no. ## dim(rho1) = dim(H1) = d1 ## dim(sig2) = dim(H2) = d2 ## default: qutrit-qubit CGP, equally-spaced energy levels, inv.temp=1 ## def problem & variables ## p = pic.Problem() X1 = p.add_variable('X1', (d1,d1), 'hermitian') X2 = p.add_variable('X2', (d2,d2), 'hermitian') X3 = p.add_variable('X3', (d2,d2), 'hermitian') ### constraints ### if GP == False: p.add_constraint((sig2|X2)==1) if cov == True: p.add_constraint(pic.kron(id_d2, X1) - dephase_H(pic.kron(X2, rho1)) >> 0. ) else: p.add_constraint(pic.kron(id_d2, X1) - pic.kron(X2, rho1) >> 0. ) else: p.add_constraint((sig2|X2)+(gam2|X3)==1) p.add_constraint(X3 >> 0) if cov == True: p.add_constraint(pic.kron(id_d2, X1) - dephase_H(pic.kron(X2, rho1)) - dephase_H(pic.kron(X3, gam1)) >> 0. ) else: p.add_constraint(pic.kron(id_d2, X1) - pic.kron(X2, rho1) - pic.kron(X3, gam1) >> 0. ) p.add_constraint(X1 >> 0) p.add_constraint(X2 >> 0) ### objective fn & solve ### p.set_objective('min', pic.trace(X1)) p.solve(verbose = 0,solver = 'cvxopt') return p.obj_value().real
def get_CBT_norm(J, n, m, rev=False): import cvxopt as cvx import picos as pic # Get completely bounded trace norm of Choi-matrix J representing quantum channel from number_of_qubits-dimensional space to m-dimensional space J = cvx.matrix(J) prob = pic.Problem(verbose=0) X = prob.add_variable("X", (n * m, n * m), vtype='complex') I = pic.new_param('I', np.eye(m)) rho0 = prob.add_variable("rho0", (n, n), vtype='hermitian') rho1 = prob.add_variable("rho1", (n, n), vtype='hermitian') prob.add_constraint(rho0 >> 0) prob.add_constraint(rho1 >> 0) prob.add_constraint(pic.trace(rho0) == 1) prob.add_constraint(pic.trace(rho1) == 1) if (rev == True): # TODO FBM: tests which conention is good. # TODO FBM: add reference to paper # This is convention REVERSED with respect to the paper, # and seems that this is a proper one???? C0 = pic.kron(rho0, I) C1 = pic.kron(rho1, I) else: C0 = pic.kron(I, rho0) C1 = pic.kron(I, rho1) F = pic.trace((J.H) * X) + pic.trace(J * (X.H)) prob.add_constraint(((C0 & X) // (X.H & C1)) >> 0) prob.set_objective('max', F) prob.solve(verbose=0) if prob.status.count("optimal") > 0: # print('solution optimal') 1 elif (prob.status.count("optimal") == 0): print('uknown_if_solution_optimal') else: print('solution not found') cbt_norm = prob.obj_value() / 2 if (abs(np.imag(cbt_norm)) >= 0.00001): raise ValueError else: cbt_norm = np.real(cbt_norm) return cbt_norm
def Hmin(rho, ref): ### compute Hmin(A|B)_rho, covariant map, ref=reference state. ### # def problem & variables # p = pic.Problem() X1 = p.add_variable('X1', (d1, d1), 'hermitian') p.add_constraint(pic.kron(id_d2, X1) - dephase_H(pic.kron(ref, rho)) >> 0.) p.add_constraint(X1 >> 0) # objective fn & solve # p.set_objective('min', pic.trace(X1)) p.solve(verbose=0, solver='cvxopt') return -np.log2(p.obj_value().real)
def f(rho1, sig2, beta=1, H1=[0, 1, 2], H2=[0, 1], cov=True, GP=True): ## rho -> sigma under CPTP/ GP/ GPC/ Cov map? ## output \approx 1 --> yes, output < 1 --> no. ## dim(rho1) = dim(H1) = d1 ## dim(sig2) = dim(H2) = d2 ## default: qutrit-qubit CPG, equally-spaced energy levels, inv.temp=1 d1 = len(H1) d2 = len(H2) id_d2 = pic.new_param('id_d2', np.eye(d2)) ## def problem & variables ## p = pic.Problem() X1 = p.add_variable('X1', (d1, d1), 'hermitian') X2 = p.add_variable('X2', (d2, d2), 'hermitian') X3 = p.add_variable('X3', (d2, d2), 'hermitian') ## Gibbs-state: def g(x): return np.exp(-beta * x) exp_array1 = np.array(list(map(g, H1))) exp_array2 = np.array(list(map(g, H2))) gam1 = pic.diag(np.true_divide(exp_array1, np.sum(exp_array1))) gam2 = pic.diag(np.true_divide(exp_array2, np.sum(exp_array2))) #g2_0 = gam2[0].value ### constraints ### if GP == False: p.add_constraint((sig2 | X2) == 1) if cov == True: p.add_constraint( pic.kron(id_d2, X1) - dephase(pic.kron(X2, rho1), H1, H2) >> 0.) else: p.add_constraint(pic.kron(id_d2, X1) - pic.kron(X2, rho1) >> 0.) else: p.add_constraint((sig2 | X2) + (gam2 | X3) == 1) p.add_constraint(X3 >> 0) if cov == True: p.add_constraint( pic.kron(id_d2, X1) - dephase(pic.kron(X2, rho1), H1, H2) - pic.kron(X3, gam1) >> 0.) else: p.add_constraint( pic.kron(id_d2, X1) - pic.kron(X2, rho1) - pic.kron(X3, gam1) >> 0.) p.add_constraint(X1 >> 0) p.add_constraint(X2 >> 0) ### objective fn & solve ### p.set_objective('min', pic.trace(X1)) p.solve(verbose=0, solver='cvxopt') return p.obj_value().real
def findQDistMaximizingCHSH2ForCHSH1ValueOf(alpha): prob = pic.Problem() A = {} for x1, x2 in product(range(2), range(2)): for a1, a2 in product(range(2), range(2)): A[x1, x2, a1, a2] = prob.add_variable('A_{0}{1}{2}{3}'.format(x1, x2, a1, a2), (2, 2), 'hermitian') prob.add_constraint(A[x1, x2, a1, a2] >> 0) for x1, x2 in product(range(2), range(2)): prob.add_constraint( sum(A[x1, x2, a1, a2] for a1 in range(2) for a2 in range(2)) == np.eye(2)) #sequential constraints for x1, a1 in product(range(2), range(2)): prob.add_constraint( sum([A[x1, 0, a1, a2] for a2 in (0, 1)]) == sum([A[x1, 1, a1, a2] for a2 in (0, 1)])) z0 = np.array([[1, 0], [0, 0]]) z1 = np.array([[0, 0], [0, 1]]) x0 = np.array([[1, 1], [1, 1]]) / 2 x1 = np.array([[1, -1], [-1, 1]]) / 2 B = {} B[0, 0] = pic.new_param('B_00', z0) B[0, 1] = pic.new_param('B_01', z1) B[1, 0] = pic.new_param('B_10', x0) B[1, 1] = pic.new_param('B_11', x1) rho = pic.new_param('rho', np.outer([1, 0, 0, 1], [1, 0, 0, 1]) / 2) A1 = [ 1 / 2 * sum(A[x1, x2, a1, a2] * (-1)**a1 for a1 in range(2) for a2 in range(2) for x2 in range(2)) for x1 in range(2) ] A2 = [ 1 / 2 * sum(A[x1, x2, a1, a2] * (-1)**a2 for a1 in range(2) for a2 in range(2) for x1 in range(2)) for x2 in range(2) ] B1 = [sum(B[y, b] * (-1)**b for b in range(2)) for y in range(2)] prob.add_constraint(pic.trace(CHSH(A1, B1) * rho) == alpha) prob.set_objective('max', pic.trace(CHSH(A2, B1) * rho)) prob.solve() # return [ pic.trace(pic.kron(A[x1, x2, a1, a2], B[y, b]) * rho).get_value().real for x1, x2, y, a1, a2, b in product(range(2), range(2), range(2), range(2), range(2), range(2)) ]
def f(rho1, sig2, gam1, gam2, d2, cov=True): # rho -> sigma under GP (set cov=False)/ GPC map? Output \approx 1 --> yes, output<1 --> no. # dim(rho1) = dim(gam1) # dim(sig2) = dim(gam2) = d2 id_d2 = pic.new_param('id_d2', np.eye(d2)) ## def problem & variables ## p = pic.Problem() X1 = p.add_variable('X1', (3, 3), 'hermitian') X2 = p.add_variable('X2', (d2, d2), 'hermitian') X3 = p.add_variable('X3', (d2, d2), 'hermitian') p.add_constraint((sig2 | X2) + (gam2 | X3) == 1) if cov == True: p.add_constraint( pic.kron(id_d2, X1) - dephase2(pic.kron(X2, rho1)) - pic.kron(X3, gam1) >> 0.) else: p.add_constraint( pic.kron(id_d2, X1) - pic.kron(X2, rho1) - pic.kron(X3, gam1) >> 0.) p.add_constraint(X1 >> 0) p.add_constraint(X2 >> 0) p.add_constraint(X3 >> 0) ## objective fn & solve ## p.set_objective('min', pic.trace(X1)) p.solve(verbose=0, solver='cvxopt') return p.obj_value().real
def f(rho1,sig2,gam1,gam2,cov): # rho -> sigma under GP (set cov=False)/ GPC map? Output \approx 1 --> yes, output<1 --> no. # dim(rho1) = dim(gam1) # dim(sig2) = dim(gam2) = d2 ## def problem & variables ## #TODO ask Rhea where general solution to this problem is p = pic.Problem() X1 = p.add_variable('X1', (dim,dim), 'hermitian') X2 = p.add_variable('X2', (2,2), 'hermitian') X3 = p.add_variable('X3', (2,2), 'hermitian') p.add_constraint((sig2|X2)+(gam2|X3)==1) if cov==True: #time-covariance constraint included p.add_constraint(pic.kron(I2, X1) - dephase2(pic.kron(X2, rho1)) - pic.kron(X3, gam1) >> 0. ) else: #time-covariance constraint not included p.add_constraint(pic.kron(I2, X1) - pic.kron(X2, rho1) - pic.kron(X3, gam1) >> 0. ) p.add_constraint(X1 >> 0) p.add_constraint(X2 >> 0) p.add_constraint(X3 >> 0) ## objective fn & solve ## p.set_objective('min', pic.trace(X1)) p.solve(verbose = 0,solver = 'cvxopt') return p.obj_value().real
def dephase(M,H1,H2): ## dephase matrix M w.r.t. H_tot = id_d2 X H1 + HR X id_d1, ## HR = -H2 ## H1, H2 lists of ordered energy eigenvalues of arb dim: low to high. d1 = len(H1) d2 = len(H2) id_d1 = pic.new_param('id_d1', np.eye(d1)) id_d2 = pic.new_param('id_d2', np.eye(d2)) dim = d1*d2 HR = np.negative(H2) H_tot = np.diag(np.matrix((pic.kron(id_d2,pic.diag(H1))+pic.kron(pic.diag(HR),id_d1)).value)) index = [np.argwhere(i==H_tot) for i in np.unique(H_tot)] dephased = pic.diag(np.zeros(dim)) PVMs=[] for i in range(len(index)): a2 = np.zeros(dim) a2[index[i]]=1 a2 = np.array(a2) PVMs.append(pic.diag(a2)) for i in range(len(index)): dephased += PVMs[i] * M * PVMs[i] return dephased
def CHSH(A, B): #chsh bell op give observables return pic.kron(A[0],B[0])+pic.kron(A[0],B[1])+pic.kron(A[1],B[0]) \ -pic.kron(A[1],B[1])
def team_opt(adj_mat, current_weights, covariance_matrices, how='geom', ne=1, edge_decisions=None): """ Runs the team optimization problem :param adj_mat: the Adjacency matrix :param current_weights: current node weights :param covariance_matrices: list of each node's large covariance matrix :param how: string that denotes fusion method :param ne: limit for number of edges to change :param edge_decisions: dictionary, if provided, the set of edges to set as 1 or 0 in their corresponding entries in PI :return: new adjacency matrix and new weights """ n = adj_mat.shape[0] beta = 1 / n tol = 0.1 s = covariance_matrices[0].shape[0] p_size = n * s edge_mod_limit = ne * 2 # Init Problem problem = pic.Problem() # Add Variables A = problem.add_variable('A', adj_mat.shape, 'symmetric') mu = problem.add_variable('mu', 1) Pbar = problem.add_variable('Pbar', (p_size, p_size)) PI = problem.add_variable('PI', adj_mat.shape, 'symmetric') delta_list = [] for i in range(n): delta_list.append(problem.add_variable('delta[{0}]'.format(i), (s, s))) delta_bar = problem.add_variable('delta_bar', (p_size, p_size)) delta_array = problem.add_variable('delta_array', (p_size, s)) # Add Params (ie constant affine expressions to help with creating constraints) cov_array = np.zeros((n * s, s)) for i in range(n): start = i * s end = i * s + s cov_array[start:end, 0:s] = covariance_matrices[i] I = pic.new_param('I', np.eye(s)) Ibar = pic.new_param('Ibar', np.eye(p_size)) cov_array_param = pic.new_param('covs', cov_array) # Set Objective if how == 'geom': problem.set_objective('min', pic.trace(Pbar)) else: problem.set_objective('min', pic.trace(delta_bar)) # Constraints # Setting Additional Constraint such that delta_bar elements equal elements in delta_list (with some tolerance) for i in range(n): start = i * s end = i * s + s problem.add_constraint( abs(delta_bar[start:end, start:end] - delta_list[i]) <= tol) if i < (n - 1): # Fill everything to left with 0s problem.add_constraint(delta_bar[start:end, end:] == np.zeros((s, (n * s) - end))) # Fill everything below with 0s problem.add_constraint(delta_bar[end:, start:end] == np.zeros(((n * s) - end, s))) # Setting Additional Constraint such that delta_array elements equal elements in delta_list (with some tolerance) for i in range(n): start = i * s end = i * s + s problem.add_constraint( abs(delta_array[start:end, :] - delta_list[i]) <= tol) if how == 'geom': # Schur constraint problem.add_constraint(((Pbar & Ibar) // (Ibar & delta_bar)).hermitianized >> 0) # Kron constraint problem.add_constraint(pic.kron(A, I) * cov_array_param == delta_array) problem.add_constraint(mu >= 0.001) problem.add_constraint(mu < 1) problem.add_constraint((A * np.ones((n, 1))) == np.ones((n, 1))) problem.add_constraint((beta * np.dot(np.ones(n).T, np.ones(n))) + (1 - mu) * np.eye(n) >= A) for i in range(n): problem.add_constraint(A[i, i] > 0) for j in range(n): if i == j: problem.add_constraint(PI[i, j] == 1.0) else: problem.add_constraint(PI[i, j] <= 1.0) problem.add_constraint(PI[i, j] >= 0.0) problem.add_constraint(A[i, j] > 0) problem.add_constraint(A[i, j] <= PI[i, j]) if edge_decisions is not None: # Ensures the set edge_decisions are maintained in PI for e, d in edge_decisions.items(): if d is not None: problem.add_constraint(PI[e[0], e[1]] == d) problem.add_constraint(PI[e[1], e[0]] == d) # Ensures the previous edges are maintained in PI for i in range(n): for j in range(n): if adj_mat[i, j] == 1: problem.add_constraint(PI[i, j] == 1.0) problem.add_constraint(abs(PI - adj_mat)**2 <= edge_mod_limit) try: problem.solve(verbose=0, solver='mosek') # problem_status = problem.status # print(problem_status) new_config = np.zeros(adj_mat.shape) new_weights = {} for i in range(n): new_weights[i] = {} for i in range(n): nw = A[i, i].value if nw == 0: nw = 0.1 new_weights[i][i] = nw new_config[i, i] = 1 for j in range(i + 1, n): if round(PI[i, j].value) == 1: new_config[i, j] = round(PI[i, j].value) new_config[j, i] = round(PI[j, i].value) nw = A[i, j].value if nw == 0: nw = 0.1 new_weights[i][j] = nw new_weights[j][i] = nw new_weights = normalize_weights(new_weights) return problem, problem.obj_value(), new_config, new_weights except Exception as e: print('solve error') print(e) return problem, 'infeasible', adj_mat, current_weights
def CHAINED(n, A, B): result = 0 for i in range(0, n - 1): result += pic.kron(A[i], B[i]) + pic.kron(A[i + 1], B[i]) result += pic.kron(A[n - 1], B[n - 1]) - pic.kron(A[0], B[n - 1]) return result
A2 = [ 1 / n * sum(A[x1, x2, a1, a2] * (-1)**a2 for a1 in range(2) for a2 in range(2) for x1 in range(n)) for x2 in range(2) ] B1 = [sum(B[y, b] * (-1)**b for b in range(2)) for y in range(n)] prob.add_constraint(pic.trace(CHAINED(n, A1, B1) * rho) == alpha) prob.set_objective('max', pic.trace(CHSH(A2, B1) * rho)) prob.solve() # dist = [ pic.trace(pic.kron(A[x1, x2, a1, a2], B[y, b]) * rho).get_value().real for x1, x2, y, a1, a2, b in product(range(n), range(2), range(n), range(2), range(2), range(2)) ] vertices = BellPolytopeWithOneWayCommunication( outputsAlice, outputsBob).getListOfVertices() print(In_ConvexHull(vertices, vertices[0])) # # with Model("lo1") as M: # # # Create variable 'x' of length 4 # x = M.variable("x", len(vertices), Domain.greaterThan(0.0))
zero3 = pic.diag([1,0,0]) one3 = pic.diag([0,1,0]) two3 = pic.diag([0,0,1]) qutrit = [zero3,one3,two3] #initialise dictionary of projectors onto total energy eigenspaces, indexed by total energy (qubit goes first) projectors = dict() #initalise list of unique energies uniq_e = list() for i in range(len(H_total)): e = H_total[i] #value of test determines whether e_total was achieved with ground or excited state on qubit test = i - dim_2 if e not in uniq_e: #begin constructing projector onto eigenspace with total energy e uniq_e.append(e) if test > -1: #involves excited state projectors[e]=pic.kron(qubit[1],qutrit[test]) else: #involves ground state projectors[e]=pic.kron(,qubit[0],qutrit[i]) else: #if projector unto state with total energy e already exists, expand that projector to include new state with the same total energy e if test > -1: projectors[e]=projectors[e]+pic.kron(,qubit[1],qutrit[test]) else: projectors[e]=projectors[e]+pic.kron(qubit[0],qutrit[i]) for key,value in projectors.items(): print(key,value)
zero2 = pic.new_param('zero2', np.array([[1., 0.], [0., 0.]])) # |0X0| one2 = pic.new_param('one2', np.array([[0., 0.], [0., 1.]])) # |1X1| I2 = pic.new_param('I2', np.eye(2)) # Identity X = pic.new_param('X', np.array([[0., 1.], [1., 0.]])) # pauli X Z = pic.new_param('Z', np.array([[1., 0.], [0., -1.]])) # pauli Z Y = pic.new_param('Y', np.array([[0., -1j], [1j, 0.]])) # pauli Y #Setting up qutrit basis states zero3 = pic.diag([1, 0, 0]) one3 = pic.diag([0, 1, 0]) two3 = pic.diag([0, 0, 1]) #Qutrit-qubit energy eigenspace projectors #TODO: find/write Python routine to automate this process Pi0 = pic.new_param('Pi0', pic.kron(zero2, zero3) + pic.kron(one2, one3)) # |00X00|+|11X11| Pi1 = pic.new_param('Pi1', pic.kron(zero2, one3) + pic.kron(one2, two3)) # |01X01|+|12X12| Pim1 = pic.new_param('Pim1', pic.kron(one2, zero3)) # |10X10| Pi2 = pic.new_param('Pi2', pic.kron(zero2, two3)) # |02X02| ### def initial state rho ### rho = pic.new_param('rho', np.ones((3, 3)) * (1 / 3)) #rho = pic.diag([1/3,1/3,1/3]) ### def Gibbs state's (system 1=qutrit, sys 2=qubit) ### b = .5 # inverse temp E0 = 0 E1 = 1. # energy level spacing
### setting up projectors onto total energy eigenspaces of qudit-qubit system ### #initialise dictionary of projectors onto total energy eigenspaces, indexed by total energy (qubit goes first) projectors = dict() #initalise list of unique energies uniq_e = list() for i in range(len(H_total)): e = H_total[i] #value of test determines whether e_total was achieved with ground or excited state on qubit test = i - dim if e not in uniq_e: #begin constructing projector onto eigenspace with total energy e uniq_e.append(e) if test > -1: #involves excited state projectors[e]=pic.kron(one2,qudit[test]) else: #involves ground state projectors[e]=pic.kron(zero2,qudit[i]) else: #if projector unto state with total energy e already exists, expand that projector to include new state with the same total energy e if test > -1: projectors[e]=projectors[e]+pic.kron(one2,qudit[test]) else: projectors[e]=projectors[e]+pic.kron(zero2,qudit[i]) ### def initial state rho ### rho = pic.new_param('rho', np.ones((dim,dim))*(1/dim)) ### def Gibbs states (system 1=qudit, sys 2=qubit) ### b = .5 # inverse temp