def sign_for_intf(self, interface): """Test sign for a given interface. """ mat = interface.const_to_matrix([[1,2,3,4],[3,4,5,6]]) self.assertEquals(intf.sign(mat), Sign.POSITIVE) self.assertEquals(intf.sign(-mat), Sign.NEGATIVE) self.assertEquals(intf.sign(0*mat), Sign.ZERO) mat = interface.const_to_matrix([[-1,2,3,4],[3,4,5,6]]) self.assertEquals(intf.sign(mat), Sign.UNKNOWN)
def sign_for_intf(self, interface): """Test sign for a given interface. """ mat = interface.const_to_matrix([[1, 2, 3, 4], [3, 4, 5, 6]]) self.assertEquals(intf.sign(mat), Sign.POSITIVE) self.assertEquals(intf.sign(-mat), Sign.NEGATIVE) self.assertEquals(intf.sign(0 * mat), Sign.ZERO) mat = interface.const_to_matrix([[-1, 2, 3, 4], [3, 4, 5, 6]]) self.assertEquals(intf.sign(mat), Sign.UNKNOWN)
def sign_for_intf(self, interface): """Test sign for a given interface. """ mat = interface.const_to_matrix([[1, 2, 3, 4], [3, 4, 5, 6]]) self.assertEqual(intf.sign(mat), (True, False)) # Positive. self.assertEqual(intf.sign(-mat), (False, True)) # Negative. self.assertEqual(intf.sign(0*mat), (True, True)) # Zero. mat = interface.const_to_matrix([[-1, 2, 3, 4], [3, 4, 5, 6]]) self.assertEqual(intf.sign(mat), (False, False)) # Unknown.
def _validate_value(self, val): """Check that the value satisfies the leaf's symbolic attributes. Parameters ---------- val : numeric type The value assigned. Returns ------- numeric type The value converted to the proper matrix type. """ if val is not None: # Convert val to the proper matrix type. val = intf.DEFAULT_INTF.const_to_matrix(val) size = intf.size(val) if size != self.size: raise ValueError("Invalid dimensions (%s, %s) for %s value." % (size[0], size[1], self.__class__.__name__)) # All signs are valid if sign is unknown. # Otherwise value sign must match declared sign. pos_val, neg_val = intf.sign(val) if self.is_positive() and not pos_val or \ self.is_negative() and not neg_val: raise ValueError("Invalid sign for %s value." % self.__class__.__name__) # Round to correct sign. elif self.is_positive(): val = np.maximum(val, 0) elif self.is_negative(): val = np.minimum(val, 0) return val
def _validate_value(self, val): """Check that the value satisfies the leaf's symbolic attributes. Parameters ---------- val : numeric type The value assigned. Returns ------- numeric type The value converted to the proper matrix type. """ if val is not None: # Convert val to the proper matrix type. val = intf.DEFAULT_INTF.const_to_matrix(val) size = intf.size(val) if size != self.size: raise ValueError( "Invalid dimensions (%s, %s) for %s value." % (size[0], size[1], self.__class__.__name__) ) # All signs are valid if sign is unknown. # Otherwise value sign must match declared sign. pos_val, neg_val = intf.sign(val) if self.is_positive() and not pos_val or \ self.is_negative() and not neg_val: raise ValueError( "Invalid sign for %s value." % self.__class__.__name__ ) return val
def _validate_value(self, val): """Check that the value satisfies the parameter's symbolic attributes. Parameters ---------- val : numeric type The value assigned. Returns ------- numeric type The value converted to the proper matrix type. """ # Convert val to the proper matrix type. val = intf.DEFAULT_INTERFACE.const_to_matrix(val) size = intf.size(val) if size != self.size: raise ValueError("Invalid dimensions (%s, %s) for %s value." % (size[0], size[1], self.__class__.__name__)) # All signs are valid if sign is unknown. # Otherwise value sign must match declared sign. sign = intf.sign(val) if self.is_positive() and not sign.is_positive() or \ self.is_negative() and not sign.is_negative(): raise ValueError("Invalid sign for %s value." % self.__class__.__name__) return val
def _compute_attr(self): """Compute the attributes of the constant related to complex/real, sign. """ # Set DCP attributes. is_real, is_imag = intf.is_complex(self.value) if self.is_complex(): is_nonneg = is_nonpos = False else: is_nonneg, is_nonpos = intf.sign(self.value) self._imag = (is_imag and not is_real) self._nonpos = is_nonpos self._nonneg = is_nonneg
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 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 __init__(self, value): # TODO HACK. # A fix for c.T*x where c is a 1D array. self.is_1D_array = False # Keep sparse matrices sparse. if intf.is_sparse(value): self._value = intf.DEFAULT_SPARSE_INTF.const_to_matrix(value) self._sparse = True else: if isinstance(value, np.ndarray) and len(value.shape) == 1: self.is_1D_array = True self._value = intf.DEFAULT_INTF.const_to_matrix(value) self._sparse = False # Set DCP attributes. self._size = intf.size(self.value) self._is_pos, self._is_neg = intf.sign(self.value) super(Constant, self).__init__()
def init_dcp_attr(self): shape = u.Shape(*intf.size(self.value)) sign = intf.sign(self.value) self._dcp_attr = u.DCPAttr(sign, u.Curvature.CONSTANT, shape)