def quad_over_lin(self, solver): p = Problem(Minimize(0.5 * quad_over_lin(abs(self.x - 1), 1)), [self.x <= -1]) s = self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(numpy.array([-1., -1.]), s.primal_vars[var.id]) for con in p.constraints: self.assertItemsAlmostEqual(numpy.array([2., 2.]), s.dual_vars[con.id])
def test_choose(): """Test choose variable.""" x = Variable((5, 4)) y = Choose((5, 4), k=4) p = Problem(Minimize(sum(1 - x) + sum(x)), [x == y]) result = p.solve(**solve_args) assert result[0] == approx(20) for v in np.nditer(x.value): assert v * (1 - v) == approx(0) assert x.value.sum() == approx(4)
def test_partial_optimize_dcp(self): """Test DCP properties of partial optimize. """ # Evaluate the 1-norm in the usual way (i.e., in epigraph form). dims = 3 x, t = Variable(dims), Variable(dims) xval = [-5] * dims p2 = Problem(cvxpy.Minimize(sum_entries(t)), [-t <= x, x <= t]) g = cvxpy.partial_optimize(p2, [t], [x]) self.assertEqual(g.curvature, s.CONVEX) p2 = Problem(cvxpy.Maximize(sum_entries(t)), [-t <= x, x <= t]) g = cvxpy.partial_optimize(p2, [t], [x]) self.assertEqual(g.curvature, s.CONCAVE) p2 = Problem(cvxpy.Maximize(square(t[0])), [-t <= x, x <= t]) g = cvxpy.partial_optimize(p2, [t], [x]) self.assertEquals(g.is_convex(), False) self.assertEquals(g.is_concave(), False)
def quad_form_coeff(self, solver): numpy.random.seed(0) A = numpy.random.randn(5, 5) z = numpy.random.randn(5, 1) P = A.T.dot(A) q = -2 * P.dot(z) p = Problem(Minimize(QuadForm(self.w, P) + q.T * self.w)) qp_solution = self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(z, qp_solution.primal_vars[var.id])
def quad_over_lin(self, solver): p = Problem(Minimize(0.5 * quad_over_lin(abs(self.x-1), 1)), [self.x <= -1]) self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(np.array([-1., -1.]), var.value, places=4) for con in p.constraints: self.assertItemsAlmostEqual(np.array([2., 2.]), con.dual_value, places=4)
def test_quad_over_lin(self) -> None: """Test quad_over_lin atom. """ P = np.array([[10, 1j], [-1j, 10]]) X = Variable((2, 2), complex=True) b = 1 y = Variable(complex=False) value = cp.quad_over_lin(P, b).value expr = cp.quad_over_lin(X, y) prob = Problem(cp.Minimize(expr), [X == P, y == b]) result = prob.solve(solver=cp.SCS, eps=1e-6, max_iters=7500, verbose=True) self.assertAlmostEqual(result, value, places=3) expr = cp.quad_over_lin(X - P, y) prob = Problem(cp.Minimize(expr), [y == b]) result = prob.solve(solver=cp.SCS, eps=1e-6, max_iters=7500, verbose=True) self.assertAlmostEqual(result, 0, places=3) self.assertItemsAlmostEqual(X.value, P, places=3)
def test_params(self): """Test with parameters. """ p = cvx.Parameter(imag=True, value=1j) x = Variable(2, complex=True) prob = Problem(cvx.Maximize(cvx.sum(cvx.imag(x) + cvx.real(x))), [cvx.abs(p*x) <= 2]) result = prob.solve() self.assertAlmostEqual(result, 4*np.sqrt(2)) val = np.ones(2)*np.sqrt(2) self.assertItemsAlmostEqual(x.value, val + 1j*val)
def quad_form_coeff(self, solver): np.random.seed(0) A = np.random.randn(5, 5) z = np.random.randn(5) P = A.T.dot(A) q = -2*P.dot(z) p = Problem(Minimize(QuadForm(self.w, P) + q.T*self.w)) self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(z, var.value, places=4)
def quad_form_bound(self, solver): P = np.array([[13, 12, -2], [12, 17, 6], [-2, 6, 12]]) q = np.array([[-22], [-14.5], [13]]) r = 1 y_star = np.array([[1], [0.5], [-1]]) p = Problem(Minimize(0.5*QuadForm(self.y, P) + q.T*self.y + r), [self.y >= -1, self.y <= 1]) self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(y_star, var.value, places=4)
def test_square_param(self): """Test issue arising with square plus parameter. """ a = Parameter(value=1) b = Variable() obj = Minimize(b**2 + abs(a)) prob = Problem(obj) prob.solve() self.assertAlmostEqual(obj.value, 1.0)
def huber_small(self, solver): # Solve the Huber regression problem x = Variable(3) objective = sum(huber(x)) # Solve problem with QP p = Problem(Minimize(objective), [x[2] >= 3]) s = self.solve_QP(p, solver) self.assertAlmostEqual(3, x.value[2], places=4) self.assertAlmostEqual(5, objective.value, places=4)
def quad_form_bound(self, solver): P = numpy.matrix([[13, 12, -2], [12, 17, 6], [-2, 6, 12]]) q = numpy.matrix([[-22], [-14.5], [13]]) r = 1 y_star = numpy.matrix([[1], [0.5], [-1]]) p = Problem(Minimize(0.5 * QuadForm(self.y, P) + q.T * self.y + r), [self.y >= -1, self.y <= 1]) s = self.solve_QP(p, solver) for var in p.variables(): self.assertItemsAlmostEqual(y_star, s.primal_vars[var.id])
def test_abs(self) -> None: """Test with absolute value. """ x = Variable(2, complex=True) prob = Problem(cp.Maximize(cp.sum(cp.imag(x) + cp.real(x))), [cp.abs(x) <= 2]) result = prob.solve(solver="SCS", eps=1e-6) self.assertAlmostEqual(result, 4 * np.sqrt(2)) val = np.ones(2) * np.sqrt(2) self.assertItemsAlmostEqual(x.value, val + 1j * val)
def cvxpy_solve_qp(P, q, G=None, h=None, A=None, b=None, initvals=None, solver=None): """ Solve a Quadratic Program defined as: minimize (1/2) * x.T * P * x + q.T * x subject to G * x <= h A * x == b calling a given solver using the CVXPY <http://www.cvxpy.org/> modelling language. Parameters ---------- P : array, shape=(n, n) Primal quadratic cost matrix. q : array, shape=(n,) Primal quadratic cost vector. G : array, shape=(m, n) Linear inequality constraint matrix. h : array, shape=(m,) Linear inequality constraint vector. A : array, shape=(meq, n), optional Linear equality constraint matrix. b : array, shape=(meq,), optional Linear equality constraint vector. initvals : array, shape=(n,), optional Warm-start guess vector (not used). solver : string, optional Solver name in ``cvxpy.installed_solvers()``. Returns ------- x : array, shape=(n,) Solution to the QP, if found, otherwise ``None``. """ global __verbose__ if initvals is not None: print("CVXPY: note that warm-start values are ignored by wrapper") n = q.shape[0] x = Variable(n) P = Constant(P) # see http://www.cvxpy.org/en/latest/faq/ objective = Minimize(0.5 * quad_form(x, P) + q * x) constraints = [] if G is not None: constraints.append(G * x <= h) if A is not None: constraints.append(A * x == b) prob = Problem(objective, constraints) prob.solve(solver=solver, verbose=__verbose__) x_opt = array(x.value).reshape((n,)) return x_opt
def exp_cone(self) -> None: """Test exponential cone problems. """ for solver in self.solvers: # Basic. p = Problem(Minimize(self.b), [exp(self.a) <= self.b, self.a >= 1]) pmod = Problem(Minimize(self.b), [ExpCone(self.a, Constant(1), self.b), self.a >= 1]) self.assertTrue(ConeMatrixStuffing().accepts(pmod)) p_new = ConeMatrixStuffing().apply(pmod) if not solver.accepts(p_new[0]): return result = p.solve(solver.name()) sltn = solve_wrapper(solver, p_new[0]) self.assertAlmostEqual(sltn.opt_val, result, places=1) inv_sltn = ConeMatrixStuffing().invert(sltn, p_new[1]) self.assertAlmostEqual(inv_sltn.opt_val, result, places=1) for var in pmod.variables(): self.assertItemsAlmostEqual(inv_sltn.primal_vars[var.id], var.value, places=1) # More complex. p = Problem(Minimize(self.b), [ exp(self.a / 2 + self.c) <= self.b + 5, self.a >= 1, self.c >= 5 ]) pmod = Problem(Minimize(self.b), [ ExpCone(self.a / 2 + self.c, Constant(1), self.b + 5), self.a >= 1, self.c >= 5 ]) self.assertTrue(ConeMatrixStuffing().accepts(pmod)) result = p.solve(solver.name()) p_new = ConeMatrixStuffing().apply(pmod) sltn = solve_wrapper(solver, p_new[0]) self.assertAlmostEqual(sltn.opt_val, result, places=0) inv_sltn = ConeMatrixStuffing().invert(sltn, p_new[1]) self.assertAlmostEqual(inv_sltn.opt_val, result, places=0) for var in pmod.variables(): self.assertItemsAlmostEqual(inv_sltn.primal_vars[var.id], var.value, places=0)
def test_news_vendor(self): # Create problem data. c, s, r, b = 10, 25, 5, 150 d_probs = [0.5, 0.5] d_vals = [55, 139] d = CategoricalRandomVariable(d_vals, d_probs) # Create optimization variables. x = NonNegative() y, z = NonNegative(), NonNegative() # Create second stage problem. obj = -s * y - r * z constrs = [y + z <= x, z <= d] # Putting these constrs in breaks the test: # y<=d, z<=d p2 = Problem(Minimize(obj), constrs) Q = partial_optimize(p2, [y, z], [x]) # Create and solve first stage problem p1 = Problem(Minimize(c * x + expectation(Q, want_de=True)), [x <= b]) p1.solve() # Solve problem the old way (i.e., deterministic equivalent) as a check. x = Variable() y1 = Variable() y2 = Variable() z1 = Variable() z2 = Variable() p3 = Problem( Minimize(c * x + 0.5 * (-r * y1 - s * z1) + 0.5 * (-r * y2 - s * z2)), [ 0 <= x, x <= b, 0 <= y1, 0 <= z1, 0 <= y2, 0 <= z2, y1 + z1 <= x, y2 + z2 <= x ]) # Putting these constrs in breaks the test: # y1 <= 55, y2 <= 139, z1 <= 55, z2 <= 139 p3.solve() self.assertAlmostEqual(p1.value, p3.value, 4)
def calc_Koopman(Yf, Yp, flag=1): solver_instance = cvxpy.CVXOPT #solver_instance = cvxpy.ECOS; if flag == 1: # moore penrose inverse, plain ol' least squares Koopman #Yp_inv = np.dot(np.transpose(Yp_final), np.linalg.inv( np.dot(Yp_final,np.transpose(Yp_final)) ) ); Yp_inv = np.linalg.pinv(Yp) K = np.dot(Yf, Yp_inv) if flag == 2: # cvx optimization approach - L2 + L1 lasso norm1_term = 0.0 all_col_handles = [None] * Yf.shape[0] for i in range(0, Yf.shape[0]): all_col_handles[i] = Variable(Yf.shape[0], 1) norm1_term = norm1_term + norm2(all_col_handles[i]) operator = all_col_handles[0] for i in range(1, Yf.shape[0]): operator = cvxpy.hstack(operator, all_col_handles[i]) print "[INFO]: CVXPY Koopman operator variable: " + repr(operator) print "[INFO]: Yf.shape in calc_Koopman: " + repr(Yf.shape) norm2_fit_term = norm2(norm2(Yf - operator * Yp, axis=0)) objective = Minimize(norm2_fit_term + norm1_term) constraints = [] prob = Problem(objective, constraints) result = prob.solve(verbose=True, solver=solver_instance) print "[INFO]: Finished executing cvx solver, printing CVXPY problem status" print(prob.status) K = operator.value if flag == 3: operator = Variable(Yf.shape[0], Yf.shape[0]) objective = Minimize(cvxpynorm(operator, 2)) constraints = [ cvxpynorm(Yf - operator * Yp, 'fro') / cvxpynorm(Yf, 'fro') < 0.01 ] prob = Problem(objective, constraints) result = prob.solve(verbose=True) #(solver=solver_instance); print(prob.status) K = operator.value return K
def sparse_system(self, solver): m = 100 n = 80 np.random.seed(1) density = 0.4 A = sp.rand(m, n, density) b = np.random.randn(m) p = Problem(Minimize(sum_squares(A * self.xs - b)), [self.xs == 0]) self.solve_QP(p, solver) self.assertAlmostEqual(b.T.dot(b), p.value, places=4)
def test_log_det(self): """Test log det. """ P = np.arange(9) - 2j*np.arange(9) P = np.reshape(P, (3, 3)) P = np.conj(P.T).dot(P)/100 + np.eye(3)*.1 value = cvx.log_det(P).value X = Variable((3, 3), complex=True) prob = Problem(cvx.Maximize(cvx.log_det(X)), [X == P]) result = prob.solve(solver=cvx.SCS, eps=1e-6) self.assertAlmostEqual(result, value, places=2)
def test_geo_mean(self): """Test domain for geo_mean """ dom = geo_mean(self.x).domain prob = Problem(Minimize(sum_entries(self.x)), dom) prob.solve() self.assertAlmostEqual(prob.value, 0) # No special case for only one weight. dom = geo_mean(self.x, [0, 2]).domain dom.append(self.x >= -1) prob = Problem(Minimize(sum_entries(self.x)), dom) prob.solve() self.assertItemsAlmostEqual(self.x.value, [-1, 0]) dom = geo_mean(self.z, [0, 1, 1]).domain dom.append(self.z >= -1) prob = Problem(Minimize(sum_entries(self.z)), dom) prob.solve() self.assertItemsAlmostEqual(self.z.value, [-1, 0, 0])
def test_nonneg_constraints_backend(self) -> None: x = Variable(shape=(2, ), name='x') objective = Maximize(-4 * x[0] - 5 * x[1]) constr_expr = hstack( [3 - (2 * x[0] + x[1]), 3 - (x[0] + 2 * x[1]), x[0], x[1]]) constraints = [NonNeg(constr_expr)] prob = Problem(objective, constraints) self.assertFalse(ConeMatrixStuffing().accepts(prob)) self.assertTrue(FlipObjective().accepts(prob)) p_min = FlipObjective().apply(prob) self.assertTrue(ConeMatrixStuffing().accepts(p_min[0]))
def test_card(self): x = Card(5, k=3) p = Problem(Maximize(sum(x)), [x <= 1, x >= 0]) result = p.solve(method="admm") self.assertAlmostEqual(result, 3) for v in np.nditer(x.value): self.assertAlmostEqual(v * (1 - v), 0) self.assertAlmostEqual(x.value.sum(), 3) #should be equivalent to x == choose x = Variable(5, 4) c = Card(5, 4, k=4) b = Boolean(5, 4) p = Problem(Minimize(sum(1 - x) + sum(x)), [x == c, x == b]) result = p.solve(method="admm", solver=CVXOPT) self.assertAlmostEqual(result, 20) for i in range(x.size[0]): for j in range(x.size[1]): v = x.value[i, j] self.assertAlmostEqual(v * (1 - v), 0)
def define_schedule_problem(): """ Define the optimization problem :return: """ demand_schedule = create_demand_schedule() variables = create_variables(plant, demand_schedule) objective = create_objective(variables, demand_schedule) constraints = create_constraints(variables, plant, demand_schedule) problem = Problem(objective, constraints) return problem
def test_choose(self): x = Variable(5,4) p = Problem(Minimize(sum(1-x) + sum(x)), [x == Choose(5,4,k=4)]) result = p.solve(method="admm", solver=CVXOPT) self.assertAlmostEqual(result, 20) for i in range(x.size[0]): for j in range(x.size[1]): v = x.value[i, j] self.assertAlmostEqual(v*(1-v), 0) self.assertAlmostEqual(x.value.sum(), 4)
def run_process(f, pipe): xbar = Parameter(n, value=np.zeros(n)) u = Parameter(n, value=np.zeros(n)) f += (rho/2)*sum_squares(x - xbar + u) prox = Problem(Minimize(f)) # ADMM loop. while True: prox.solve() pipe.send(x.value) xbar.value = pipe.recv() u.value += x.value - xbar.value
def solveX(data): a = data[0:3] u = data[3:6] z = data[6:9] rho = data[9] x = Variable(3, 1) g = square(norm(x - a)) + rho / 2 * square(norm(x - z + u)) objective = Minimize(g) p = Problem(objective, []) result = p.solve() return x.value
def test_rho_init(self): p_list = [Problem(Minimize(norm(self.x)))] rho_list = assign_rho(p_list) self.assertDictEqual(rho_list[0], {self.x.id: 1.0}) rho_list = assign_rho(p_list, default=0.5) self.assertDictEqual(rho_list[0], {self.x.id: 0.5}) rho_list = assign_rho(p_list, rho_init={self.x.id: 1.5}) self.assertDictEqual(rho_list[0], {self.x.id: 1.5}) p_list.append( Problem(Minimize(0.5 * sum_squares(self.y)), [norm(self.x) <= 10])) rho_list = assign_rho(p_list) self.assertDictEqual(rho_list[0], {self.x.id: 1.0}) self.assertDictEqual(rho_list[1], {self.x.id: 1.0, self.y.id: 1.0}) rho_list = assign_rho(p_list, rho_init={self.x.id: 2.0}, default=0.5) self.assertDictEqual(rho_list[0], {self.x.id: 2.0}) self.assertDictEqual(rho_list[1], {self.x.id: 2.0, self.y.id: 0.5})
def sparse_system(self, solver): m = 1000 n = 800 numpy.random.seed(1) density = 0.2 A = sp.rand(m, n, density) b = numpy.random.randn(m, 1) p = Problem(Minimize(sum_squares(A * self.xs - b)), [self.xs == 0]) s = self.solve_QP(p, solver) self.assertAlmostEqual(b.T.dot(b), s.opt_val)
def test_affine_atoms_canon(self): """Test canonicalization for affine atoms. """ # Scalar. x = Variable() expr = cvx.imag(x + 1j * x) prob = Problem(Minimize(expr), [x >= 0]) result = prob.solve() self.assertAlmostEqual(result, 0) self.assertAlmostEqual(x.value, 0) x = Variable(imag=True) expr = 1j * x prob = Problem(Minimize(expr), [cvx.imag(x) <= 1]) result = prob.solve() self.assertAlmostEqual(result, -1) self.assertAlmostEqual(x.value, 1j) x = Variable(2) expr = x / 1j prob = Problem(Minimize(expr[0] * 1j + expr[1] * 1j), [cvx.real(x + 1j) >= 1]) result = prob.solve() self.assertAlmostEqual(result, -np.inf) prob = Problem(Minimize(expr[0] * 1j + expr[1] * 1j), [cvx.real(x + 1j) <= 1]) result = prob.solve() self.assertAlmostEqual(result, -2) self.assertItemsAlmostEqual(x.value, [1, 1]) prob = Problem( Minimize(expr[0] * 1j + expr[1] * 1j), [cvx.real(x + 1j) >= 1, cvx.conj(x) <= 0]) result = prob.solve() self.assertAlmostEqual(result, np.inf) x = Variable((2, 2)) y = Variable((3, 2), complex=True) expr = cvx.vstack([x, y]) prob = Problem(Minimize(cvx.sum(cvx.imag(cvx.conj(expr)))), [x == 0, cvx.real(y) == 0, cvx.imag(y) <= 1]) result = prob.solve() self.assertAlmostEqual(result, -6) self.assertItemsAlmostEqual(y.value, 1j * np.ones((3, 2))) self.assertItemsAlmostEqual(x.value, np.zeros((2, 2))) x = Variable((2, 2)) y = Variable((3, 2), complex=True) expr = cvx.vstack([x, y]) prob = Problem(Minimize(cvx.sum(cvx.imag(expr.H))), [x == 0, cvx.real(y) == 0, cvx.imag(y) <= 1]) result = prob.solve() self.assertAlmostEqual(result, -6) self.assertItemsAlmostEqual(y.value, 1j * np.ones((3, 2))) self.assertItemsAlmostEqual(x.value, np.zeros((2, 2)))
def test_flow_control(self): # Problem data. m = 40 m_a = 20 n = 22 n_a = 5 n_b = 5 np.random.seed(1) R = np.vstack((np.hstack((np.round(rand(m_a,n_a)), np.zeros((m_a,n_b)), np.round(rand(m_a,n-n_a-n_b)))), np.hstack((np.zeros((m-m_a,n_a)), np.round(rand(m-m_a,n_b)), np.round(rand(m-m_a,n-n_a-n_b)))) )) c = 5*rand(m) # Find optimum directly. f_star = Variable(n) prob = Problem(Maximize(sum(sqrt(f_star))), [R*f_star <= c]) prob.solve() print("True Objective:", prob.value) print("True Solution:", f_star.value) # Partition data into two groups with overlap. R_a = R[:m_a,:n_a] R_b = R[m_a:,n_a:(n_a + n_b)] S_a = R[:m_a,(n_a + n_b):] S_b = R[m_a:,(n_a + n_b):] c_a = c[:m_a] c_b = c[m_a:] n_ab = n - n_a - n_b # Define separate problem for each group. f_a = Variable(n_a) f_b = Variable(n_b) x = Variable(n_ab) p_list = [Problem(Maximize(sum(sqrt(f_a)) + 0.5*sum(sqrt(x))), [R_a*f_a + S_a*x <= c_a]), Problem(Maximize(sum(sqrt(f_b)) + 0.5*sum(sqrt(x))), [R_b*f_b + S_b*x <= c_b])] probs = Problems(p_list) # Solve via consensus. probs.solve(method = "consensus", rho_init = 10, max_iter = 20) print("Consensus Objective:", -probs.value) # TODO: All problems recast as minimization, so flip sign of objective to compare print("Consensus Solution:", np.hstack((f_a.value, f_b.value, x.value)))