def setUp(self): # Set the dimensionality. n = self.n = 4 # Primal problem. self.P = P = picos.Problem() self.X = X = P.add_variable("X", (n, n), "symmetric") P.set_objective("max", X | 1) self.CT = P.add_constraint(picos.diag_vect(X) == 1) self.CX = P.add_constraint(X >> 0) # Dual problem. self.D = D = picos.Problem() self.mu = mu = D.add_variable("mu", n) self.Z = Z = D.add_variable("Z", (n, n), "symmetric") D.set_objective("min", mu | 1) D.add_constraint(1 - picos.diag(mu) + Z == 0) D.add_constraint(Z >> 0)
E1 = [0,1,3,4] # list of energy eigenvalues of input Hamiltonian E2 = [0,1] # list of energy eigenvalues of output Hamiltonian d1 = len(E1) d2 = len(E2) threshold = 0.9999 # set threshold for f(rho,sig) <=1 Cov = True # covariant constraint Gp = False # Gibbs-preserving constraint beta = 1. # inverse temperature rho = pic.new_param('rho', np.ones((d1,d1))*(1/d1)) # input state rho = maximally coherent state ## Gibbs-state: def g(x): return np.exp(-beta * x) exp_array1 = np.array(list(map(g,E1))) exp_array2 = np.array(list(map(g,E2))) 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 cbit = pic.new_param('zero',np.array([[0.5,0.5],[0.5,0.5]])) # |+X+| zero = pic.new_param('zero', np.array([[1.,0.],[0.,0.]])) # |0X0| one = pic.new_param('one', np.array([[0.,0.],[0.,1.]])) # |1X1| I2 = pic.new_param('I2', np.eye(2)) # id_2 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 def dephase(M,H1,H2): ## dephase matrix M w.r.t. H_tot = id_d2 X H1 + HR X id_d1, ## HR = -H2
import numpy as np import picos as pic #qubit Hamiltonian H_1 = [0,1] #higher-dim system Hamiltonian H_2 = [0,1,2] #dimension of higher-dim system dim_2 = len(H_2) #total Hamiltonian H_total = [x - H_1[0] for x in H_2] + [x - H_1[1] for x in H_2] #setting up qubit basis states zero2 = pic.diag([1,0]) # |0X0| one2 = pic.diag([0,1])# |1X1| qubit = [zero2,one2] #Setting up qutrit basis states 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
#This is the SDP solver import picos as pic import matplotlib.pyplot as plt #setting up some useful qubit states plus2 = pic.new_param('plus2', np.array([[.5, .5], [.5, .5]])) # |+X+| minus2 = pic.new_param('minus2', np.array([[.5, -.5], [-.5, .5]])) # |-X-| 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 ###
def solve_RMCFP_L_2(G, s, t, mu, delta, Gamma): ''' This function solves the Robust MCFP with L_2 uncertainty set :param G: bidirectional graph object :param s: source node (0) :param t: sink (terminal) node (N-1) :param mu: nominal edges costs :param delta: costs deviations (uncertainty amplification) :param Gamma: uncertainty ball size :return: ''' # Define problem using PICOS P = pic.Problem() # Add the flow variables and auxiliary variable x = {} for e in G.edges(): x[e] = P.add_variable('x[{0}]'.format(e), 1) v = P.add_variable('v', 1) # Add "dummy" variables which will be exactly x in a vector form # to easily add the robust feasibility constraint x_vector = P.add_variable('x', len(G.edges)) # Add parameter to PICOS mu_pic = pic.new_param('mu', mu) delta_pic = pic.new_param('delta', delta) Gamma_pic = pic.new_param('Gamma', Gamma) # --- Add constraints --- # Robust feasibility constraint (its equivalent) P.add_constraint( abs(pic.diag(Gamma_pic * delta_pic) * x_vector) <= v - (mu_pic | x_vector)) # Enforce x_vector elements to be equal to all x variables P.add_list_of_constraints([ x_vector[i] == x[e] for (i, e) in zip(range(len(x_vector)), G.edges()) ]) # Enforce flow conservation P.add_list_of_constraints([ pic.sum([x[i, j] for i in G.predecessors(j)], 'i', 'pred(j)') == pic.sum([x[j, k] for k in G.successors(j)], 'k', 'succ(j)') for j in G.nodes() if j not in (s, t) ], 'j', 'nodes-(s,t)') # Set source flow at s P.add_constraint( pic.sum([x[s, j] for j in G.successors(s)], 'j', 'succ(s)') == 1) # Set sink flow at t P.add_constraint( pic.sum([x[i, t] for i in G.predecessors(t)], 'i', 'pred(t)') == 1) # Enforce edge capacities P.add_list_of_constraints( [x[e[:2]] <= e[2]['capacity'] for e in G.edges(data=True)], # list of constraints [('e', 2)], # e is a double index 'edges') # set the index belongs to # Enforce flow non-negativity P.add_list_of_constraints( [x[e] >= 0 for e in G.edges()], # list of constraints [('e', 2)], # e is a double index 'edges') # set the index belongs to # Solve P.set_objective('min', v) sol = P.solve(verbose=0, solver='cvxopt') # Unpack solution vector x = np.array(sol['cvxopt_sol']['x']).reshape(-1)[:len(G.edges())] return P, x
def dephase2(M): #qudit to qutrit dephase_M = pic.diag([0]*dim*2) for e in projectors.keys(): dephase_M = dephase_M + projectors[e]*M*projectors[e] return dephase_M
#TODO: pic.new_param vs np.array? plus2 = pic.new_param('plus2', np.array([[.5,.5],[.5,.5]])) # |+X+| minus2 = pic.new_param('minus2', np.array([[.5,-.5],[-.5,.5]])) # |-X-| 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 qudit basis states inside a list ### qudit = list() diag = [0]*dim for i in range(dim): diag[i] = 1 qudit.append(pic.diag(diag)) diag[i] = 0 ### 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)
def convexHessianExprPicos(Q, R, N, A, B, dP, alpha, scaling, index, G=None, C=None, F=None, Fg=None, T=None): """ Construct the Picos symbolic expression of the convexified Hessian :param H: non-convex Hessian :param A: system matrix :param B: input matrix :param dP: ... :return: Picos Expression of the convexified Hessian """ # set-up period = len(dP) H = scaling['alpha'] * alpha * mtools.buildHessian(Q[index], R[index], N[index]) A = A[index] B = B[index] if C is not None: CM = C[index] if G is not None: GM = G[index] dP1 = scaling['dP'] * dP[index] dP2 = scaling['dP'] * dP[(index + 1) % period] # convexify dQ = A.T * dP2 * A - dP1 dN = A.T * dP2 * B dNT = B.T * dP2.T * A dR = B.T * dP2 * B dH = (dQ & dN) // (dN.T & dR) # add constraints contribution if G is not None: dH = dH + GM.T * picos.diag(scaling['F'] * Fg[index]) * GM if F is not None: if F[index] is not None: dH = dH + CM.T * picos.diag(scaling['F'] * F[index]) * CM # add free regularisation if T is not None: if T[index] is not None: dH = dH + scaling['T'] * T[index] return H + dH