def revert_cvxpy_solution(self): ''' Get QP primal and duar variables from cvxpy solution ''' (x_cvx, u_cvx) = self.cvxpy_variables constraints = self.cvxpy_problem.constraints T = self.T # primal solution x = np.concatenate((cvxpy.vec(x_cvx).value, cvxpy.vec(u_cvx).value)) # dual solution constraint_values = [constr.dual_value for constr in constraints] y = np.array([]) # Add dynamics for i in np.arange(T + 1): y = np.append(y, -constraint_values[i]) # Equalities # Add state constraints (2 * (T + 1)) for i in np.arange(T + 1, 3 * (T + 1) - 1, 2): y = np.append(y, constraint_values[i + 1] - constraint_values[i]) # Add input constraints ( 2 * T ) for i in np.arange(3 * (T + 1), 3 * (T + 1) + 2 * T - 1, 2): y = np.append(y, constraint_values[i + 1] - constraint_values[i]) return x, y
def proximal_op(prob, var_slack, lambd): """ proximal operator of the objective :param prob: problem :param var_slack: list of slack variables :param lambd: proximal operator parameter :return: a problem with proximal operator """ new_cost = prob.objective.expr new_constr = prob.constraints slack_id = [var.id for var in var_slack] #Add proximal variables prob_variables = prob.variables() prob_variables.sort(key=lambda x: x.id) for var in prob_variables: # add quadratic terms for all variables that are not slacks if not var.id in slack_id: if prob.objective.NAME == 'minimize': new_cost = new_cost + cvx.square( cvx.norm(cvx.vec(var - var.value), 2)) / 2 / lambd else: new_cost = new_cost - cvx.square( cvx.norm(cvx.vec(var - var.value), 2)) / 2 / lambd # Define proximal problem if prob.objective.NAME == 'minimize': new_prob = cvx.Problem(cvx.Minimize(new_cost), new_constr) else: # maximize new_prob = cvx.Problem(cvx.Maximize(new_cost), new_constr) return new_prob
def max_min_dccp(n_samples, var_importance): """Solve MaxMin Diversity problem on hypercube :nsamples : number of samples :var_importance: list of floats, specifying importance of each variable """ radii = np.ones(n_samples) # radii v_scale = cvx.vec(var_importance) c = cvx.Variable((n_samples, len(var_importance))) constr = [] for i in range(n_samples - 1): for j in range(i + 1, n_samples): # distance vector is scaled by variable importance d = cvx.multiply(cvx.vec(c[i, :] - c[j, :]), v_scale) constr.append(cvx.norm(d, 2) >= radii[i] + radii[j]) # minimize the size of the square to fit the given spheres # (by minimzing the largest component of any center vector) prob = cvx.Problem( cvx.Minimize(cvx.max(cvx.max(cvx.abs(c), axis=1) + radii)), constr) prob.solve(method='dccp', solver='ECOS', ep=1e-2, max_slack=1e-2) l = cvx.max(cvx.max(cvx.abs(c), axis=1) + radii).value * 2 pi = np.pi ratio = pi * cvx.sum(cvx.square(radii)).value / cvx.square(l).value print("ratio =", ratio) # shift to positive numbers coords = c.value - np.min(c.value) # scale maximum coordinate to 1 coords /= np.max(coords) return coords
def tv_cvxpy_regulariser(self, u, isotropic=True, direction = "forward", boundaries = "Neumann"): G = self.sparse_gradient_matrix(u.shape, direction = direction, order = 1, boundaries = boundaries) DX, DY = G[1], G[0] if isotropic: return cvxpy.sum(cvxpy.norm(cvxpy.vstack([DX @ cvxpy.vec(u), DY @ cvxpy.vec(u)]), 2, axis = 0)) else: return cvxpy.sum(cvxpy.norm(cvxpy.vstack([DX @ cvxpy.vec(u), DY @ cvxpy.vec(u)]), 1, axis = 0))
def test_vec(self): """Test the vec atom. """ expr = cp.vec(self.C) self.assertEqual(expr.sign, s.UNKNOWN) self.assertEqual(expr.curvature, s.AFFINE) self.assertEqual(expr.shape, (6, )) expr = cp.vec(self.x) self.assertEqual(expr.shape, (2, )) expr = cp.vec(cp.square(self.a)) self.assertEqual(expr.sign, s.NONNEG) self.assertEqual(expr.curvature, s.CONVEX) self.assertEqual(expr.shape, (1, ))
def linearize(expr): """Returns the tangent approximation to the expression. Gives an elementwise lower (upper) bound for convex (concave) expressions. No guarantees for non-DCP expressions. Args: expr: An expression. Returns: An affine expression. """ if expr.is_affine(): return expr else: tangent = expr.value if tangent is None: raise ValueError( "Cannot linearize non-affine expression with missing variable values." ) grad_map = expr.grad for var in expr.variables(): if grad_map[var] is None: return None if var.ndim > 1: temp = cvx.reshape(cvx.vec(var - var.value), (var.shape[0] * var.shape[1], 1)) grad_transp = np.transpose(grad_map[var]) flattened = grad_transp * temp if np.isscalar(grad_transp) else grad_transp @ temp tangent = tangent + cvx.reshape(flattened, expr.shape) else: tangent = tangent + np.transpose(grad_map[var]) @ (var - var.value) return tangent
def policy_unU2(G, R, L, d, x_prev, un_U, gamma): # a greedy policy that max next step return using un_U [n,A]=R.shape [m,temp]=d.shape Q = cvxpy.Variable(n,A) M = cvxpy.Variable(n,n) x = cvxpy.Variable(n,1) Kr = cvxpy.kron(np.ones((A,1)),np.eye(n)) # Create two constraints. constraints = [-M + cvxpy.mul_elemwise(G,(np.ones((n, 1)) * cvxpy.vec(Q).T)) * Kr == 0, L * x - d <= 0, x - M * x_prev == 0, Q * np.ones((A, 1)) - np.ones((n, 1)) == 0, Q >= 0, x >= 0, x.T * np.ones((n, 1)) - 1 == 0 ] # Form objective. obj = cvxpy.Minimize(-(x.T) * un_U) # Form and solve problem. prob = cvxpy.Problem(obj, constraints) prob.solve(solver = cvxpy.ECOS, verbose = False, max_iters = 5000) # prob.solve(solver = cvxpy.SCS, verbose = False) return Q.value, M.value, x.value
def linearize(expr): """Returns the tangent approximation to the expression. Gives an elementwise lower (upper) bound for convex (concave) expressions. No guarantees for non-DCP expressions. Args: expr: An expression. Returns: An affine expression. """ if expr.is_affine(): return expr else: tangent = expr.value if tangent is None: raise ValueError( "Cannot linearize non-affine expression with missing variable values." ) grad_map = expr.grad for var in expr.variables(): if var.is_matrix(): flattened = np.transpose( grad_map[var]) * cvx.vec(var - var.value) tangent = tangent + cvx.reshape(flattened, *expr.shape) else: if var.shape[1] == 1: tangent = tangent + np.transpose( grad_map[var]) * (var - var.value) else: tangent = tangent + (var - var.value) * grad_map[var] return tangent
def matapply(self, mat): if isinstance(mat, cvxpy.expressions.expression.Expression): return cvxpy.vec(mat) else: # being explicit that we want a column vec # NB: (cvxpy.vec().value is a column vec) return mat.reshape((np.prod(mat.shape), 1), order='F')
def matapply(self, mat, compute_measmat=False): """Apply to oper A \otimes B given as vec(ab^T), all vecs F-order""" if self._measmat is not None: if isinstance(mat, cvxpy.expressions.expression.Expression): out = self._measmat * cvxpy.vec(mat) else: out = self._measmat @ mat.flatten(order='F') else: # FIXME: will fail if cvxpy expression passed out = np.zeros((self.nmeas, 1)) if compute_measmat: self._measmat = np.zeros((self.nmeas, np.prod(self.shape))) M, N, P, Q = self.shape for i in range(M): for k in range(P): measvec = np.zeros((np.prod(self.shape),)) for j in range(N): for l in range(Q): measvec[M*N*(P*l + k) + M*j + i] = self.fixed_mat[j, l] out[i + M*k] = np.dot(measvec, mat.flatten(order='F')) if compute_measmat: self._measmat[i+M*k, :] = measvec if compute_measmat: return (out, self._measmat) else: return out
def trace_preserving_constraint(mat_r: Variable, mat_i: Variable) -> List[Constraint]: """Return CVXPY trace preserving constraints for a complex matrix. Args: mat_r: The CVXPY variable for the real part of the matrix. mat_i: The CVXPY variable for the complex part of the matrix. Returns: A list of constraints on the real and imaginary parts. """ sdim = int(np.sqrt(mat_r.shape[0])) ptr = partial_trace_super(sdim, sdim) return [ ptr @ cvxpy.vec(mat_r) == np.identity(sdim).ravel(), ptr @ cvxpy.vec(mat_i) == np.zeros(sdim * sdim), ]
def linearize(expr): """Returns the tangent approximation to the expression. Gives an elementwise lower (upper) bound for convex (concave) expressions. No guarantees for non-DCP expressions. Args: expr: An expression. Returns: An affine expression. """ if expr.is_affine(): return expr else: tangent = expr.value if tangent is None: raise ValueError( "Cannot linearize non-affine expression with missing variable values." ) grad_map = expr.grad for var in expr.variables(): if grad_map[var] is None: return None if var.ndim > 1: temp = cvx.reshape(cvx.vec(var - var.value), (var.shape[0] * var.shape[1], 1)) flattened = np.transpose(grad_map[var]) * temp tangent = tangent + cvx.reshape(flattened, expr.shape) else: tangent = tangent + np.transpose(grad_map[var])*(var - var.value) return tangent
def test_matrix_constraint(self) -> None: X = cp.Variable((2, 2), pos=True) a = cp.Parameter(pos=True, value=0.1) obj = cp.Minimize(cp.geo_mean(cp.vec(X))) constr = [cp.diag(X) == a, cp.hstack([X[0, 1], X[1, 0]]) == 2 * a] problem = cp.Problem(obj, constr) gradcheck(problem, gp=True) perturbcheck(problem, gp=True)
def KEDM(param, A): N = param.N d = param.d K = ktools.K_base(param) ########################################################################### MaxIter = 500 verbosity = True ########################################################################### output = KEDM_OUT() tau_list = ktools.generalsampler(param, 'basis') trn_list = ktools.generalsampler(param, 'trn_sample') tst_list = ktools.generalsampler(param, 'tst_sample') log_list = ktools.generalsampler(param, 'log_sample') D, W, ei = ktools.generateData(param, trn_list, A) G = [] con = [] for k in range(K): G.append(cvx.Variable((N, N), PSD=True)) con.append(cvx.sum(G[k], axis=0) == 0) for t in log_list: weights = ktools.W(t, tau_list, param) weights = weights / np.linalg.norm(weights) G_tot = ktools.G_t(G, weights, True) con.append(G_tot >> 0) cost = 0 for i_t, t in enumerate(trn_list): weights = ktools.W(t, tau_list, param) G_tot = ktools.G_t(G, weights, True) con.append(G_tot >> 0) D_G = ktools.gram2edm(G_tot, N, True) W_vec = np.diag(W[i_t].flatten()) alpha = (np.linalg.norm(np.matmul(W_vec, D[i_t].flatten())))**(-2) cost += alpha * cvx.norm(cvx.matmul(W_vec, cvx.vec(D[i_t] - D_G)))**2 obj = cvx.Minimize(cost) prob = cvx.Problem(obj, con) try: prob.solve(solver=cvx.CVXOPT, verbose=False, normalize=True) except Exception as message: print(message) output.status = str(prob.status) if str(prob.status) == 'optimal': G = ktools.rankProj(G, param) eo = ktools.testError(param, tau_list, tst_list, G, A) output.G = G output.tau_list = tau_list output.trn_list = trn_list output.tst_list = tst_list output.ei = ei output.eo = eo output.A = A return output
def gen_data_ndim(nb_datapoints, dim, savefile, rand_seed=7): """Sampling according to Table 1 in manuscript: - uniform point positioning (x) in [0,1] for each dimension - uniform eigenvalues in [-1,1] - ortho-normal basis/matrix (eigvecs) of eigenvectors :param nb_datapoints: how many data points to sample :param dim: dimensionality of SDP sub-problem to sample :param savefile: file to save sampled data in :param rand_seed: random seed, pre-set to 7 :return: None """ np.random.seed(rand_seed) X = cvx.Variable(dim, dim) data_points = [] t_init = timer() t0 = timer() for data_pt_nb in range(1, nb_datapoints + 1): # ortho-normal basis/matrix (eigvecs) of eigenvectors eigvecs = ortho_group.rvs(dim) # uniform eigenvalues in [-1,1] eigvals = np.random.uniform(-1, 1, dim).tolist() # construct sampled Q from eigen-decomposition Q = np.matmul(np.matmul(eigvecs, np.diag(eigvals)), np.transpose(eigvecs)) # uniform point positioning (x) in [0,1] for each dimension x = np.random.uniform(0, 1, dim).tolist() # construct cvx SDP sub-problem obj_sdp = cvx.Minimize(cvx.sum_entries(cvx.mul_elemwise(Q, X))) constraints = [ cvx.lambda_min( cvx.hstack(cvx.vstack(1, np.array(x)), cvx.vstack(cvx.vec(x).T, X))) >= 0, *[X[ids, ids] <= x[ids] for ids in range(0, dim)] ] prob = cvx.Problem(obj_sdp, constraints) # solve it using Mosek SDP solver prob.solve(verbose=False, solver=cvx.MOSEK) # store upper triangular matrix in array (row major) since it is symmetric Q = np.triu(Q, 1) + np.triu(Q, 0) # save eigendecomposition, point positioning, matrix Q and solution of SDP sub-problem data_points.append([ *eigvecs.T.flatten(), *eigvals, *x, *list(Q[np.triu_indices(dim)]), obj_sdp.value ]) # save to file and empty data_points buffer every 1000 entries if not data_pt_nb % 1000: t1 = timer() with open(savefile, "a") as f: for line in data_points: f.write(",".join(str(x) for x in line) + "\n") data_points = [] print( str(data_pt_nb) + " " + str(dim) + "D points, time = " + str(t1 - t0) + "s" + ", total = " + str(t1 - t_init) + "s") t0 = t1
def test_linearize(self) -> None: """Test linearize method. """ # Affine. expr = (2 * self.x - 5)[0] self.x.value = [1, 2] lin_expr = linearize(expr) self.x.value = [55, 22] self.assertAlmostEqual(lin_expr.value, expr.value) self.x.value = [-1, -5] self.assertAlmostEqual(lin_expr.value, expr.value) # Convex. expr = self.A**2 + 5 with self.assertRaises(Exception) as cm: linearize(expr) self.assertEqual( str(cm.exception), "Cannot linearize non-affine expression with missing variable values." ) self.A.value = [[1, 2], [3, 4]] lin_expr = linearize(expr) manual = expr.value + 2 * cp.reshape( cp.diag(cp.vec(self.A)).value @ cp.vec(self.A - self.A.value), (2, 2)) self.assertItemsAlmostEqual(lin_expr.value, expr.value) self.A.value = [[-5, -5], [8.2, 4.4]] assert (lin_expr.value <= expr.value).all() self.assertItemsAlmostEqual(lin_expr.value, manual.value) # Concave. expr = cp.log(self.x) / 2 self.x.value = [1, 2] lin_expr = linearize(expr) manual = expr.value + cp.diag( 0.5 * self.x**-1).value @ (self.x - self.x.value) self.assertItemsAlmostEqual(lin_expr.value, expr.value) self.x.value = [3, 4.4] assert (lin_expr.value >= expr.value).all() self.assertItemsAlmostEqual(lin_expr.value, manual.value)
def _expval(A, x): """@todo: Docstring for _expval. :param A: @todo :param x: @todo :returns: @todo """ # transpose A since cvxpy vectorizes in Fortran order A_map = A.transpose(0, 2, 1).reshape((len(A), -1)) return A_map * cvx.vec(x)
def setup_solver_cvx(self): c = self.constvars imagedims = c['imagedims'] n_image = c['n_image'] d_image = c['d_image'] l_labels = c['l_labels'] l_shm = c['l_shm'] self.cvx_x = Variable( ('p', (l_shm, d_image, n_image)), ('q0', (n_image, )), ('q1', (l_labels, n_image)), ('q2', (l_labels, n_image)), ) self.cvx_y = Variable( ('u1', (n_image, l_labels)), ('v', (n_image, l_shm)), ('misc', (n_image, )), ) p, q0, q1, q2 = [cvxVariable(*a['shape']) for a in self.cvx_x.vars()] self.cvx_vars = p + [q0, q1, q2] fid_fun_dual = 0 for i in range(n_image): for k in range(l_labels): fid_fun_dual += -1.0/c['b'][k]*(cvx.power(q2[k,i],2)/2 \ + cvx.maximum(q2[k,i]*c['b'][k]*c['f1'][i,k], q2[k,i]*c['b'][k]*c['f2'][i,k])) self.cvx_obj = cvx.Maximize(fid_fun_dual - cvx.sum(q0)) div_op = sparse_div_op(imagedims) self.cvx_dual = True self.cvx_constr = [] # u1_constr for i in range(n_image): self.cvx_constr.append(c['b'] * q0[i] - q1[:, i] >= 0) # v_constr for i in range(n_image): for k in range(l_shm): Yk = cvx.vec(c['Y'][:, k]) self.cvx_constr.append( Yk.T*(c['M'][k]*q2[:,i] + q1[:,i]) \ - cvxOp(div_op, p[k], i) == 0) # additional inequality constraints for i in range(n_image): self.cvx_constr.append(sum(cvx.sum_squares(p[k][:,i]) \ for k in range(l_shm)) <= c['lbd']**2)
def sos_to_sdp(syms, poly, z): deg = len(z) A, b = construct_constraints(syms, poly, z) obj = cvx.Minimize(0) q = cvx.Variable(deg * deg, 1) X = Expression.cast_to_const(q) #Find a solution to the equality constraints for setting up the starting strongly feasible point constraints = [-A * q == b] prob = cvx.Problem(obj, constraints) prob.solve() Q0 = np.reshape(np.array(q.value), (deg, deg)) largest_eval = np.max(np.linalg.eigvals(Q0)) if (largest_eval <= 1e-10): return (prob.status, -np.matrix(Q0)) s0 = largest_eval + 10 #initialize starting points Q = cvx.Variable(deg, deg) q = cvx.vec(Q) s = cvx.Variable() Q.value = Q0 s.value = s0 m = b.shape[0] eps = 0.0001 t = 0.1 mu = 1.5 iteration = 1 print("Running barrier method:") while (s.value > 0) and (m / t > eps): obj = cvx.Minimize(s - (1 / t) * atom.log_det(s * np.eye(deg) - Q)) constraints = [-A * q == b, Q == Q.T, q == cvx.vec(Q)] prob = cvx.Problem(obj, constraints) prob.solve() #print(Q.value) #print(obj.value) print("Iteration: {} Value of s: {}".format(iteration, s.value)) t *= mu iteration += 1 return (prob.status, -np.matrix(Q.value))
def linearize(expr, vars=None, grads=None): """Returns the tangent approximation to the expression. Gives an elementwise lower (upper) bound for convex (concave) expressions. No guarantees for non-DCP expressions. Args: expr: An expression. Returns: An affine expression. """ if expr.is_affine(): return expr else: if expr.value is None: raise ValueError( "Cannot linearize non-affine expression with missing variable values." ) if grads is None: grads = {} base_key = str(expr) + 'value' if base_key in grads: grads[ base_key].value = expr.value # Not a grad, but stored here for convenience else: grads[base_key] = cvx.Parameter(expr.value.shape, value=expr.value) tangent = grads[base_key] grad_map = expr.grad for var in expr.variables(): if grad_map[var] is None: return None if vars is not None: vars[var.name()].value = var.value key = str(expr) + var.name() if key in grads: grads[key].value = grad_map[var] else: grads[key] = cvx.Parameter(grad_map[var].shape, value=grad_map[var]) value = var.value if vars is None else vars[var.name()] if var.ndim > 1: temp = cvx.reshape(cvx.vec(var - value), (var.shape[0] * var.shape[1], 1)) flattened = grads[key].T @ temp tangent = tangent + cvx.reshape(flattened, expr.shape) tangent = tangent + cvx.reshape(flattened, expr.shape) else: tangent = tangent + grads[key].T @ (var - value) return tangent
def test_proximal(self): ''' Checks if proximal objective function works. ''' #Define variables x1 = cvx.Variable() x2 = cvx.Variable() x3 = cvx.Variable() x4 = cvx.Variable() #Define slack variable inputs lambd = 1 / 2 slack = cvx.Variable() #Define initialization x1.value = 1 x2.value = 1 x3.value = 0 x4.value = 0 slack.value = 1 / (5e-3) #Define problem obj = cvx.Minimize(cvx.abs(x1 * x2 + x3 * x4)) constr = [x1 + x2 + x3 + x4 == 1] prob = cvx.Problem(obj, constr) #Get proximal problem outputProb = dmcp.proximal_op(prob, [slack], lambd) #Define ground truth test for proximal objective objTest = cvx.Minimize( cvx.abs(x1 * x2 + x3 * x4) + cvx.square(cvx.norm(cvx.vec(x1 - x1.value), 2)) / 2 / lambd + cvx.square(cvx.norm(cvx.vec(x2 - x2.value), 2)) / 2 / lambd + cvx.square(cvx.norm(cvx.vec(x3 - x3.value), 2)) / 2 / lambd + cvx.square(cvx.norm(cvx.vec(x4 - x4.value), 2)) / 2 / lambd) #Assertion Test self.assertAlmostEqual(outputProb.objective.value, objTest.value) self.assertEqual(outputProb.objective.expr.name(), objTest.expr.name())
def linearize(expr): """Returns the tangent approximation to the expression. Gives an elementwise lower (upper) bound for convex (concave) expressions. No guarantees for non-DCP expressions. Args: expr: An expression. Returns: An affine expression. """ if expr.is_affine(): return expr else: if expr.value is None: raise ValueError( "Cannot linearize non-affine expression with missing variable values." ) tangent = np.real(expr.value) #+ np.imag(expr.value) grad_map = expr.grad for var in expr.variables(): if grad_map[var] is None: return None complex_flag = False if var.is_complex() or np.any(np.iscomplex(grad_map[var])): complex_flag = True if var.ndim > 1: temp = cvx.reshape(cvx.vec(var - var.value), (var.shape[0] * var.shape[1], 1)) if complex_flag: flattened = np.transpose(np.real(grad_map[var])) @ cvx.real(temp) + \ np.transpose(np.imag(grad_map[var])) @ cvx.imag(temp) else: flattened = np.transpose(np.real(grad_map[var])) @ temp tangent = tangent + cvx.reshape(flattened, expr.shape) elif var.size > 1: if complex_flag: tangent = tangent + np.transpose(np.real(grad_map[var])) @ (cvx.real(var) - np.real(var.value)) \ + np.transpose(np.imag(grad_map[var])) @ (cvx.imag(var) - np.imag(var.value)) else: tangent = tangent + np.transpose(np.real( grad_map[var])) @ (var - var.value) else: if complex_flag: tangent = tangent + np.real(grad_map[var]) * (cvx.real(var) - np.real(var.value)) \ + np.imag(grad_map[var]) * (cvx.imag(var) - np.imag(var.value)) else: tangent = tangent + np.real( grad_map[var]) * (var - var.value) return tangent
def test_special_idx(self): """Test with special index. """ c = [0, 1] n = len(c) # Create optimization variables. f = cvx.Variable((n, n), hermitian=True) # Create constraints. constraints = [f >> 0] for k in range(1, n): indices = [(i * n) + i - (n - k) for i in range(n - k, n)] constraints += [cvx.sum(cvx.vec(f)[indices]) == c[n - k]] # Form objective. obj = cvx.Maximize(c[0] - cvx.real(cvx.trace(f))) # Form and solve problem. prob = cvx.Problem(obj, constraints) prob.solve()
def norm_mat(self, X): r"""Returns the implementation of the vector norm for matrices. This function uses CVXPY commands to transform the input matrix `X` into a vector and then compute the :math:`\ell_p` norm. Parameters ---------- X : matrix-like The matrix whose vector norm we wish to compute. Returns ------- cvxpy.Expression The CVXPY expression of the :math:`\ell_p` norm. """ return cvxpy.pnorm(cvxpy.vec(X), self.p)
def sos_to_sdp_min(syms, poly, z): deg = len(z) Q = cvx.Semidef(deg) q = cvx.vec(Q) gamma = cvx.Variable() A, b = construct_constraints_min(syms, poly, z) const_val = np.asscalar(b[-1]) - gamma A = A[:-1] b = b[:-1] constraints = [A * q == b, q[0] == const_val] obj = cvx.Maximize(gamma) prob = cvx.Problem(obj, constraints) opt_val = prob.solve(solver=cvx.SCS) Q = np.matrix(Q.value) return (prob.status, opt_val, Q)
def policy_unU(G, R, L, d, x_prev, un_U, gamma): [n,A]=R.shape [m,temp]=d.shape Q = cvxpy.Variable(n,A) M = cvxpy.Variable(n,n) S = cvxpy.Variable(m,n) K = cvxpy.Variable(m,m) # U = cvxpy.Variable(n,1) # y = cvxpy.Variable(m,1) # r = cvxpy.Variable(n,1) xi = cvxpy.Variable(m,1) # z = cvxpy.Variable(1,1) x = cvxpy.Variable(n,1) Kr = cvxpy.kron(np.ones((A,1)),np.eye(n)) # Create two constraints. constraints = [#(d.T) * y - z <= opt_ref, -M + cvxpy.mul_elemwise(G,(np.ones((n, 1)) * cvxpy.vec(Q).T)) * Kr == 0, # -r + cvxpy.mul_elemwise(R,Q) * np.ones((A, 1)) == 0, # -L.T * y + z * np.ones((n, 1)) - U_ref <= 0, # -U + r + gamma * M.T * U_next == 0, -K * L + L * M + xi * np.ones((1, n)) <= 0, xi + d - K * d >= 0, x - M * x_prev == 0, Q * np.ones((A, 1)) - np.ones((n, 1)) == 0, Q >= 0, #np.zeros((n, A)), # y >= 0, # np.zeros((m, 1)), K >= 0, #np.zeros((m, m)), x >= 0, x.T * np.ones((n, 1)) - 1 == 0 ] # Form objective. obj = cvxpy.Minimize(-(x.T) * un_U) # Form and solve problem. prob = cvxpy.Problem(obj, constraints) # prob.solve(solver = cvxpy.MOSEK, verbose = True) prob.solve(solver = cvxpy.ECOS, verbose = False, max_iters = 1000) # prob.solve(solver = cvxpy.SCS, verbose = False) return Q.value, M.value, x.value
def policy(G, R, L, d, un_Q, un_M, un_U, U_next, U_ref, opt_ref, gamma): [n,A]=R.shape [m,temp]=d.shape Q = cvxpy.Variable(n,A) M = cvxpy.Variable(n,n) S = cvxpy.Variable(m,n) K = cvxpy.Variable(m,m) U = cvxpy.Variable(n,1) y = cvxpy.Variable(m,1) r = cvxpy.Variable(n,1) xi = cvxpy.Variable(m,1) z = cvxpy.Variable(1,1) Kr = cvxpy.kron(np.ones((A,1)),np.eye(n)) # Create two constraints. constraints = [(d.T) * y - z <= opt_ref, -M + cvxpy.mul_elemwise(G,(np.ones((n, 1)) * cvxpy.vec(Q).T)) * Kr == 0, -r + cvxpy.mul_elemwise(R,Q) * np.ones((A, 1)) == 0, -L.T * y + z * np.ones((n, 1)) - U_ref <= 0, -U + r + gamma * M.T * U_next == 0, -K * L + L * M + S + xi * np.ones((1, n)) == 0, xi + d - K * d >= 0, Q * np.ones((A, 1)) - np.ones((n, 1)) == 0, Q >= np.zeros((n, A)), y >= np.zeros((m, 1)), S >= np.zeros((m, n)), K >= np.zeros((m, m)), M >= np.zeros((n, n)) ] # Form objective. obj = cvxpy.Minimize(cvxpy.norm((Q - un_Q), 'fro')) # obj = cvxpy.Minimize(cvxpy.norm((M - un_M), 'fro')) # obj = cvxpy.Minimize(cvxpy.norm((U - un_U))) # Form and solve problem. prob = cvxpy.Problem(obj, constraints) prob.solve(solver = cvxpy.ECOS, verbose = False, max_iters = 2000, feastol = 1e-4, reltol = 1e-4, abstol = 1e-4) # prob.solve(solver = cvxpy.CVXOPT, verbose = True) return U.value, Q.value, M.value
def policy(G, R, L, d, U_next, gamma): [n,A]=R.shape [m,temp]=d.shape Q = cvxpy.Variable(n,A) M = cvxpy.Variable(n,n) S = cvxpy.Variable(m,n) K = cvxpy.Variable(m,m) U = cvxpy.Variable(n,1) y = cvxpy.Variable(m,1) r = cvxpy.Variable(n,1) xi = cvxpy.Variable(m,1) z = cvxpy.Variable(1,1) Kr = cvxpy.kron(np.ones((A,1)),np.eye(n)) # Create two constraints. constraints = [-M + cvxpy.mul_elemwise(G, (np.ones((n, 1)) * cvxpy.vec(Q).T)) * Kr == 0, -r + cvxpy.mul_elemwise(R,Q) * np.ones((A, 1)) == 0, -L.T * y + z * np.ones((n, 1)) - U <= 0, -U + r + gamma * M.T * U_next == 0, -K * L + L * M + xi * np.ones((1, n)) <= 0, xi + d - K * d >= 0, Q * np.ones((A, 1)) - np.ones((n, 1)) == 0, Q >= 0, #np.zeros((n, A)), y >= 0, #np.zeros((m, 1)), K >= 0, #np.zeros((m, m)), ] # Form objective. obj = cvxpy.Minimize((d.T) * y - z) # Form and solve problem. prob = cvxpy.Problem(obj, constraints) # prob.solve(solver = cvxpy.MOSEK, verbose = True) # prob.solve(solver = cvxpy.CVXOPT, verbose = True) prob.solve(solver = cvxpy.ECOS, verbose = True, max_iters = 2000, feastol = 1e-4, reltol = 1e-4, abstol = 1e-4) # prob.solve(solver = cvxpy.SCS, verbose = False) return U.value, Q.value, M.value, ((d.T) * y - z).value
def KEDM(param, A): N = param.N d = param.d K = ktools.K_base(param) ########################################################################### MaxIter = 500 verbosity = True ########################################################################### output = KEDM_OUT() tau_list = ktools.generalsampler(param, 'basis') trn_list = ktools.generalsampler(param, 'trn_sample') tst_list = ktools.generalsampler(param, 'tst_sample') log_list = ktools.generalsampler(param, 'log_sample') D, W, ei = ktools.generateData(param, trn_list, A) G = [] con = [] for k in range(K): G.append(cvx.Variable((N, N), PSD=True)) con.append(cvx.sum(G[k],axis = 0) == 0) for t in log_list: weights = ktools.W(t, tau_list, param) weights = weights/np.linalg.norm(weights) G_tot = ktools.G_t(G, weights, True) con.append(G_tot>>0) cost = 0 for i_t, t in enumerate(trn_list): weights = ktools.W(t, tau_list, param) G_tot = ktools.G_t(G, weights, True) con.append(G_tot >> 0) D_G = ktools.gram2edm(G_tot, N, True) W_vec = np.diag(W[i_t].flatten()) alpha = (np.linalg.norm( np.matmul(W_vec, D[i_t].flatten()) ) )**(-2) cost += alpha*cvx.norm( cvx.matmul(W_vec, cvx.vec(D[i_t]-D_G) ) )**2 obj = cvx.Minimize(cost) prob = cvx.Problem(obj,con)
def test_lplcn_ghost(): def laplop(m, n): ddn = sp.spdiags( np.ones(n) * np.array([[1, -2, 1]]).T, [-1, 0, 1], n, n) ddm = sp.spdiags( np.ones(m) * np.array([[1, -2, 1]]).T, [-1, 0, 1], m, m) return sp.kron(ddm, sp.eye(n, n)) + sp.kron(sp.eye(m, m), ddn) imagedims = np.array((30, 40)) data = np.random.rand(*imagedims) op = LaplacianOp(imagedims, 1, boundary="curvature") Dy_curv = op.y.new().reshape(imagedims) op(data, Dy_curv) gimagedims = imagedims + 2 A = cp.Constant(laplop(*gimagedims[::-1])) y = cp.Variable(gimagedims) Dy = cp.reshape(A * cp.vec(y), gimagedims) cp.Problem(cp.Minimize(cp.sum_squares(Dy[1:-1, 1:-1])), [y[1:-1, 1:-1] == data]).solve() Dy_ghost = Dy.value assert np.linalg.norm(Dy_curv - Dy_ghost[1:-1, 1:-1], ord=np.inf) < 1e-12
def get_error(noncvx_vars, eps, rel_eps): """The error bound for comparing infeasibility. """ error = sum([cvx.norm(cvx.vec(var)) for var in noncvx_vars]).value return eps + rel_eps*error
point_x_e[i] = -1 * length + length_setion * (i % n_srt) + length_setion point_y_e[i] = length - length_setion - length_setion * (i // n_srt) radius_p = 2 * length / np.sqrt(n * np.pi) r = [radius_p for i in range(n)] radius = 1.5 c = cvx.Variable((n, 2)) constr = [] for i in range(n - 1): for j in range(i + 1, n): constr.append( cvx.norm(cvx.vec(c[i, :] - c[j, :]), 2) >= r[i] + r[j]) prob = cvx.Problem(cvx.Minimize(cvx.max(cvx.max(cvx.abs(c), axis=1) + r)), constr) prob.solve(method='dccp', solver='ECOS', ep=1e-2, max_slack=1e-2) point_e = np.column_stack((point_x_e, point_y_e)) point_t = np.column_stack((point_x_t, point_y_t)) point_c = np.column_stack((point_x_c, point_y_c)) z_t = np.zeros((n, 1)) z_e = np.zeros((n, 1)) z_c = np.zeros((n, 1)) firing_position_x_t = np.zeros((n, nsteps)) firing_position_y_t = np.zeros((n, nsteps)) firing_position_x_e = np.zeros((n, nsteps))
__author__ = 'Xinyue' import cvxpy as cvx import numpy as np import matplotlib.pyplot as plt import dccp np.random.seed(0) n = 10 r = np.linspace(1, 5, n) c = cvx.Variable((n, 2)) constr = [] for i in range(n - 1): for j in range(i + 1, n): constr.append(cvx.norm(cvx.vec(c[i, :] - c[j, :]), 2) >= r[i] + r[j]) prob = cvx.Problem(cvx.Minimize(cvx.max(cvx.max(cvx.abs(c), axis=1) + r)), constr) prob.solve(method='dccp', solver='ECOS', ep=1e-2, max_slack=1e-2) l = cvx.max(cvx.max(cvx.abs(c), axis=1) + r).value * 2 pi = np.pi ratio = pi * cvx.sum(cvx.square(r)).value / cvx.square(l).value print "ratio =", ratio # plot plt.figure(figsize=(5, 5)) circ = np.linspace(0, 2 * pi) x_border = [-l / 2, l / 2, l / 2, -l / 2, -l / 2] y_border = [-l / 2, -l / 2, l / 2, l / 2, -l / 2] for i in xrange(n): plt.plot(c[i, 0].value + r[i] * np.cos(circ), c[i, 1].value + r[i] * np.sin(circ), 'b') plt.plot(x_border, y_border, 'g')
def dist(self, matrix): """Distance from matrix to projection. """ proj_mat = self.project(matrix) return cvxpy.norm(cvxpy.vec(matrix - proj_mat), 2).value
def cvx_fit(data: np.array, basis_matrix: np.array, weights: Optional[np.array] = None, psd: bool = True, trace: Optional[int] = None, trace_preserving: bool = False, **kwargs) -> np.array: r""" Reconstruct a quantum state using CVXPY convex optimization. **Objective function** This fitter solves the constrained least-squares minimization: :math:`minimize: ||a * x - b ||_2` subject to: * :math:`x >> 0` (PSD, optional) * :math:`\text{trace}(x) = t` (trace, optional) * :math:`\text{partial_trace}(x)` = identity (trace_preserving, optional) where: * a is the matrix of measurement operators :math:`a[i] = vec(M_i).H` * b is the vector of expectation value data for each projector :math:`b[i] ~ \text{Tr}[M_i.H * x] = (a * x)[i]` * x is the vectorized density matrix (or Choi-matrix) to be fitted **PSD constraint** The PSD keyword constrains the fitted matrix to be postive-semidefinite, which makes the optimization problem a SDP. If PSD=False the fitted matrix will still be constrained to be Hermitian, but not PSD. In this case the optimization problem becomes a SOCP. **Trace constraint** The trace keyword constrains the trace of the fitted matrix. If trace=None there will be no trace constraint on the fitted matrix. This constraint should not be used for process tomography and the trace preserving constraint should be used instead. **Trace preserving (TP) constraint** The trace_preserving keyword constrains the fitted matrix to be TP. This should only be used for process tomography, not state tomography. Note that the TP constraint implicitly enforces the trace of the fitted matrix to be equal to the square-root of the matrix dimension. If a trace constraint is also specified that differs from this value the fit will likely fail. **CVXPY Solvers** Various solvers can be called in CVXPY using the `solver` keyword argument. See the `CVXPY documentation <https://www.cvxpy.org/tutorial/advanced/index.html#solve-method-options>`_ for more information on solvers. Args: data: (vector like) vector of expectation values basis_matrix: (matrix like) measurement operators weights: (vector like) weights to apply to the objective function (default: None) psd: (default: True) enforces the fitted matrix to be positive semidefinite (default: True) trace: trace constraint for the fitted matrix (default: None). trace_preserving: (default: False) Enforce the fitted matrix to be trace preserving when fitting a Choi-matrix in quantum process tomography (default: False). **kwargs: kwargs for cvxpy solver. Raises: ImportError: if cvxpy is not present RuntimeError: In case cvx fitting failes Returns: The fitted matrix rho that minimizes :math:`||basis_matrix * vec(rho) - data||_2`. """ # Check if CVXPY package is installed if not _HAS_CVX: raise ImportError("The CVXPY package is required to use the cvx_fit() " "function. You can install it with 'pip install " "cvxpy' or use a `lstsq` fitter instead of cvx_fit.") # SDP VARIABLES # Since CVXPY only works with real variables we must specify the real # and imaginary parts of rho seperately: rho = rho_r + 1j * rho_i dim = int(np.sqrt(basis_matrix.shape[1])) rho_r = cvxpy.Variable((dim, dim), symmetric=True) rho_i = cvxpy.Variable((dim, dim)) # CONSTRAINTS # The constraint that rho is Hermitian (rho.H = rho) # transforms to the two constraints # 1. rho_r.T = rho_r.T (real part is symmetric) # 2. rho_i.T = -rho_i.T (imaginary part is anti-symmetric) cons = [rho_i == -rho_i.T] # Trace constraint: note this should not be used at the same # time as the trace preserving constraint. if trace is not None: cons.append(cvxpy.trace(rho_r) == trace) # Since we can only work with real matrices in CVXPY we can specify # a complex PSD constraint as # rho >> 0 iff [[rho_r, -rho_i], [rho_i, rho_r]] >> 0 if psd is True: rho = cvxpy.bmat([[rho_r, -rho_i], [rho_i, rho_r]]) cons.append(rho >> 0) # Trace preserving constraint when fitting Choi-matrices for # quantum process tomography. Note that this adds an implicity # trace constraint of trace(rho) = sqrt(len(rho)) = dim # if a different trace constraint is specified above this will # cause the fitter to fail. if trace_preserving is True: sdim = int(np.sqrt(dim)) ptr = partial_trace_super(sdim, sdim) cons.append(ptr @ cvxpy.vec(rho_r) == np.identity(sdim).ravel()) cons.append(ptr @ cvxpy.vec(rho_i) == np.zeros(sdim * sdim)) # Rescale input data and matrix by weights if they are provided if weights is not None: w = np.array(weights) w = w / np.sqrt(sum(w**2)) basis_matrix = w[:, None] * basis_matrix data = w * data # OBJECTIVE FUNCTION # The function we wish to minimize is || arg ||_2 where # arg = bm * vec(rho) - data # Since we are working with real matrices in CVXPY we expand this as # bm * vec(rho) = (bm_r + 1j * bm_i) * vec(rho_r + 1j * rho_i) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # + 1j * (bm_r * vec(rho_i) + bm_i * vec(rho_r)) # = bm_r * vec(rho_r) - bm_i * vec(rho_i) # where we drop the imaginary part since the expectation value is real bm_r = np.real(basis_matrix) bm_i = np.imag(basis_matrix) # CVXPY doesn't seem to handle sparse matrices very well so we convert # sparse matrices to Numpy arrays. if isinstance(basis_matrix, sps.spmatrix): bm_r = bm_r.todense() bm_i = bm_i.todense() arg = bm_r @ cvxpy.vec(rho_r) - bm_i @ cvxpy.vec(rho_i) - np.array(data) # SDP objective function obj = cvxpy.Minimize(cvxpy.norm(arg, p=2)) # Solve SDP prob = cvxpy.Problem(obj, cons) iters = 5000 max_iters = kwargs.get('max_iters', 20000) # Set default solver if none is specified if 'solver' not in kwargs: if 'CVXOPT' in cvxpy.installed_solvers(): kwargs['solver'] = 'CVXOPT' elif 'MOSEK' in cvxpy.installed_solvers(): kwargs['solver'] = 'MOSEK' problem_solved = False while not problem_solved: kwargs['max_iters'] = iters prob.solve(**kwargs) if prob.status in ["optimal_inaccurate", "optimal"]: problem_solved = True elif prob.status == "unbounded_inaccurate": if iters < max_iters: iters *= 2 else: raise RuntimeError( "CVX fit failed, probably not enough iterations for the " "solver") elif prob.status in ["infeasible", "unbounded"]: raise RuntimeError( "CVX fit failed, problem status {} which should not " "happen".format(prob.status)) else: raise RuntimeError("CVX fit failed, reason unknown") rho_fit = rho_r.value + 1j * rho_i.value return rho_fit
def optimize(p0, d, L, w, options): # print('Vxf', Vxf) # n, T = Vxf['n'], options['max_iter'] # x = cvx.Variable(n, T+1) # states of the system # for t in range(T): if L == -1: #SOS Vxf['n'] = np.sqrt(matlength(p) / d**2) Vxf['d'] = d Vxf['P'] = p.reshape(Vxf['n'] * d, Vxf['n'] * d) Vxf['SOS'] = 1 else: Vxf = shape_DS(p0, d, L, options) Vxf.update(Vxf) _, Vx = computeEnergy(x, np.array(()), Vxf, nargout=2) # xd will be 2 x 750 # Vx should be (2, 750), # Vdot (750,) for expt 0, Vdot = np.sum(Vx * xd, axis=0) #derivative of J w.r.t. xd norm_Vx = np.sqrt(np.sum(Vx * Vx, axis=0)) norm_xd = np.sqrt(np.sum(xd * xd, axis=0)) # print('Vx: {}, Vdot, {} norm_Vx, {}, xd: {}, norm_xd: {}, butt: {}'.format(Vx.shape, Vdot.shape, # norm_Vx.shape, (xd).shape, norm_xd.shape, butt.shape) ) # x: (2, 750), xd (2, 750) # Vx: (2, 750), Vdot, (750,) norm_Vx, (750,), norm_xd: (750,), xd: (2, 750), butt: (750, 750) # expand arrays to fit suppose shape Vdot = np.expand_dims(Vdot, axis=0) norm_Vx = np.expand_dims(norm_Vx, axis=0) norm_xd = np.expand_dims(norm_xd, axis=0) butt = norm_Vx * norm_xd # w was added by Lekan to regularize the invalid values in butt J = Vdot / (butt + w) J[np.where(norm_xd == 0)] = 0 J[np.where(norm_Vx == 0)] = 0 J[np.where(Vdot > 0)] = J[np.where(Vdot > 0)]**2 # solves psi(t,n)**2 J[np.where(Vdot < 0)] = -w * J[np.where( Vdot < 0)]**2 # # J should be (1, 750) # print('J: ', J.shape) J = np.sum(J, axis=1) # Jsum would be of shape (1,) print('J sum: ', J[0]) # print('Vxf: ', -Vxf['P'], 'L: ', L) constraints = [] for l in range(L): # constraints.append(cvx.Parameter(Vxf['P'][:,:,l]>0)) constraints.append(Vxf['P'][:, :, l] > 0) # The 'minimize' objective must resolve to a scalar. J_var = cvx.Variable(cvx.vec(J)) obj = cvx.Minimize(J) prob = cvx.Problem(obj) #, constraints) optionsAlg = { 'maxiters': options['max_iter'], 'show_progress': True, 'refinement': 1, 'abstol': 1e-12, 'reltol': 1e-10, 'feastol': 1e-7, } prob.solve(verbose=True) #, options=optionsAlg)solver=SCS, # prob.solve() return prob #.status, prob.value, J.value
__author__ = 'Xinyue' import cvxpy as cvx import numpy as np import matplotlib.pyplot as plt import dccp np.random.seed(0) n = 10 r = np.linspace(1, 5, n) c = cvx.Variable((n,2)) constr = [] for i in range(n-1): for j in range(i+1, n): constr.append(cvx.norm(cvx.vec(c[i,:]-c[j,:]), 2) >= r[i]+r[j]) prob = cvx.Problem(cvx.Minimize(cvx.max(cvx.max(cvx.abs(c), axis=1) + r)), constr) prob.solve(method = 'dccp', solver='ECOS', ep = 1e-2, max_slack = 1e-2) l = cvx.max(cvx.max(cvx.abs(c),axis=1)+r).value*2 pi = np.pi ratio = pi*cvx.sum(cvx.square(r)).value/cvx.square(l).value print "ratio =", ratio # plot plt.figure(figsize=(5,5)) circ = np.linspace(0,2*pi) x_border = [-l/2, l/2, l/2, -l/2, -l/2] y_border = [-l/2, -l/2, l/2, l/2, -l/2] for i in xrange(n): plt.plot(c[i,0].value+r[i]*np.cos(circ),c[i,1].value+r[i]*np.sin(circ),'b') plt.plot(x_border,y_border,'g') plt.axes().set_aspect('equal') plt.xlim([-l/2,l/2])