def test_convexify_obj(self): """Test convexify objective """ obj = Maximize(sum_entries(square(self.x))) self.x.value = [1,1] obj_conv = convexify_obj(obj) prob_conv = Problem(obj_conv, [self.x <= -1]) prob_conv.solve() self.assertAlmostEqual(prob_conv.value,-6) obj = Minimize(sqrt(self.a)) self.a.value = 1 obj_conv = convexify_obj(obj) prob_conv = Problem(obj_conv,sqrt(self.a).domain) prob_conv.solve() self.assertAlmostEqual(prob_conv.value,0.5)
def test_convexify_obj(self): """Test convexify objective """ obj = Maximize(sum_entries(square(self.x))) self.x.value = [1, 1] obj_conv = convexify_obj(obj) prob_conv = Problem(obj_conv, [self.x <= -1]) prob_conv.solve() self.assertAlmostEqual(prob_conv.value, -6) obj = Minimize(sqrt(self.a)) self.a.value = 1 obj_conv = convexify_obj(obj) prob_conv = Problem(obj_conv, sqrt(self.a).domain) prob_conv.solve() self.assertAlmostEqual(prob_conv.value, 0.5)
def iter_dccp(self, max_iter, tau, mu, tau_max, solver, **kwargs): """ ccp iterations :param max_iter: maximum number of iterations in ccp :param tau: initial weight on slack variables :param mu: increment of weight on slack variables :param tau_max: maximum weight on slack variables :param solver: specify the solver for the transformed problem :return value of the objective function, maximum value of slack variables, value of variables """ # split non-affine equality constraints constr = [] for arg in self.constraints: if str( type(arg) ) == "<class 'cvxpy.constraints.zero.Zero'>" and not arg.is_dcp(): constr.append(arg.expr.args[0] + arg.expr.args[1] <= 0) constr.append(-arg.expr.args[0] - arg.expr.args[1] <= 0) else: constr.append(arg) obj = self.objective self = cvx.Problem(obj, constr) it = 1 converge = False # keep the values from the previous iteration or initialization previous_cost = float("inf") previous_org_cost = self.objective.value variable_pres_value = [] for var in self.variables(): variable_pres_value.append(var.value) # each non-dcp constraint needs a slack variable var_slack = [] for constr in self.constraints: if not constr.is_dcp(): var_slack.append(cvx.Variable(constr.size)) while it <= max_iter and all(var.value is not None for var in self.variables()): constr_new = [] # objective temp = convexify_obj(self.objective) if not self.objective.is_dcp(): # non-sub/super-diff while temp is None: # damping var_index = 0 for var in self.variables(): #var_index = self.variables().index(var) var.value = 0.8 * var.value + 0.2 * variable_pres_value[ var_index] var_index += 1 temp = convexify_obj(self.objective) # domain constraints for dom in self.objective.args[0].domain: constr_new.append(dom) # new cost function cost_new = temp.args[0] # constraints count_slack = 0 for arg in self.constraints: temp = convexify_constr(arg) if not arg.is_dcp(): while temp is None: # damping for var in self.variables: var_index = self.variables().index(var) var.value = 0.8 * var.value + 0.2 * variable_pres_value[ var_index] temp = convexify_constr(arg) newcon = temp[0] # new constraint without slack variable for dom in temp[1]: # domain constr_new.append(dom) constr_new.append(newcon.expr <= var_slack[count_slack]) constr_new.append(var_slack[count_slack] >= 0) count_slack = count_slack + 1 else: constr_new.append(temp) # objective if self.objective.NAME == 'minimize': for var in var_slack: cost_new += tau * cvx.sum(var) obj_new = cvx.Minimize(cost_new) else: for var in var_slack: cost_new -= tau * cvx.sum(var) obj_new = cvx.Maximize(cost_new) # new problem prob_new = cvx.Problem(obj_new, constr_new) # keep previous value of variables variable_pres_value = [] for var in self.variables(): variable_pres_value.append(var.value) # solve if solver is None: logger.info("iteration=%d, cost value=%.5f, tau=%.5f", it, prob_new.solve(**kwargs), tau) else: logger.info("iteration=%d, cost value=%.5f, tau=%.5f", it, prob_new.solve(solver=solver, **kwargs), tau) max_slack = None # print slack if (prob_new._status == "optimal" or prob_new._status == "optimal_inaccurate") and not var_slack == []: slack_values = [v.value for v in var_slack if v.value is not None] max_slack = max([np.max(v) for v in slack_values] + [-np.inf]) logger.info("max slack = %.5f", max_slack) #terminate if np.abs(previous_cost - prob_new.value) <= 1e-5 and np.abs( self.objective.value - previous_org_cost) <= 1e-5: it_real = it it = max_iter + 1 converge = True else: previous_cost = prob_new.value previous_org_cost = self.objective.value it_real = it tau = min([tau * mu, tau_max]) it += 1 # return if converge: self._status = "Converged" else: self._status = "Not_converged" var_value = [] for var in self.variables(): var_value.append(var.value) if not var_slack == []: return (self.objective.value, max_slack, var_value) else: return (self.objective.value, var_value)
def iter_dccp(self, max_iter, tau, mu, tau_max, solver, ep, max_slack_tol, **kwargs): """ ccp iterations :param max_iter: maximum number of iterations in ccp :param tau: initial weight on slack variables :param mu: increment of weight on slack variables :param tau_max: maximum weight on slack variables :param solver: specify the solver for the transformed problem :return value of the objective function, maximum value of slack variables, value of variables """ # split non-affine equality constraints constr = [] for constraint in self.constraints: if str(type(constraint)) == "<class 'cvxpy.constraints.zero.Equality'>" and not constraint.is_dcp(): constr.append(constraint.args[0] <= constraint.args[1]) constr.append(constraint.args[0] >= constraint.args[1]) else: constr.append(constraint) obj = self.objective self = cvx.Problem(obj, constr) it = 1 converge = False # keep the values from the previous iteration or initialization previous_cost = float("inf") previous_org_cost = self.objective.value variable_pres_value = [] for var in self.variables(): variable_pres_value.append(var.value) # each non-dcp constraint needs a slack variable var_slack = [] for constr in self.constraints: if not constr.is_dcp(): var_slack.append(cvx.Variable(constr.shape)) while it <= max_iter and all(var.value is not None for var in self.variables()): constr_new = [] # objective convexified_obj = convexify_obj(self.objective) if not self.objective.is_dcp(): # non-sub/super-diff while convexified_obj is None: # damping var_index = 0 for var in self.variables(): #var_index = self.variables().index(var) var.value = 0.8*var.value + 0.2* variable_pres_value[var_index] var_index += 1 convexified_obj = convexify_obj(self.objective) # domain constraints for dom in self.objective.expr.domain: constr_new.append(dom) # new cost function cost_new = convexified_obj.expr # constraints count_slack = 0 for arg in self.constraints: temp = convexify_constr(arg) if not arg.is_dcp(): while temp is None: # damping for var in self.variables: var_index = self.variables().index(var) var.value = 0.8 * var.value + 0.2 * variable_pres_value[var_index] temp = convexify_constr(arg) newcon = temp[0] # new constraint without slack variable for dom in temp[1]:# domain constr_new.append(dom) constr_new.append(newcon.expr <= var_slack[count_slack]) constr_new.append(var_slack[count_slack] >= 0) count_slack = count_slack + 1 else: constr_new.append(arg) # objective if self.objective.NAME == 'minimize': for var in var_slack: cost_new += tau*cvx.sum(var) obj_new = cvx.Minimize(cost_new) else: for var in var_slack: cost_new -= tau*cvx.sum(var) obj_new = cvx.Maximize(cost_new) # new problem prob_new = cvx.Problem(obj_new, constr_new) # keep previous value of variables variable_pres_value = [] for var in self.variables(): variable_pres_value.append(var.value) # solve if solver is None: logger.info("iteration=%d, cost value=%.5f, tau=%.5f", it, prob_new.solve(**kwargs), tau) else: logger.info("iteration=%d, cost value=%.5f, tau=%.5f", it, prob_new.solve(solver=solver, **kwargs), tau) max_slack = None # print slack if (prob_new._status == "optimal" or prob_new._status == "optimal_inaccurate") and not var_slack == []: slack_values = [v.value for v in var_slack if v.value is not None] max_slack = max([np.max(v) for v in slack_values] + [-np.inf]) logger.info("max slack = %.5f", max_slack) #terminate if prob_new.value is not None and np.abs(previous_cost - prob_new.value) <= ep and np.abs(self.objective.value - previous_org_cost) <= ep \ and (max_slack is None or max_slack <= max_slack_tol ): it = max_iter+1 converge = True else: previous_cost = prob_new.value previous_org_cost = self.objective.value tau = min([tau*mu,tau_max]) it += 1 # return if converge: self._status = "Converged" else: self._status = "Not_converged" var_value = [] for var in self.variables(): var_value.append(var.value) if not var_slack == []: return(self.objective.value, max_slack, var_value) else: return(self.objective.value, var_value)