def _get_var_offsets(self, objective, constraints): """Maps each variable to a horizontal offset. Parameters ---------- objective : Expression The canonicalized objective. constraints : list The canonicalized constraints. Returns ------- tuple (map of variable to offset, length of variable vector) """ vars_ = lu.get_expr_vars(objective) for constr in constraints: vars_ += lu.get_expr_vars(constr.expr) var_offsets = OrderedDict() var_sizes = {} # Ensure the variables are always in the same # order for the same problem. var_names = list(set(vars_)) var_names.sort(key=lambda (var_id, var_size): var_id) # Map var ids to offsets. vert_offset = 0 for var_id, var_size in var_names: var_sizes[var_id] = var_size var_offsets[var_id] = vert_offset vert_offset += var_size[0]*var_size[1] return (var_offsets, var_sizes, vert_offset)
def _get_var_offsets(self, objective, constraints): """Maps each variable to a horizontal offset. Parameters ---------- objective : Expression The canonicalized objective. constraints : list The canonicalized constraints. Returns ------- tuple (map of variable to offset, length of variable vector) """ vars_ = lu.get_expr_vars(objective) for constr in constraints: vars_ += lu.get_expr_vars(constr.expr) var_offsets = OrderedDict() var_sizes = {} # Ensure the variables are always in the same # order for the same problem. var_names = list(set(vars_)) var_names.sort(key=lambda (var_id, var_size): var_id) # Map var ids to offsets. vert_offset = 0 for var_id, var_size in var_names: var_sizes[var_id] = var_size var_offsets[var_id] = vert_offset vert_offset += var_size[0] * var_size[1] return (var_offsets, var_sizes, vert_offset)
def _get_var_offsets(self, objective, constraints, nonlinear=None): """Maps each variable to a horizontal offset. Parameters ---------- objective : Expression The canonicalized objective. constraints : list The canonicalized constraints. nonlinear : list, optional Non-linear constraints for CVXOPT. Returns ------- tuple (map of variable to offset, length of variable vector) """ vars_ = lu.get_expr_vars(objective) for constr in constraints: vars_ += lu.get_expr_vars(constr.expr) # If CVXOPT is the solver, some of the variables are # in NonLinearConstraints. if nonlinear is not None: for constr in nonlinear: for nonlin_var in constr.variables(): vars_ += lu.get_expr_vars(nonlin_var) var_offsets = OrderedDict() var_sizes = {} # Ensure the variables are always in the same # order for the same problem. var_names = list(set(vars_)) var_names.sort(key=lambda (var_id, var_size): var_id) # Map var ids to offsets. vert_offset = 0 for var_id, var_size in var_names: var_sizes[var_id] = var_size var_offsets[var_id] = vert_offset vert_offset += var_size[0]*var_size[1] return (var_offsets, var_sizes, vert_offset)
def get_var_offsets(objective, constraints, nonlinear): """Maps each variable to a horizontal offset. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The canonicalized constraints. nonlinear : list Non-linear constraints for CVXOPT. Returns ------- tuple (map of variable to offset, length of variable vector) """ vars_ = lu.get_expr_vars(objective) for constr in constraints: vars_ += lu.get_expr_vars(constr.expr) # If CVXOPT is the solver, some of the variables are # in NonLinearConstraints. for constr in nonlinear: for nonlin_var in constr.args: vars_ += lu.get_expr_vars(nonlin_var) var_offsets = OrderedDict() # Ensure the variables are always in the same # order for the same problem. var_names = list(set(vars_)) var_names.sort(key=lambda id_and_shape: id_and_shape[0]) # Map var ids to offsets and shape. var_shapes = {} vert_offset = 0 for var_id, var_shape in var_names: var_shapes[var_id] = var_shape var_offsets[var_id] = vert_offset vert_offset += np.prod(var_shape, dtype=int) return (var_offsets, var_shapes, vert_offset)
def presolve(objective, constr_map): """Eliminates unnecessary constraints and short circuits the solver if possible. Parameters ---------- objective : LinOp The canonicalized objective. constr_map : dict A map of constraint type to a list of constraints. Returns ------- bool Is the problem infeasible? """ # Remove redundant constraints. for key, constraints in constr_map.items(): ids = set() uniq_constr = [] for c in constraints: if c.constr_id not in ids: uniq_constr.append(c) ids.add(c.constr_id) constr_map[key] = uniq_constr # If there are no constraints, the problem is unbounded # if any of the coefficients are non-zero. # If all the coefficients are zero then return the constant term # and set all variables to 0. if not any(constr_map.values()): str(objective) # TODO # Remove constraints with no variables or parameters. for key in [s.EQ, s.LEQ]: new_constraints = [] for constr in constr_map[key]: vars_ = lu.get_expr_vars(constr.expr) if len(vars_) == 0 and not lu.get_expr_params(constr.expr): V, I, J, coeff = canonInterface.get_problem_matrix( [constr]) is_pos, is_neg = intf.sign(coeff) # For equality constraint, coeff must be zero. # For inequality (i.e. <= 0) constraint, # coeff must be negative. if key == s.EQ and not (is_pos and is_neg) or \ key == s.LEQ and not is_neg: return s.INFEASIBLE else: new_constraints.append(constr) constr_map[key] = new_constraints return None
def test_get_vars(self): """Test getting vars from an expression. """ shape = (5, 4) x = create_var(shape) y = create_var(shape) A = create_const(np.ones(shape), shape) # Expanding dict. add_expr = sum_expr([x, y, A]) vars_ = get_expr_vars(add_expr) ref = [(x.data, shape), (y.data, shape)] self.assertCountEqual(vars_, ref)
def test_leq_constr(self): """Test creating a less than or equal constraint. """ shape = (5, 5) x = create_var(shape) y = create_var(shape) lh_expr = sum_expr([x, y]) value = np.ones(shape) rh_expr = create_const(value, shape) constr = create_leq(lh_expr, rh_expr) self.assertEqual(constr.shape, shape) vars_ = get_expr_vars(constr.expr) ref = [(x.data, shape), (y.data, shape)] self.assertCountEqual(vars_, ref)
def presolve(objective, constr_map, check_params=False): """Eliminates unnecessary constraints and short circuits the solver if possible. Parameters ---------- objective : LinOp The canonicalized objective. constr_map : dict A map of constraint type to a list of constraints. check_params : bool, optional Should constraints with parameters be evaluated? Returns ------- bool Is the problem infeasible? """ # Remove redundant constraints. for key, constraints in constr_map.items(): uniq_constr = unique(constraints, key=lambda c: c.constr_id) constr_map[key] = list(uniq_constr) # If there are no constraints, the problem is unbounded # if any of the coefficients are non-zero. # If all the coefficients are zero then return the constant term # and set all variables to 0. if not any(constr_map.values()): str(objective) # TODO # Remove constraints with no variables or parameters. for key in [s.EQ, s.LEQ]: new_constraints = [] for constr in constr_map[key]: vars_ = lu.get_expr_vars(constr.expr) if len(vars_) == 0 and not lu.get_expr_params(constr.expr): coeff = op2mat.get_constant_coeff(constr.expr) sign = intf.sign(coeff) # For equality constraint, coeff must be zero. # For inequality (i.e. <= 0) constraint, # coeff must be negative. if key is s.EQ and not sign.is_zero() or \ key is s.LEQ and not sign.is_negative(): return s.INFEASIBLE else: new_constraints.append(constr) constr_map[key] = new_constraints return None
def test_eq_constr(self): """Test creating an equality constraint. """ shape = (5, 5) x = create_var(shape) y = create_var(shape) lh_expr = sum_expr([x, y]) value = np.ones(shape) rh_expr = create_const(value, shape) constr = create_eq(lh_expr, rh_expr) self.assertEqual(constr.shape, shape) vars_ = get_expr_vars(constr.expr) ref = [(x.data, shape), (y.data, shape)] if PY2: self.assertItemsEqual(vars_, ref) else: self.assertCountEqual(vars_, ref)
def format(self, eq_constr, leq_constr, dims, solver): """Formats SDP constraints as inequalities for the solver. Parameters ---------- eq_constr : list A list of the equality constraints in the canonical problem. leq_constr : list A list of the inequality constraints in the canonical problem. dims : dict A dict with the dimensions of the conic constraints. solver : str The solver being called. """ new_eq = self.__format[0] # If an equality constraint was introduced, update eq_constr and dims. if new_eq: eq_constr += new_eq dims[s.EQ_DIM] += self.size[0] * self.size[1] # Record the noncvx_var id. bool_id = lu.get_expr_vars(self.noncvx_var)[0][0] dims[self.CONSTR_TYPE].append(bool_id)
def format(self, eq_constr, leq_constr, dims, solver): """Formats SDP constraints as inequalities for the solver. Parameters ---------- eq_constr : list A list of the equality constraints in the canonical problem. leq_constr : list A list of the inequality constraints in the canonical problem. dims : dict A dict with the dimensions of the conic constraints. solver : str The solver being called. """ new_eq = self.__format[0] # If an equality constraint was introduced, update eq_constr and dims. if new_eq: eq_constr += new_eq dims[s.EQ_DIM] += self.size[0]*self.size[1] # Record the noncvx_var id. bool_id = lu.get_expr_vars(self.noncvx_var)[0][0] dims[self.CONSTR_TYPE].append(bool_id)
def test_consistency(self): """Test that variables and constraints keep a consistent order. """ import itertools num_solves = 4 vars_lists = [] ineqs_lists = [] var_ids_order_created = [] for k in range(num_solves): sum = 0 constraints = [] var_ids = [] for i in range(100): var = Variable(name=str(i)) var_ids.append(var.id) sum += var constraints.append(var >= i) var_ids_order_created.append(var_ids) obj = Minimize(sum) p = Problem(obj, constraints) objective, constr_map = p.canonicalize() all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.LEQ]) var_offsets, var_sizes, x_length = p._get_var_offsets(objective, all_ineq) # Sort by offset. vars_ = sorted(var_offsets.items(), key=lambda (var_id, offset): offset) vars_ = [var_id for (var_id, offset) in vars_] vars_lists.append(vars_) ineqs_lists.append(constr_map[s.LEQ]) # Verify order of variables is consistent. for i in range(num_solves): self.assertEqual(var_ids_order_created[i], vars_lists[i]) for i in range(num_solves): for idx, constr in enumerate(ineqs_lists[i]): var_id, _ = lu.get_expr_vars(constr.expr)[0] self.assertEqual(var_ids_order_created[i][idx], var_id)
def test_consistency(self): """Test that variables and constraints keep a consistent order. """ import itertools num_solves = 4 vars_lists = [] ineqs_lists = [] var_ids_order_created = [] for k in range(num_solves): sum = 0 constraints = [] var_ids = [] for i in range(100): var = Variable(name=str(i)) var_ids.append(var.id) sum += var constraints.append(var >= i) var_ids_order_created.append(var_ids) obj = Minimize(sum) p = Problem(obj, constraints) objective, constr_map = p.canonicalize() all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.LEQ]) var_offsets, var_sizes, x_length = p._get_var_offsets( objective, all_ineq) # Sort by offset. vars_ = sorted(var_offsets.items(), key=lambda (var_id, offset): offset) vars_ = [var_id for (var_id, offset) in vars_] vars_lists.append(vars_) ineqs_lists.append(constr_map[s.LEQ]) # Verify order of variables is consistent. for i in range(num_solves): self.assertEqual(var_ids_order_created[i], vars_lists[i]) for i in range(num_solves): for idx, constr in enumerate(ineqs_lists[i]): var_id, _ = lu.get_expr_vars(constr.expr)[0] self.assertEqual(var_ids_order_created[i][idx], var_id)
from cvxpy.lin_ops.tree_mat import mul, tmul, prune_constants import cvxpy.problems.iterative as iterative from cvxpy.problems.solvers.utilities import SOLVERS from cvxpy.problems.problem_data.sym_data import SymData import numpy as np import numpy.linalg import scipy.sparse as sp import scipy.linalg as LA import unittest import faoInterface # Convolution x = Variable(3) f = np.matrix(np.array([1, 2, 3])).T g = np.array([0, 1, 0.5]) f_conv_g = np.array([0., 1., 2.5, 4., 1.5]) expr = conv(f, x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = g output_arr = np.zeros(5) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) # self.assertItemsAlmostEqual(output_arr, f_conv_g) input_arr = np.array(range(5)) output_arr = np.zeros(3) toep = LA.toeplitz(np.array([1, 0, 0]), np.array([1, 2, 3, 0, 0])) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) print output_arr print toep
def test_fao_mul(self): """Test the mul method. """ n = 2 ones = np.ones(n) # Matrix-vector multiplication. x = Variable(n) A = np.matrix("1 2; 3 4").A expr = (A * x).canonical_form[0] input_arr = np.ones(n) output_arr = np.zeros(n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == A.dot(ones)).all() input_arr = np.ones(n) output_arr = np.zeros(n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == A.T.dot(ones)).all() n = 2 m = 3 ones = np.ones((m, n)) # Matrix-matrix multiplication. x = Variable(m, n) A = np.matrix("1 2 3; 4 5 6").A expr = (A * x).canonical_form[0] input_arr = np.ones(m * n) output_arr = np.zeros(n * n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == A.dot(ones).flatten(order='F')).all() ones = np.ones((n, n)) input_arr = np.ones(n * n) output_arr = np.zeros(m * n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == A.T.dot(ones).flatten(order='F')).all() # Addition n = 2 x = Variable(n, n) y = Variable(n, n) expr = (y + x).canonical_form[0] input_arr = np.array(range(2 * n * n)) output_arr = np.zeros(n * n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == np.array([0 + 4, 1 + 5, 2 + 6, 3 + 7])).all() input_arr = np.array(range(n * n)) output_arr = np.zeros(2 * n * n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == np.hstack([input_arr, input_arr])).all() # Negation x = Variable(3, 2) expr = (-x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = np.arange(6) output_arr = np.zeros(3 * 2) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == -input_arr).all() input_arr = np.arange(6) output_arr = np.zeros(3 * 2) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == -input_arr).all() # Convolution x = Variable(3) f = np.matrix(np.array([1, 2, 3])).T g = np.array([0, 1, 0.5]) f_conv_g = np.array([0., 1., 2.5, 4., 1.5]) expr = conv(f, x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = g output_arr = np.zeros(5) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) self.assertItemsAlmostEqual(output_arr, f_conv_g) input_arr = np.array(range(5)) output_arr = np.zeros(3) toep = LA.toeplitz(np.array([1, 0, 0]), np.array([1, 2, 3, 0, 0])) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) print output_arr print toep self.assertItemsAlmostEqual(output_arr, toep.dot(input_arr))
from cvxpy.problems.solvers.utilities import SOLVERS from cvxpy.problems.problem_data.sym_data import SymData import numpy as np import numpy.linalg import scipy.sparse as sp import scipy.linalg as LA import unittest import faoInterface # Convolution x = Variable(3) f = np.matrix(np.array([1, 2, 3])).T g = np.array([0, 1, 0.5]) f_conv_g = np.array([ 0., 1., 2.5, 4., 1.5]) expr = conv(f, x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = g output_arr = np.zeros(5) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) # self.assertItemsAlmostEqual(output_arr, f_conv_g) input_arr = np.array(range(5)) output_arr = np.zeros(3) toep = LA.toeplitz(np.array([1,0,0]), np.array([1, 2, 3, 0, 0])) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) print output_arr print toep
def test_fao_mul(self): """Test the mul method. """ n = 2 ones = np.ones(n) # Matrix-vector multiplication. x = Variable(n) A = np.matrix("1 2; 3 4").A expr = (A*x).canonical_form[0] input_arr = np.ones(n) output_arr = np.zeros(n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == A.dot(ones)).all() input_arr = np.ones(n) output_arr = np.zeros(n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == A.T.dot(ones)).all() n = 2 m = 3 ones = np.ones((m,n)) # Matrix-matrix multiplication. x = Variable(m,n) A = np.matrix("1 2 3; 4 5 6").A expr = (A*x).canonical_form[0] input_arr = np.ones(m*n) output_arr = np.zeros(n*n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == A.dot(ones).flatten(order='F')).all() ones = np.ones((n,n)) input_arr = np.ones(n*n) output_arr = np.zeros(m*n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == A.T.dot(ones).flatten(order='F')).all() # Addition n = 2 x = Variable(n, n) y = Variable(n, n) expr = (y + x).canonical_form[0] input_arr = np.array(range(2*n*n)) output_arr = np.zeros(n*n) vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == np.array([0 + 4, 1 + 5, 2 + 6, 3 + 7])).all() input_arr = np.array(range(n*n)) output_arr = np.zeros(2*n*n) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == np.hstack([input_arr, input_arr])).all() # Negation x = Variable(3,2) expr = (-x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = np.arange(6) output_arr = np.zeros(3*2) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) assert (output_arr == -input_arr).all() input_arr = np.arange(6) output_arr = np.zeros(3*2) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) assert (output_arr == -input_arr).all() # Convolution x = Variable(3) f = np.matrix(np.array([1, 2, 3])).T g = np.array([0, 1, 0.5]) f_conv_g = np.array([ 0., 1., 2.5, 4., 1.5]) expr = conv(f, x).canonical_form[0] vars_ = lu.get_expr_vars(expr) dag = fao.tree_to_dag(expr, vars_) input_arr = g output_arr = np.zeros(5) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr) self.assertItemsAlmostEqual(output_arr, f_conv_g) input_arr = np.array(range(5)) output_arr = np.zeros(3) toep = LA.toeplitz(np.array([1,0,0]), np.array([1, 2, 3, 0, 0])) faoInterface.eval_FAO_DAG(dag, input_arr, output_arr, forward=False) print output_arr print toep self.assertItemsAlmostEqual(output_arr, toep.dot(input_arr))