def ecos_solve_qp( P, q, G=None, h=None, A=None, b=None, initvals=None, verbose: bool = False ) -> Optional[ndarray]: """ Solve a Quadratic Program defined as: .. math:: \\begin{split}\\begin{array}{ll} \\mbox{minimize} & \\frac{1}{2} x^T P x + q^T x \\\\ \\mbox{subject to} & G x \\leq h \\\\ & A x = h \\end{array}\\end{split} using `ECOS <https://github.com/embotech/ecos>`_. Parameters ---------- P : numpy.array Primal quadratic cost matrix. q : numpy.array Primal quadratic cost vector. G : numpy.array Linear inequality constraint matrix. h : numpy.array Linear inequality constraint vector. A : numpy.array, optional Linear equality constraint matrix. b : numpy.array, optional Linear equality constraint vector. initvals : numpy.array, optional Warm-start guess vector (not used). verbose : bool, optional Set to `True` to print out extra information. Returns ------- x : array, shape=(n,) Solution to the QP, if found, otherwise ``None``. """ if initvals is not None: warn("note that warm-start values ignored by this wrapper") c_socp, G_socp, h_socp, dims = convert_to_socp(P, q, G, h) if A is not None: A_socp = hstack([A, zeros((A.shape[0], 1))]) A_socp = csc_matrix(A_socp) solution = solve(c_socp, G_socp, h_socp, dims, A_socp, b, verbose=verbose) else: solution = solve(c_socp, G_socp, h_socp, dims, verbose=verbose) flag = solution["info"]["exitFlag"] if flag != 0: warn(f"ECOS returned exit flag {flag} ({__exit_flag_meaning__[flag]})") return None return solution["x"][:-1]
def runEcos(tSolve, tWait, x_s, m_s, goldSearch=False, tDist=None): # find linear, SOC, and exponential inequality constraints # find equality constraints # initializes minimization function G, h, q, l, e = socConstraints(tSolve, goldSearch, m_s, tDist=tDist) A_mat, b = equalityConstraints(tSolve, x_s) c = np.zeros(11 * tSolve + 1) if goldSearch: # optimizes for slack variable, norm of final distance must be # less than or equal to this slack variable. Returns exit flag # (whether the solution was optimal or not) and final landing # distance c[-1] = 1 solution = ecos.solve(c, G, h, { 'l': l, 'q': q, 'e': e }, A=A_mat, b=b, verbose=False, abstol=1e-4, feastol=1e-4, reltol=1e-4) finDist = linalg.norm(solution['x'][11 * (tSolve - 1) + 1:11 * (tSolve - 1) + 3]) return solution['info']['exitFlag'], finDist else: # optimizes for maximizing final fuel. Returns the solution found # by ecos c[11 * (tSolve - 1) + 6] = -1 solution = ecos.solve(c, G, h, { 'l': l, 'q': q, 'e': e }, A=A_mat, b=b, verbose=False, abstol=1e-4, feastol=1e-4, reltol=1e-4) print("The solution was: ", solution['info']['exitFlag']) return solution['x']
def test_problems(): sol = ecos.solve(c, G, h, dims) yield check_solution, sol['x'][0], 1 sol = ecos.solve(c, G, h, dims, A, b) yield check_solution, sol['x'][0], 3 new_dims = {'q':[2], 'l': 0} sol = ecos.solve(c, G, h, new_dims) yield check_solution, sol['x'][0], 0.5
def test_problems_with_longs(): new_dims = {'q': [], 'l': long(2)} sol = ecos.solve(c, G, h, new_dims) yield check_solution, sol['x'][0], 1 sol = ecos.solve(c, G, h, new_dims, A, b) yield check_solution, sol['x'][0], 3 new_dims = {'q':[long(2)], 'l': 0} sol = ecos.solve(c, G, h, new_dims) yield check_solution, sol['x'][0], 0.5
def test_problems(): myopts = {'feastol': 2e-8, 'reltol': 2e-8, 'abstol': 2e-8, 'verbose':True}; sol = ecos.solve(c, G, h, dims, **myopts) yield check_solution, sol['x'][0], 4 sol = ecos.solve(c, G, h, dims, A, b, **myopts) yield check_solution, sol['x'][0], 3 new_dims = {'q':[2], 'l': 0} sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 2
def test_problems_with_longs(): new_dims = {'q': [], 'l': long(2)} myopts = {'feastol': 2e-8, 'reltol': 2e-8, 'abstol': 2e-8}; sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 4 sol = ecos.solve(c, G, h, new_dims, A, b, **myopts) yield check_solution, sol['x'][0], 3 new_dims = {'q':[long(2)], 'l': 0} sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 2
def solve(self, objective, constraints, cached_data, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ prob_data = self.get_problem_data(objective, constraints, cached_data) obj_offset = prob_data[1] results_dict = ecos.solve(*prob_data[0], verbose=verbose, **solver_opts) return self.format_results(results_dict, None, obj_offset)
def solve(self, objective, constraints, cached_data, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ prob_data = self.get_problem_data(objective, constraints, cached_data) obj_offset = prob_data[1] # Add arguments for MIP solver. sym_data = self.get_sym_data(objective, constraints, cached_data) bool_idx, int_idx = self._noncvx_id_to_idx(sym_data.dims, sym_data.var_offsets, sym_data.var_sizes) results_dict = ecos.solve(*prob_data[0], verbose=verbose, bool_vars_idx=bool_idx,# int_vars_idx=int_idx, **solver_opts) return self.format_results(results_dict, None, obj_offset)
def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None): import ecos cones = dims_to_solver_dict(data[ConicSolver.DIMS]) # Default verbose to false for BB wrapper. if 'mi_verbose' in solver_opts: mi_verbose = solver_opts['mi_verbose'] del solver_opts['mi_verbose'] else: mi_verbose = verbose solution = ecos.solve(data[s.C], data[s.G], data[s.H], cones, data[s.A], data[s.B], verbose=verbose, mi_verbose=mi_verbose, bool_vars_idx=data[s.BOOL_IDX], int_vars_idx=data[s.INT_IDX], **solver_opts) return solution
def test_problems_with_longs(): new_dims = {'q': [], 'l': long(2)} myopts = { 'feastol': 2e-8, 'reltol': 2e-8, 'abstol': 2e-8 } sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 4 sol = ecos.solve(c, G, h, new_dims, A, b, **myopts) yield check_solution, sol['x'][0], 3 new_dims = {'q': [long(2)], 'l': 0} sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 2
def test_problems(): myopts = { 'feastol': 2e-8, 'reltol': 2e-8, 'abstol': 2e-8, 'verbose': True } sol = ecos.solve(c, G, h, dims, **myopts) yield check_solution, sol['x'][0], 4 sol = ecos.solve(c, G, h, dims, A, b, **myopts) yield check_solution, sol['x'][0], 3 new_dims = {'q': [2], 'l': 0} sol = ecos.solve(c, G, h, new_dims, **myopts) yield check_solution, sol['x'][0], 2
def test_advanced(self): """Test code from the advanced section of the tutorial. """ x = Variable() prob = Problem(Minimize(square(x)), [x == 2]) # Get ECOS arguments. data = prob.get_problem_data(ECOS) # Get ECOS_BB arguments. data = prob.get_problem_data(ECOS_BB) # Get CVXOPT arguments. if CVXOPT in installed_solvers(): data = prob.get_problem_data(CVXOPT) # Get SCS arguments. data = prob.get_problem_data(SCS) import ecos # Get ECOS arguments. data = prob.get_problem_data(ECOS) # Call ECOS solver. solver_output = ecos.solve(data["c"], data["G"], data["h"], data["dims"], data["A"], data["b"]) # Unpack raw solver output. prob.unpack_results(ECOS, solver_output)
def test_unpack_results(self): """Test unpack results method. """ with self.assertRaises(Exception) as cm: Problem(Minimize(exp(self.a))).unpack_results("blah", None) self.assertEqual(str(cm.exception), "Unknown solver.") prob = Problem(Minimize(exp(self.a)), [self.a == 0]) args = prob.get_problem_data(s.SCS) results_dict = scs.solve(*args) prob = Problem(Minimize(exp(self.a)), [self.a == 0]) prob.unpack_results(s.SCS, results_dict) self.assertAlmostEqual(self.a.value, 0, places=4) self.assertAlmostEqual(prob.value, 1, places=3) self.assertAlmostEqual(prob.status, s.OPTIMAL) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) args = prob.get_problem_data(s.ECOS) results_dict = ecos.solve(*args) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) prob.unpack_results(s.ECOS, results_dict) self.assertItemsAlmostEqual(self.x.value, [0,0]) self.assertAlmostEqual(prob.value, 0) self.assertAlmostEqual(prob.status, s.OPTIMAL) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) args = prob.get_problem_data(s.CVXOPT) results_dict = cvxopt.solvers.conelp(*args) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) prob.unpack_results(s.CVXOPT, results_dict) self.assertItemsAlmostEqual(self.x.value, [0,0]) self.assertAlmostEqual(prob.value, 0) self.assertAlmostEqual(prob.status, s.OPTIMAL)
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Not used. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ import ecos data = self.get_problem_data(objective, constraints, cached_data) results_dict = ecos.solve(data[s.C], data[s.G], data[s.H], data[s.DIMS], data[s.A], data[s.B], verbose=verbose, **solver_opts) return self.format_results(results_dict, None, data[s.OFFSET], cached_data)
def test_advanced(self): """Test code from the advanced section of the tutorial. """ x = Variable() prob = Problem(Minimize(square(x)), [x == 2]) # Get ECOS arguments. data = prob.get_problem_data(ECOS) # Get ECOS_BB arguments. data = prob.get_problem_data(ECOS_BB) # Get CVXOPT arguments. data = prob.get_problem_data(CVXOPT) # Get SCS arguments. data = prob.get_problem_data(SCS) import ecos # Get ECOS arguments. data = prob.get_problem_data(ECOS) # Call ECOS solver. solver_output = ecos.solve(data["c"], data["G"], data["h"], data["dims"], data["A"], data["b"]) # Unpack raw solver output. prob.unpack_results(ECOS, solver_output)
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Not used. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ data = self.get_problem_data(objective, constraints, cached_data) results_dict = ecos.solve(data[s.C], data[s.G], data[s.H], data[s.DIMS], data[s.A], data[s.B], verbose=verbose, **solver_opts) return self.format_results(results_dict, None, data[s.OFFSET], cached_data)
def test_1(): prob_data = (np.array([-22., -14.5, 13., 0., 13.94907477]), scipy.sparse.csc_matrix( [[-1., 0., 0., 0., 0.], [0., -1., 0., 0., 0.], [0., 0., -1., 0., 0.], [1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., -1., 0.], [-0.06300143, 0.05999372, -0.04139022, 0., 0.], [0.32966768, -0.07973959, -0.61737787, 0., 0.], [0.59441633, 0.77421041, 0.21741083, 0., 0.], [0., 0., 0., 0., -1.], [0., 0., 0., 0., 1.], [0., 0., 0., -2., 0.]]), np.array([ 1., 1., 1., 1., 1., 1., -0., -0., -0., -0., 1., 1., -0. ]), { 'bool_ids': [], 'f': 0, 'l': 6, 'q': [4, 3], 's': [], 'int_ids': [], 'ep': 0 }, scipy.sparse.csc_matrix(np.zeros( (0, 5), dtype=np.float64)), np.array([], dtype=np.float64)) result = ecos.solve(*prob_data, verbose=False) assert result['info']['infostring'] == 'Optimal solution found'
def test_unpack_results(self): """Test unpack results method. """ with self.assertRaises(Exception) as cm: Problem(Minimize(exp(self.a))).unpack_results("blah", None) self.assertEqual(str(cm.exception), "Unknown solver.") prob = Problem(Minimize(exp(self.a)), [self.a == 0]) args = prob.get_problem_data(s.SCS) results_dict = scs.solve(*args) prob = Problem(Minimize(exp(self.a)), [self.a == 0]) prob.unpack_results(s.SCS, results_dict) self.assertAlmostEqual(self.a.value, 0, places=4) self.assertAlmostEqual(prob.value, 1, places=3) self.assertAlmostEqual(prob.status, s.OPTIMAL) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) args = prob.get_problem_data(s.ECOS) results_dict = ecos.solve(*args) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) prob.unpack_results(s.ECOS, results_dict) self.assertItemsAlmostEqual(self.x.value, [0, 0]) self.assertAlmostEqual(prob.value, 0) self.assertAlmostEqual(prob.status, s.OPTIMAL) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) args = prob.get_problem_data(s.CVXOPT) results_dict = cvxopt.solvers.conelp(*args) prob = Problem(Minimize(norm(self.x)), [self.x == 0]) prob.unpack_results(s.CVXOPT, results_dict) self.assertItemsAlmostEqual(self.x.value, [0, 0]) self.assertAlmostEqual(prob.value, 0) self.assertAlmostEqual(prob.status, s.OPTIMAL)
def solve(self, objective, constraints, cached_data, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ prob_data = self.get_problem_data(objective, constraints, cached_data) obj_offset = prob_data[1] results = ecos.solve(*prob_data[0], verbose=verbose, **solver_opts) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] if status in s.SOLUTION_PRESENT: primal_val = results['info']['pcost'] value = primal_val + obj_offset return (status, value, results['x'], results['y'], results['z']) else: return (status, None, None, None, None)
def test_advanced2(self): """Test code from the advanced section of the tutorial. """ x = cvx.Variable() prob = cvx.Problem(cvx.Minimize(cvx.square(x)), [x == 2]) # Get ECOS arguments. data, chain, inverse = prob.get_problem_data(cvx.ECOS) # Get ECOS_BB arguments. data, chain, inverse = prob.get_problem_data(cvx.ECOS_BB) # Get CVXOPT arguments. if cvx.CVXOPT in cvx.installed_solvers(): data, chain, inverse = prob.get_problem_data(cvx.CVXOPT) # Get SCS arguments. data, chain, inverse = prob.get_problem_data(cvx.SCS) import ecos # Get ECOS arguments. data, chain, inverse = prob.get_problem_data(cvx.ECOS) # Call ECOS solver. solution = ecos.solve(data["c"], data["G"], data["h"], ecos_conif.dims_to_solver_dict(data["dims"]), data["A"], data["b"]) # Unpack raw solver output. prob.unpack_results(solution, chain, inverse)
def solve(self, c, G, h, dims, A, b, output): """Solves the exponential Cone Program min_{Delta_p}H(T|U,V) where U,V in {X,Y,Z} Args: c: numpy.array - objective function weights G: scipy.sparse.csc_matrix - matrix of exponential and nonnegative inequalities h: numpy.array - L.H.S. of inequalities dims: dictionary - cones to be used keys: string - cone type (exponential or nonegative) values: int - number of cones A: scipy.sparse.csc_matrix - Matrix of marginal, q-w coupling, and q-p coupling equations b: numpy.array - L.H.S. of equalities output: int - print different outputs based on (int) to console Returns: sol_rpq: numpy.array - primal optimal solution sol_slack: numpy.array - slack of primal optimal solution (G*sol_rpq - h) sol_lambda: numpy.array - equalities dual optimal solution sol_mu: numpy.array - inequalities dual optimal solution sol_info: dictionary - Brief stats of the optimization from ECOS """ itic = time.process_time() self.marg_xyz = None # for cond[]mutinf computation below if self.verbose != None: # print(self.verbose) self.ecos_kwargs["verbose"] = self.verbose #^ if solution = ecos.solve(c, G, h, dims, A, b, **self.ecos_kwargs) if 'x' in solution.keys(): self.sol_rpq = solution['x'] self.sol_slack = solution['s'] self.sol_lambda = solution['y'] self.sol_mu = solution['z'] self.sol_info = solution['info'] itoc = time.process_time() if output == 2: print( "TRIVARIATE_UNQ.solve(): Time to solve the Exponential Program of H(S|W,T)", itoc - itic, "secs") return "success", self.sol_rpq, self.sol_slack, self.sol_lambda, self.sol_mu, self.sol_info else: # "x" not in dict solution return "TRIVARIATE_UNQ.solve(): x not in dict solution -- No Solution Found!!!"
def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None): import ecos cones = dims_to_solver_dict(data[ConicSolver.DIMS]) solution = ecos.solve(data[s.C], data[s.G], data[s.H], cones, data[s.A], data[s.B], verbose=verbose, **solver_opts) return solution
def test_advanced(self): """Test code from the advanced section of the tutorial. """ x = Variable() prob = Problem(Minimize(square(x)), [x == 2]) # Get ECOS arguments. c, G, h, dims, A, b = prob.get_problem_data(ECOS) # Get CVXOPT arguments. c, G, h, dims, A, b = prob.get_problem_data(CVXOPT) # Get SCS arguments. data, dims = prob.get_problem_data(SCS) import ecos # Get ECOS arguments. c, G, h, dims, A, b = prob.get_problem_data(ECOS) # Call ECOS solver. solver_output = ecos.solve(c, G, h, dims, A, b) # Unpack raw solver output. prob.unpack_results(ECOS, solver_output) # # Risk return tradeoff curve # def test_risk_return_tradeoff(self): # from math import sqrt # from cvxopt import matrix # from cvxopt.blas import dot # from cvxopt.solvers import qp, options # import scipy # n = 4 # S = matrix( [[ 4e-2, 6e-3, -4e-3, 0.0 ], # [ 6e-3, 1e-2, 0.0, 0.0 ], # [-4e-3, 0.0, 2.5e-3, 0.0 ], # [ 0.0, 0.0, 0.0, 0.0 ]] ) # pbar = matrix([.12, .10, .07, .03]) # N = 100 # # CVXPY # Sroot = numpy.asmatrix(scipy.linalg.sqrtm(S)) # x = cp.Variable(n, name='x') # mu = cp.Parameter(name='mu') # mu.value = 1 # TODO cp.Parameter("positive") # objective = cp.Minimize(-pbar*x + mu*quad_over_lin(Sroot*x,1)) # constraints = [sum_entries(x) == 1, x >= 0] # p = cp.Problem(objective, constraints) # mus = [ 10**(5.0*t/N-1.0) for t in range(N) ] # xs = [] # for mu_val in mus: # mu.value = mu_val # p.solve() # xs.append(x.value) # returns = [ dot(pbar,x) for x in xs ] # risks = [ sqrt(dot(x, S*x)) for x in xs ] # # QP solver
def solve(self, c, G, h, dims, A, b, output): """Solves the second-order cone program min_{Pi_x}1/2 x^TWx + f^T x Args: c: numpy.array - objective function weights G: scipy.sparse.csc_matrix - matrix of soc and nonnegative inequalities h: numpy.array - L.H.S. of inequalities dims: dictionary - cones to be used keys: string - cone type (soc or nonegative) values: int - number of cones A: scipy.sparse.csc_matrix - Matrix of identity equations b: numpy.array - L.H.S. of equalities output: int - print different outputs based on (int) to console Returns: sol_tx: numpy.array - primal optimal solution sol_slack: numpy.array - slack of primal optimal solution (G*sol_rpq - h) sol_lambda: numpy.array - equalities dual optimal solution sol_mu: numpy.array - inequalities dual optimal solution sol_info: dictionary - Brief stats of the optimization from ECOS """ itic = time.process_time() if self.verbose != None: # print(self.verbose) self.ecos_kwargs["verbose"] = self.verbose #^ if solution = ecos.solve(c, G, h, dims, A, b, **self.ecos_kwargs) if 'x' in solution.keys(): self.sol_tx = solution['x'] self.sol_slack = solution['s'] self.sol_lambda = solution['y'] self.sol_mu = solution['z'] self.sol_info = solution['info'] itoc = time.process_time() if output == 2: print( "TRIVARIATE_QP.solve(): Time to solve the Quadratic Program of Least Squares", itoc - itic, "secs") return "success", self.sol_tx, self.sol_slack, self.sol_lambda, self.sol_mu, self.sol_info else: # "x" not in dict solution return "TRIVARIATE_QP.solve(): x not in dict solution -- No Solution Found!!!"
def ecos_solver(G, h, A, b, c, n): # In order to use ecos, we must provide sparse matrices A = csc_matrix(A) G = csc_matrix(G) dims = dict(l=n**2, q=[]) solution = ecos.solve(c, G, h, dims, A, b) if solution['info']['exitFlag'] == 0: return True, solution['x'] # TODO status could be unknown here, but we're currently ignoring that return False, None
def ecos_solver(G, h, A, b, c, n): # In order to use ecos, we must provide sparse matrices A = csc_matrix(A) G = csc_matrix(G) dims = dict(l=n ** 2, q=[]) solution = ecos.solve(c, G, h, dims, A, b) if solution['info']['exitFlag'] == 0: return True, solution['x'] # TODO status could be unknown here, but we're currently ignoring that return False, None
def solve_func(params): data = self.prob2socp(params) sol = ecos.solve(**data) result = self.socp2prob(sol['x']) result['info'] = sol['info'] # set the objective value multiplier = self.__codegen.objective_multiplier offset = self.__codegen.objective_offset result['objval'] = multiplier * sol['info']['pcost'] + offset return result
def solve_func(params, dims): data = self.prob2socp(params, dims) sol = ecos.solve(**data) result = self.socp2prob(sol['x'], dims) result['info'] = sol['info'] # set the objective value multiplier = self.__codegen.objective_multiplier offset = self.__codegen.objective_offset result['objval'] = multiplier * sol['info']['pcost'] + offset return result
def NashEquilibriumECOSSolver(M): """ https://github.com/embotech/ecos-python min c*x s.t. A*x = b G*x <= h https://github.com/embotech/ecos/wiki/Usage-from-MATLAB args: c,b,h: numpy.array A, G: Scipy sparse matrix """ row, col = M.shape c = np.zeros(row + 1) # max z c[-1] = -1 # x1+x2+...+xn=1 A = np.ones(row + 1) A[-1] = 0. A = csr_matrix([A]) b = np.array([1.]) # M.T*x<=z G1 = np.ones((col, row + 1)) G1[:col, :row] = -1. * M.T # x>=0 G2 = np.zeros((row, row + 1)) for i in range(row): G2[i, i] = -1. # x<=1. G3 = np.zeros((row, row + 1)) for i in range(row): G3[i, i] = 1. G = csr_matrix(np.concatenate((G1, G2, G3))) h = np.concatenate((np.zeros(2 * row), np.ones(row))) # specify number of variables dims = {'l': col + 2 * row, 'q': []} solution = ecos.solve(c, G, h, dims, A, b, verbose=False) p1_value = solution['x'][:row] p2_value = solution['z'][:col] # z is the dual variable of x # There are at least two bad cases with above constrained optimization, # where the constraints are not fully satisfied (some numerical issue): # 1. the sum of vars is larger than 1. # 2. the value of var may be negative. abs_p1_value = np.abs(p1_value) abs_p2_value = np.abs(p2_value) p1_value = abs_p1_value / np.sum(abs_p1_value) p2_value = abs_p2_value / np.sum(abs_p2_value) return (p1_value, p2_value)
def _ecos_solve(self, objective, constr_map, dims, sorted_vars, var_offsets, x_length, verbose): """Calls the ECOS solver and returns the result. Parameters ---------- objective: Expression The canonicalized objective. constr_map: dict A dict of the canonicalized constraints. dims: dict A dict with information about the types of constraints. sorted_vars: list An ordered list of the problem variables. var_offsets: dict A dict mapping variable id to offset in the stacked variable x. x_length: int The height of x. verbose: bool Should the solver show output? Returns ------- tuple (status, optimal objective, optimal x, optimal equality constraint dual, optimal inequality constraint dual) """ c, obj_offset = self._constr_matrix([objective], var_offsets, x_length, self._DENSE_INTF, self._DENSE_INTF) # Convert obj_offset to a scalar. obj_offset = self._DENSE_INTF.scalar_value(obj_offset) A, b = self._constr_matrix(constr_map[s.EQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) G, h = self._constr_matrix(constr_map[s.INEQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) # Convert c,h,b to 1D arrays. c, h, b = map(lambda mat: np.asarray(mat)[:, 0], [c.T, h, b]) results = ecos.solve(c, G, h, dims, A, b, verbose=verbose) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] if status == s.OPTIMAL: primal_val = results['info']['pcost'] value = self.objective._primal_to_result( primal_val - obj_offset) return (status, value, results['x'], results['y'], results['z']) else: return (status, None, None, None, None)
def solve_via_data(self, data, warm_start: bool, verbose: bool, solver_opts, solver_cache=None): import ecos cones = dims_to_solver_dict(data[ConicSolver.DIMS]) if data[s.A] is not None and data[s.A].nnz == 0 and np.prod(data[s.A].shape) > 0: raise ValueError( "ECOS cannot handle sparse data with nnz == 0; " "this is a bug in ECOS, and it indicates that your problem " "might have redundant constraints.") solution = ecos.solve(data[s.C], data[s.G], data[s.H], cones, data[s.A], data[s.B], verbose=verbose, **solver_opts) return solution
def solve_func(params, dims): data = self.prob2socp(params, dims) sol = ecos.solve(**data) result = self.socp2prob(sol["x"], sol["y"], sol["z"], dims) result["info"] = sol["info"] # set the objective value multiplier = self.__codegen.objective_multiplier offset = self.__codegen.objective_offset if isinstance(offset, str): # in this case, offset is likely python *code* offset = eval(offset) result["objval"] = multiplier * sol["info"]["pcost"] + offset return result
def solve_func(params, dims): data = self.prob2socp(params, dims) sol = ecos.solve(**data) result = self.socp2prob(sol['x'], sol['y'], sol['z'], dims) result['info'] = sol['info'] # set the objective value multiplier = self.__codegen.objective_multiplier offset = self.__codegen.objective_offset if isinstance(offset, str): # in this case, offset is likely python *code* offset = eval(offset) result['objval'] = multiplier * sol['info']['pcost'] + offset return result
def solve_via_data(data, params): import ecos if 'max_iters' in params: max_iters = params['max_iters'] else: max_iters = 100000 sol = ecos.solve(data['c'], data['G'], data['h'], data['cones'], data['A'], data['b'], verbose=params['verbose'], max_iters=max_iters) return sol
def solver(self, params, dims): temp = self.prob2socp() data = temp(params, dims) sol = ecos.solve(**data) temp1 = self.socp2prob() result = temp1(sol['x'], sol['y'], sol['z'], dims) result['info'] = sol['info'] # set the objective value multiplier = self.__codegen.objective_multiplier offset = self.__codegen.objective_offset if isinstance(offset, str): # in this case, offset is likely python *code* offset = eval(offset) result['objval'] = multiplier * sol['info']['pcost'] + offset return result
def solve_via_data(data, params): if not Mosek.is_installed(): warnings.warn(_MOSEK_INSTALL_) import ecos if 'max_iters' in params: max_iters = params['max_iters'] else: max_iters = 100000 sol = ecos.solve(data['c'], data['G'], data['h'], data['cones'], data['A'], data['b'], verbose=params['verbose'], max_iters=max_iters) return sol
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Not used. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ import ecos data = self.get_problem_data(objective, constraints, cached_data) # Default verbose to false for BB wrapper. if 'mi_verbose' in solver_opts: mi_verbose = solver_opts['mi_verbose'] del solver_opts['mi_verbose'] else: mi_verbose = verbose results_dict = ecos.solve(data[s.C], data[s.G], data[s.H], data[s.DIMS], data[s.A], data[s.B], verbose=verbose, mi_verbose=mi_verbose, bool_vars_idx=data[s.BOOL_IDX], int_vars_idx=data[s.INT_IDX], **solver_opts) return self.format_results(results_dict, data, cached_data)
def solve(self): # (c) Abdullah Makkeh, Dirk Oliver Theis # Permission to use and modify under Apache License version 2.0 self.marg_yz = None # for cond[]mutinf computation below if self.verbose != None: self.ecos_kwargs["verbose"] = self.verbose solution = ecos.solve(self.c, self.G,self.h, self.dims, self.A,self.b, **self.ecos_kwargs) if 'x' in solution.keys(): self.sol_rpq = solution['x'] self.sol_slack = solution['s'] self.sol_lambda = solution['y'] self.sol_mu = solution['z'] self.sol_info = solution['info'] return "success" else: # "x" not in dict solution return "x not in dict solution -- No Solution Found!!!"
def _ecos_solve(self, objective, constr_map, dims, var_offsets, x_length, verbose, opts): """Calls the ECOS solver and returns the result. Parameters ---------- objective: Expression The canonicalized objective. constr_map: dict A dict of the canonicalized constraints. dims: dict A dict with information about the types of constraints. var_offsets: dict A dict mapping variable id to offset in the stacked variable x. x_length: int The height of x. verbose: bool Should the solver show output? opts: dict List of user-specific options for ECOS Returns ------- tuple (status, optimal objective, optimal x, optimal equality constraint dual, optimal inequality constraint dual) """ prob_data = self._ecos_problem_data(objective, constr_map, dims, var_offsets, x_length) obj_offset = prob_data[1] opts = dict({"VERBOSE": verbose}.items() + opts.items()) results = ecos.solve(*prob_data[0], **opts) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] if status == s.OPTIMAL: primal_val = results['info']['pcost'] value = self.objective._primal_to_result( primal_val - obj_offset) return (status, value, results['x'], results['y'], results['z']) else: return (status, None, None, None, None)
def solve(self, P, q, G, h): import ecos n_pairs = P.shape[0] L, max_eigval = self._decompose(P) # minimize wrt t,x c = numpy.empty(n_pairs + 1) c[1:] = q c[0] = 0.5 * max_eigval zerorow = numpy.zeros((1, L.shape[1])) G_quad = numpy.block([ [-1, zerorow], [1, zerorow], [numpy.zeros((L.shape[0], 1)), -2 * L], ]) G_lin = sparse.hstack((sparse.csc_matrix((G.shape[0], 1)), G)) G_all = sparse.vstack((G_lin, sparse.csc_matrix(G_quad)), format="csc") n_constraints = G.shape[0] h_all = numpy.empty(G_all.shape[0]) h_all[:n_constraints] = h h_all[n_constraints:(n_constraints + 2)] = 1 h_all[(n_constraints + 2):] = 0 dims = { "l": G.shape[0], # scalar, dimension of positive orthant "q": [G_quad.shape[0]] # vector with dimensions of second order cones } results = ecos.solve(c, G_all, h_all, dims, verbose=self.verbose, max_iters=self.max_iter or 1000) self._check_success(results) # drop solution for t x = results["x"][1:] return x[numpy.newaxis]
def solve(self): # (c) Abdullah Makkeh, Dirk Oliver Theis # Permission to use and modify under Apache License version 2.0 self.marg_yz = None # for cond[]mutinf computation below if self.verbose is not None: self.ecos_kwargs["verbose"] = self.verbose solution = ecos.solve(self.c, self.G, self.h, self.dims, self.A, self.b, **self.ecos_kwargs) if 'x' in solution.keys(): self.sol_rpq = solution['x'] self.sol_slack = solution['s'] self.sol_lambda = solution['y'] self.sol_mu = solution['z'] self.sol_info = solution['info'] return "success" else: # "x" not in dict solution return "x not in dict solution -- No Solution Found!!!"
def prox(self, v): '''computes prox_{f/rho}(v)''' # set the RHS of the solver if self.n == 0: return np.empty(0) self.socp_vars['h'][-self.n:] = -v + self.c_offset if self.solver == "ecos": sol = ecos.solve(verbose=False, **self.socp_vars) else: raise Exception('Unknown solver') x = np.array(sol['x']) x = np.reshape(x, (x.shape[0], )) #self.z = np.array(sol['z'])[:self.m] # self.objval = sol['info']['pcost'] # self.s = np.array(sol['s'])[:self.m] return x[:self.n]
def prox(self, v): '''computes prox_{f/rho}(v)''' # set the RHS of the solver if self.n == 0: return np.empty(0) self.socp_vars['h'][-self.n:] = -v + self.c_offset if self.solver == "ecos": sol = ecos.solve(verbose=False, **self.socp_vars) else: raise Exception('Unknown solver') x = np.array(sol['x']) x = np.reshape(x, (x.shape[0],)) #self.z = np.array(sol['z'])[:self.m] # self.objval = sol['info']['pcost'] # self.s = np.array(sol['s'])[:self.m] return x[:self.n]
def solve(canon, verbose=False, fail_return=True): if importlib.util.find_spec("ecos"): import ecos import scipy # assumed that if you have ecos, you have scipy else: print("WARNING: Module 'ecos' not found - can not solve") return None G = scipy.sparse.csc_matrix(*canon.G.to_scipy()) c = np.array(canon.c) h = np.array(canon.h) if canon.A is not None: A = scipy.sparse.csc_matrix(*canon.A.to_scipy()) b = np.array(canon.b) else: A = None b = None return ecos.solve(c, G, h, canon.dims, A, b, verbose=verbose)
def test_advanced(self): """Test code from the advanced section of the tutorial. """ x = Variable() prob = Problem(Minimize(square(x)), [x == 2]) # Get ECOS arguments. c, G, h, dims, A, b = prob.get_problem_data(ECOS) # Get CVXOPT arguments. c, G, h, dims, A, b = prob.get_problem_data(CVXOPT) # Get SCS arguments. data, dims = prob.get_problem_data(SCS) import ecos # Get ECOS arguments. c, G, h, dims, A, b = prob.get_problem_data(ECOS) # Call ECOS solver. solver_output = ecos.solve(c, G, h, dims, A, b) # Unpack raw solver output. prob.unpack_results(ECOS, solver_output)
def _ecos_solve(self, objective, constr_map, dims, var_offsets, x_length, verbose, opts): """Calls the ECOS solver and returns the result. Parameters ---------- objective: Expression The canonicalized objective. constr_map: dict A dict of the canonicalized constraints. dims: dict A dict with information about the types of constraints. var_offsets: dict A dict mapping variable id to offset in the stacked variable x. x_length: int The height of x. verbose: bool Should the solver show output? opts: dict List of user-specific options for ECOS Returns ------- tuple (status, optimal objective, optimal x, optimal equality constraint dual, optimal inequality constraint dual) """ prob_data = self._ecos_problem_data(objective, constr_map, dims, var_offsets, x_length) obj_offset = prob_data[1] results = ecos.solve(*prob_data[0], verbose=verbose) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] if status == s.OPTIMAL: primal_val = results['info']['pcost'] value = self.objective._primal_to_result(primal_val - obj_offset) return (status, value, results['x'], results['y'], results['z']) else: return (status, None, None, None, None)
def _ecos_solve(self, objective, constr_map, dims, var_offsets, x_length, verbose, opts): """Calls the ECOS solver and returns the result. Parameters ---------- objective: Expression The canonicalized objective. constr_map: dict A dict of the canonicalized constraints. dims: dict A dict with information about the types of constraints. var_offsets: dict A dict mapping variable id to offset in the stacked variable x. x_length: int The height of x. verbose: bool Should the solver show output? opts: dict List of user-specific options for ECOS Returns ------- tuple (status, optimal objective, optimal x, optimal equality constraint dual, optimal inequality constraint dual) """ prob_data = self._ecos_problem_data(objective, constr_map, dims, var_offsets, x_length) obj_offset = prob_data[1] results = ecos.solve(*prob_data[0], verbose=verbose, **opts) status = s.SOLVER_STATUS[s.ECOS][results["info"]["exitFlag"]] if status in s.SOLUTION_PRESENT: primal_val = results["info"]["pcost"] value = self.objective._primal_to_result(primal_val - obj_offset) return (status, value, results["x"], results["y"], results["z"]) else: return (status, None, None, None, None)
def test_1(): prob_data = ( np.array([-22. , -14.5 , 13. , 0. , 13.94907477]), scipy.sparse.csc_matrix([ [-1. , 0. , 0. , 0. , 0. ], [ 0. , -1. , 0. , 0. , 0. ], [ 0. , 0. , -1. , 0. , 0. ], [ 1. , 0. , 0. , 0. , 0. ], [ 0. , 1. , 0. , 0. , 0. ], [ 0. , 0. , 1. , 0. , 0. ], [ 0. , 0. , 0. , -1. , 0. ], [-0.06300143, 0.05999372, -0.04139022, 0. , 0. ], [ 0.32966768, -0.07973959, -0.61737787, 0. , 0. ], [ 0.59441633, 0.77421041, 0.21741083, 0. , 0. ], [ 0. , 0. , 0. , 0. , -1. ], [ 0. , 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , -2. , 0. ]]), np.array([ 1., 1., 1., 1., 1., 1., -0., -0., -0., -0., 1., 1., -0.]), {'bool_ids': [], 'f': 0, 'l': 6, 'q': [4, 3], 's': [], 'int_ids': [], 'ep': 0}, scipy.sparse.csc_matrix(np.zeros((0, 5), dtype=np.float64)), np.array([], dtype=np.float64) ) result = ecos.solve(*prob_data, verbose=False) assert result['info']['infostring'] == 'Optimal solution found'
def _solve(self, solver=s.ECOS, ignore_dcp=False, verbose=False): if not self.is_dcp(): if ignore_dcp: print ("Problem does not follow DCP rules. " "Solving a convex relaxation.") else: raise Exception("Problem does not follow DCP rules.") objective,constr_map,dims = self.canonicalize() var_offsets,x_length = self.variables(objective, constr_map[s.EQ] + constr_map[s.INEQ]) c,obj_offset = self.constraints_matrix([objective], var_offsets, x_length, self.dense_interface, self.dense_interface) A,b = self.constraints_matrix(constr_map[s.EQ], var_offsets, x_length, self.interface, self.dense_interface) G,h = self.constraints_matrix(constr_map[s.INEQ], var_offsets, x_length, self.interface, self.dense_interface) # ECHU: get the nonlinear constraints F = self.nonlinear_constraint_function(constr_map[s.NONLIN], var_offsets, x_length) # Save original cvxopt solver options. old_options = cvxopt.solvers.options # Silence cvxopt if verbose is False. cvxopt.solvers.options['show_progress'] = verbose # Always do one step of iterative refinement after solving KKT system. cvxopt.solvers.options['refinement'] = 1 # Target cvxopt clp if nonlinear constraints exist if constr_map[s.NONLIN]: # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A, F) results = cvxopt.solvers.cpl(c.T,F,G,h,A=A,b=b, dims=dims,kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] # Target cvxopt solver if SDP or invalid for ECOS. elif solver == s.CVXOPT or len(dims['s']) > 0 or min(G.size) == 0: # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A) # Adjust tolerance to account for regularization. cvxopt.solvers.options['feastol'] = 2*1e-6 results = cvxopt.solvers.conelp(c.T,G,h,A=A,b=b, dims=dims,kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] else: # If possible, target ECOS. # ECHU: ecos interface has changed and no longer relies on CVXOPT # as a result, we have to convert cvxopt data structures into # numpy arrays # # ideally, CVXPY would no longer user CVXOPT, except when calling # conelp # cnp, hnp, bnp = map(lambda x: np.fromiter(iter(x),dtype=np.double,count=len(x)), (c, h, b)) Gp,Gi,Gx = G.CCS m,n1 = G.size Ap,Ai,Ax = A.CCS p,n2 = A.size Gp, Gi, Ap, Ai = map(lambda x: np.fromiter(iter(x),dtype=np.int32,count=len(x)), (Gp,Gi,Ap,Ai)) Gx, Ax = map(lambda x: np.fromiter(iter(x),dtype=np.double,count=len(x)), (Gx, Ax)) Gsp = sp.csc_matrix((Gx,Gi,Gp),shape=(m,n1)) if p == 0: Asp = None bnp = None else: Asp = sp.csc_matrix((Ax,Ai,Ap),shape=(p,n2)) # ECHU: end conversion results = ecos.solve(cnp,Gsp,hnp,dims,Asp,bnp,verbose=verbose) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] primal_val = results['info']['pcost'] # Restore original cvxopt solver options. cvxopt.solvers.options = old_options if status == s.SOLVED: self.save_values(results['x'], sorted(var_offsets.keys())) self.save_values(results['y'], constr_map[s.EQ]) if constr_map[s.NONLIN]: self.save_values(results['zl'], constr_map[s.INEQ]) else: self.save_values(results['z'], constr_map[s.INEQ]) return self.objective.value(primal_val - obj_offset[0]) else: return status
data = np.random.randn(nnz) Acouple = sp.coo_matrix((data, ij), (m, n)) # add the two A = A + Acouple # randomly generate an "x" (free) x = np.random.randn((n)) # generate a vector which will be used to create the complementary "s" and "y" tmp = np.random.randn((m)) y = np.maximum(tmp, 0) s = np.maximum(-tmp, 0) # now, s and y are complementary primal-dual pair c = -A.T * y b = A * x + s dims = {'l': m, 'q': [], 's': []} # A = A.tocoo() # solvers.conelp(cvxopt.matrix(c), cvxopt.spmatrix(A.data, A.row, A.col), cvxopt.matrix(b), dims) # import ecos ecos.solve(c, A, b, dims) objval = c.T.dot(x) socp_vars = {'c': c, 'G': A, 'h': b, 'A': None, 'b': None, 'dims': dims} # print b.T.dot(y)
def properly_solves(lang): from .. qc_lang import QCML p = QCML(debug=True) p.parse(mult) p.canonicalize() if lang == "C": p.codegen(lang) p.save("test_problem") c_test_code = """ #include "test_problem.h" #include "ecos.h" int main(int argc, char **argv) { double Adata[6] = {1,2,3,4,5,6}; double Bdata[6] = {1,2,3,4,5,6}; long Ai[6] = {0,0,1,1,2,2}; long Aj[6] = {0,1,0,1,0,1}; long Bj[6] = {0,0,0,1,1,1}; long Bi[6] = {0,1,2,0,1,2}; double c[3] = {1,2,3}; double d[3] = {4,5,6}; qc_matrix A; qc_matrix B; A.v = Adata; A.i = Ai; A.j = Aj; A.nnz = 6; A.m = 3; A.n = 2; B.v = Bdata; B.i = Bi; B.j = Bj; B.nnz = 6; B.m = 3; B.n = 2; test_problem_params p; p.A = &A; p.B = &B; p.c = c; p.d = d; qc_socp *data = qc_test_problem2socp(&p, NULL); // run ecos and solve it pwork *mywork = ECOS_setup(data->n, data->m, data->p, data->l, data->nsoc, data->q, 0, data->Gx, data->Gp, data->Gi, data->Ax, data->Ap, data->Ai, data->c, data->h, data->b); if (mywork) { ECOS_solve(mywork); printf("Objective value at termination of C program is %f\\n", mywork->info->pcost); ECOS_cleanup(mywork, 0); } qc_socp_free(data); return 0; } """ objval, _ = make_and_execute_ecos_solve("test_problem", c_test_code) assert objval == solution else: p.codegen(lang) socp_data = p.prob2socp({'A': np.array(A), 'B': np.array(B), 'c': np.array(c), 'd': np.array(d)}) print socp_data import ecos sol = ecos.solve(**socp_data) print sol assert abs(sol['info']['pcost'] - solution) < 1e-6
def properly_solves(lang): from .. qc_lang import QCML p = QCML(debug=True) p.parse(mult) p.canonicalize() if lang == "C": p.codegen(lang) p.save("test_problem") c_test_code = """ #include "test_problem.h" #include "ecos.h" int main(int argc, char **argv) { double Adata[6] = {1,2,3,4,5,6}; double Bdata[6] = {1,2,3,4,5,6}; long Ai[6] = {0,0,1,1,2,2}; long Aj[6] = {0,1,0,1,0,1}; long Bi[6] = {0,0,0,1,1,1}; long Bj[6] = {0,1,2,0,1,2}; double c[3] = {1,2,3}; double d[3] = {4,5,6}; qc_matrix A; qc_matrix B; A.v = Adata; A.i = Ai; A.j = Aj; A.nnz = 6; A.m = 3; A.n = 2; B.v = Bdata; B.i = Bi; B.j = Bj; B.nnz = 6; B.m = 2; B.n = 3; test_problem_params p; p.A = &A; p.B = &B; p.c = c; p.d = d; qc_socp *data = qc_test_problem2socp(&p, NULL); // run ecos and solve it pwork *mywork = ECOS_setup(data->n, data->m, data->p, data->l, data->nsoc, data->q, data->Gx, data->Gp, data->Gi, data->Ax, data->Ap, data->Ai, data->c, data->h, data->b); if (mywork) { ECOS_solve(mywork); printf("Objective value at termination of C program is %f\\n", mywork->info->pcost); ECOS_cleanup(mywork, 0); } qc_socp_free(data); return 0; } """ with open("test_problem/main.c", "w") as f: f.write(c_test_code) os.chdir("test_problem") print "Running make...." subprocess.check_output(["make"]) if platform.system() == 'Linux': cmd = ["cc", "-O3", "main.c", "-L%s" % ECOS_PATH, "-I%s/include" % ECOS_PATH, "-I%s/external/SuiteSparse_config" % ECOS_PATH, "-lecos", "-lm", "-lrt", "test_problem.o", "qcml_utils.o", "-o","main"] else: cmd = ["cc", "-O3", "main.c", "-L%s" % ECOS_PATH, "-I%s/include" % ECOS_PATH, "-I%s/external/SuiteSparse_config" % ECOS_PATH, "-lecos", "-lm", "test_problem.o", "qcml_utils.o", "-o","main"] print ' '.join(cmd) try: subprocess.check_output(cmd) except subprocess.CalledProcessError: print "" print "This test fails because it cannot find ECOS," print "please set your ECOS_PATH environment variable." print "" print " export ECOS_PATH=/PATH/TO/ECOS" print "" raise try: output = subprocess.check_output(["./main"]) except: print "" print "There is a bug in the compiled C code." print "" raise objval = re.findall(r'Objective value at termination of C program is (\d+\.\d*)', output) os.chdir("..") shutil.rmtree("%s/test_problem" % os.getcwd()) assert len(objval) == 1 assert float(objval[0]) == solution else: p.codegen(lang) socp_data = p.prob2socp({'A': np.array(A), 'B': np.array(B), 'c': np.array(c), 'd': np.array(d)}) print socp_data import ecos sol = ecos.solve(**socp_data) print sol assert abs(sol['info']['pcost'] - solution) < 1e-6
for i in range(m): a = np.random.randn(n) a = a / np.linalg.norm(a) bi = 1 + np.random.rand(1) A[i, :] = a b[i] = bi q = QCML() q.parse(''' dimensions m n variables x(n) r parameters A(m,n) b(m) maximize r A*x + r <= b ''') q.canonicalize() q.dims = {'m': m, 'n': n} q.codegen("python") socp_data = q.prob2socp(locals()) # stuffed variable size n = socp_data['G'].shape[1] ecos_sol = ecos.solve(**socp_data) socp_sol = ecos_sol['x'] prob_sol_x = q.socp2prob(ecos_sol['x'])['x'] prob_sol_r = q.socp2prob(ecos_sol['x'])['r']
def _solve(self, solver=s.ECOS, ignore_dcp=False, verbose=False): """Solves a DCP compliant optimization problem. Saves the values of primal and dual variables in the variable and constraint objects, respectively. Args: solver: The solver to use. Defaults to ECOS. ignore_dcp: Overrides the default of raising an exception if the problem is not DCP. verbose: Overrides the default of hiding solver output. Returns: The optimal value for the problem, or a string indicating why the problem could not be solved. """ if not self.is_dcp(): if ignore_dcp: print ("Problem does not follow DCP rules. " "Solving a convex relaxation.") else: raise Exception("Problem does not follow DCP rules.") objective, constr_map, dims = self.canonicalize() all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.INEQ]) var_offsets, x_length = self._get_var_offsets(objective, all_ineq) c, obj_offset = self._constr_matrix([objective], var_offsets, x_length, self._DENSE_INTF, self._DENSE_INTF) A, b = self._constr_matrix(constr_map[s.EQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) G, h = self._constr_matrix(constr_map[s.INEQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) # Save original cvxopt solver options. old_options = cvxopt.solvers.options # Silence cvxopt if verbose is False. cvxopt.solvers.options['show_progress'] = verbose # Always do one step of iterative refinement after solving KKT system. cvxopt.solvers.options['refinement'] = 1 # Target cvxopt clp if nonlinear constraints exist if constr_map[s.NONLIN]: # Get the nonlinear constraints. F = self._merge_nonlin(constr_map[s.NONLIN], var_offsets, x_length) # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A, F) results = cvxopt.solvers.cpl(c.T, F, G, h, A=A, b=b, dims=dims,kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] # Target cvxopt solver if SDP or invalid for ECOS. elif solver == s.CVXOPT or len(dims['s']) > 0 or min(G.size) == 0: # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A) # Adjust tolerance to account for regularization. cvxopt.solvers.options['feastol'] = 2*1e-6 results = cvxopt.solvers.conelp(c.T, G, h, A=A, b=b, dims=dims, kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] else: # If possible, target ECOS. # ECHU: ecos interface has changed and no longer relies on CVXOPT # as a result, we have to convert cvxopt data structures into # numpy arrays # # ideally, CVXPY would no longer user CVXOPT, except when calling # conelp # cnp, hnp, bnp = (np.fromiter(iter(x), dtype=np.double, count=len(x)) for x in (c, h, b)) Gp, Gi, Gx = G.CCS m, n1 = G.size Ap, Ai, Ax = A.CCS p, n2 = A.size Gp, Gi, Ap, Ai = (np.fromiter(iter(x), dtype=np.int32, count=len(x)) for x in (Gp, Gi, Ap, Ai)) Gx, Ax = (np.fromiter(iter(x), dtype=np.double, count=len(x)) for x in (Gx, Ax)) Gsp = sp.csc_matrix((Gx, Gi, Gp), shape=(m, n1)) if p == 0: Asp = None bnp = None else: Asp = sp.csc_matrix((Ax, Ai, Ap), shape=(p, n2)) # ECHU: end conversion results = ecos.solve(cnp, Gsp, hnp, dims, Asp, bnp, verbose=verbose) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] primal_val = results['info']['pcost'] # Restore original cvxopt solver options. cvxopt.solvers.options = old_options if status == s.SOLVED: self._save_values(results['x'], var_offsets.keys()) self._save_values(results['y'], constr_map[s.EQ]) if constr_map[s.NONLIN]: self._save_values(results['zl'], constr_map[s.INEQ]) else: self._save_values(results['z'], constr_map[s.INEQ]) return self.objective._primal_to_result(primal_val - obj_offset[0]) else: return status
def _solve(self, solver=s.ECOS, ignore_dcp=False, verbose=False): """Solves a DCP compliant optimization problem. Saves the values of primal and dual variables in the variable and constraint objects, respectively. Parameters ---------- solver : str, optional The solver to use. Defaults to ECOS. ignore_dcp : bool, optional Overrides the default of raising an exception if the problem is not DCP. verbose : bool, optional Overrides the default of hiding solver output. Returns ------- float The optimal value for the problem, or a string indicating why the problem could not be solved. """ if not self.is_dcp(): if ignore_dcp: print ("Problem does not follow DCP rules. " "Solving a convex relaxation.") else: raise Exception("Problem does not follow DCP rules.") objective, constr_map, dims = self.canonicalize() all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.INEQ]) var_offsets, x_length = self._get_var_offsets(objective, all_ineq) c, obj_offset = self._constr_matrix([objective], var_offsets, x_length, self._DENSE_INTF, self._DENSE_INTF) # Convert obj_offset to a scalar. obj_offset = self._DENSE_INTF.scalar_value(obj_offset) A, b = self._constr_matrix(constr_map[s.EQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) G, h = self._constr_matrix(constr_map[s.INEQ], var_offsets, x_length, self._SPARSE_INTF, self._DENSE_INTF) # Save original cvxopt solver options. old_options = cvxopt.solvers.options # Silence cvxopt if verbose is False. cvxopt.solvers.options['show_progress'] = verbose # Always do one step of iterative refinement after solving KKT system. cvxopt.solvers.options['refinement'] = 1 # Target cvxopt solver if SDP or invalid for ECOS. if solver == s.CVXOPT or len(dims['s']) > 0 \ or min(G.shape) == 0 or constr_map[s.NONLIN]: # Convert c,A,b,G,h to cvxopt matrices. c, b, h = map(lambda vec: self._CVXOPT_DENSE_INTF.const_to_matrix(vec, convert_scalars=True), [c, b, h]) A, G = map(lambda mat: self._CVXOPT_SPARSE_INTF.const_to_matrix(mat, convert_scalars=True), [A, G]) # Target cvxopt clp if nonlinear constraints exist if constr_map[s.NONLIN]: # Get the nonlinear constraints. F = self._merge_nonlin(constr_map[s.NONLIN], var_offsets, x_length) # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A, F) results = cvxopt.solvers.cpl(c.T, F, G, h, A=A, b=b, dims=dims,kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] else: # Get custom kktsolver. kktsolver = get_kktsolver(G, dims, A) # Adjust tolerance to account for regularization. cvxopt.solvers.options['feastol'] = 2*1e-6 results = cvxopt.solvers.conelp(c.T, G, h, A=A, b=b, dims=dims, kktsolver=kktsolver) status = s.SOLVER_STATUS[s.CVXOPT][results['status']] primal_val = results['primal objective'] else: # If possible, target ECOS. # Convert c,h,b to 1D arrays. c, h, b = map(lambda mat: np.asarray(mat)[:, 0], [c.T, h, b]) results = ecos.solve(c, G, h, dims, A, b, verbose=verbose) status = s.SOLVER_STATUS[s.ECOS][results['info']['exitFlag']] primal_val = results['info']['pcost'] # Restore original cvxopt solver options. cvxopt.solvers.options = old_options if status == s.OPTIMAL: self._save_values(results['x'], var_offsets.keys()) self._save_values(results['y'], constr_map[s.EQ]) if constr_map[s.NONLIN]: self._save_values(results['zl'], constr_map[s.INEQ]) else: self._save_values(results['z'], constr_map[s.INEQ]) self._value = self.objective._primal_to_result( primal_val - obj_offset) else: self._handle_failure(status, var_offsets.keys(), itertools.chain(constr_map[s.EQ], constr_map[s.INEQ])) self._status = status return self.value
# dims = {'l': 2} import numpy as np from scipy import sparse ij = np.array([[0,1],[0,1]]) A = sparse.csc_matrix(([1.,1.], ij), (2,2)) b = np.array([1.,1.]) G = sparse.csc_matrix(([-1.,-1.], ij), (2,2)) h = np.array([0.,0.]) c = np.array([1.,1.]) dims = {'l': 2} print c print h sol = ecos.solve(c,G,h,dims,A,b) print sol print sol['x'] # Ai = numpy.matrix([0,1]) # Ap = numpy.matrix([0,1,2]) # b = numpy.matrix([1.,1.]) # c = numpy.matrix([1.,1.]) # # solution = p.solve(Ax, Ai, Ap, b, c) # print solution['x'] # print solution['y'] # print solution['status'] # # print getrefcount(solution['x']) h = hpy()
b = np.random.randn(m) q = QCML() q.parse(''' dimensions m n variable x(n) parameters A(m,n) b(m) minimize norm1(x) A*x == b ''') q.canonicalize() q.dims = {'m': m, 'n': n} q.codegen('python') socp_vars = q.prob2socp(locals()) # convert to CSR for fast row slicing to distribute problem socp_vars['A'] = socp_vars['A'].tocsr() socp_vars['G'] = socp_vars['G'].tocsr() # the size of the stuffed x or v n = socp_vars['A'].shape[1] ecos_sol = ecos.solve(**socp_vars) # solution to transformed socp (stuffed) socp_sol = ecos_sol['x'] # solution to original problem (unstuffed) prob_sol = q.socp2prob(ecos_sol['x'])['x']