Exemplo n.º 1
0
    def apply(self, problem):
        inverse_data = InverseData(problem)
        real2imag = {
            var.id: lu.get_id()
            for var in problem.variables() if var.is_complex()
        }
        constr_dict = {
            cons.id: lu.get_id()
            for cons in problem.constraints if cons.is_complex()
        }
        real2imag.update(constr_dict)
        inverse_data.real2imag = real2imag

        leaf_map = {}
        real_obj, imag_obj = self.canonicalize_tree(problem.objective,
                                                    inverse_data.real2imag,
                                                    leaf_map)
        assert imag_obj is None

        constrs = []
        for constraint in problem.constraints:
            # real2imag maps variable id to a potential new variable
            # created for the imaginary part.
            real_constrs, imag_constrs = self.canonicalize_tree(
                constraint, inverse_data.real2imag, leaf_map)
            if real_constrs is not None:
                constrs.extend(real_constrs)
            if imag_constrs is not None:
                constrs.extend(imag_constrs)

        new_problem = problems.problem.Problem(real_obj, constrs)
        return new_problem, inverse_data
Exemplo n.º 2
0
    def apply(self, problem):
        """See docstring for MatrixStuffing.apply"""
        inverse_data = InverseData(problem)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        params_to_P, params_to_q, flattened_variable = self.stuffed_objective(
            problem, extractor)
        # Lower equality and inequality to Zero and NonPos.
        cons = []
        for con in problem.constraints:
            if isinstance(con, Equality):
                con = lower_equality(con)
            elif isinstance(con, Inequality):
                con = lower_ineq_to_nonpos(con)
            cons.append(con)

        # Reorder constraints to Zero, NonPos.
        constr_map = group_constraints(cons)
        ordered_cons = constr_map[Zero] + constr_map[NonPos]
        inverse_data.cons_id_map = {con.id: con.id for con in ordered_cons}

        inverse_data.constraints = ordered_cons
        # Batch expressions together, then split apart.
        expr_list = [arg for c in ordered_cons for arg in c.args]
        params_to_Ab = extractor.affine(expr_list)

        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = ParamQuadProg(params_to_P, params_to_q,
                                 flattened_variable, params_to_Ab,
                                 problem.variables(), inverse_data.var_offsets,
                                 ordered_cons, problem.parameters(),
                                 inverse_data.param_id_map)
        return new_prob, inverse_data
Exemplo n.º 3
0
    def apply(self, problem):
        inverse_data = InverseData(problem)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        params_to_objective, flattened_variable = self.stuffed_objective(
            problem, extractor)
        # Lower equality and inequality to Zero and NonNeg.
        cons = []
        for con in problem.constraints:
            if isinstance(con, Equality):
                con = lower_equality(con)
            elif isinstance(con, Inequality):
                con = lower_ineq_to_nonneg(con)
            elif isinstance(con, NonPos):
                con = nonpos2nonneg(con)
            elif isinstance(con, SOC) and con.axis == 1:
                con = SOC(con.args[0], con.args[1].T, axis=0,
                          constr_id=con.constr_id)
            elif isinstance(con, PowCone3D) and con.args[0].ndim > 1:
                x, y, z = con.args
                alpha = con.alpha
                con = PowCone3D(x.flatten(), y.flatten(), z.flatten(), alpha.flatten(),
                                constr_id=con.constr_id)
            elif isinstance(con, ExpCone) and con.args[0].ndim > 1:
                x, y, z = con.args
                con = ExpCone(x.flatten(), y.flatten(), z.flatten(),
                              constr_id=con.constr_id)
            cons.append(con)
        # Reorder constraints to Zero, NonNeg, SOC, PSD, EXP, PowCone3D
        constr_map = group_constraints(cons)
        ordered_cons = constr_map[Zero] + constr_map[NonNeg] + \
            constr_map[SOC] + constr_map[PSD] + constr_map[ExpCone] + constr_map[PowCone3D]
        inverse_data.cons_id_map = {con.id: con.id for con in ordered_cons}

        inverse_data.constraints = ordered_cons
        # Batch expressions together, then split apart.
        expr_list = [arg for c in ordered_cons for arg in c.args]
        params_to_problem_data = extractor.affine(expr_list)

        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = ParamConeProg(params_to_objective,
                                 flattened_variable,
                                 params_to_problem_data,
                                 problem.variables(),
                                 inverse_data.var_offsets,
                                 ordered_cons,
                                 problem.parameters(),
                                 inverse_data.param_id_map)
        return new_prob, inverse_data
Exemplo n.º 4
0
    def apply(self, problem):
        inverse_data = InverseData(problem)

        leaf_map = {}
        real_obj, imag_obj = self.canonicalize_tree(problem.objective,
                                                    inverse_data.real2imag,
                                                    leaf_map)
        assert imag_obj is None

        constrs = []
        for constraint in problem.constraints:
            if type(constraint) == Equality:
                constraint = utilities.lower_equality(constraint)
            elif type(constraint) == Inequality:
                constraint = utilities.lower_inequality(constraint)
            # real2imag maps variable id to a potential new variable
            # created for the imaginary part.
            real_constrs, imag_constrs = self.canonicalize_tree(
                constraint, inverse_data.real2imag, leaf_map)
            if real_constrs is not None:
                constrs.extend(real_constrs)
            if imag_constrs is not None:
                constrs.extend(imag_constrs)

        new_problem = problems.problem.Problem(real_obj, constrs)
        return new_problem, inverse_data
Exemplo n.º 5
0
    def apply(self, problem):
        inverse_data = InverseData(problem)

        new_obj, new_var = self.stuffed_objective(problem, inverse_data)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        new_cons = []
        for con in problem.constraints:
            arg_list = []
            for arg in con.args:
                A, b = extractor.get_coeffs(arg)
                arg_list.append(reshape(A * new_var + b, arg.shape))
            new_cons.append(con.copy(arg_list))
            inverse_data.cons_id_map[con.id] = new_cons[-1].id

        # Map of old constraint id to new constraint id.
        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = problems.problem.Problem(Minimize(new_obj), new_cons)
        return new_prob, inverse_data
Exemplo n.º 6
0
	def apply(self, problem):
		inverse_data = InverseData(problem)
		is_minimize = type(problem.objective) == Minimize
		chance_expr, chance_constraints = self.chance_tree(problem.objective.args[0], is_minimize, True, False)
		chance_objective = Minimize(chance_expr) if is_minimize else Maximize(chance_expr)
		
		if any([type(atom) == cc.quantile for con in problem.constraints for atom in con.atoms()]):
			raise DCPError("Quantile atom may not be nested in constraints.")
		new_problem = cc.problem.Problem(chance_objective, problem.constraints + chance_constraints)
		return new_problem, inverse_data
Exemplo n.º 7
0
    def apply(self, problem):
        """See docstring for MatrixStuffing.apply"""
        inverse_data = InverseData(problem)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        new_obj, new_var, r = self.stuffed_objective(problem, extractor)
        inverse_data.r = r
        # Lower equality and inequality to Zero and NonPos.
        cons = []
        for con in problem.constraints:
            if isinstance(con, Equality):
                con = lower_equality(con)
            elif isinstance(con, Inequality):
                con = lower_inequality(con)
            cons.append(con)

        # Batch expressions together, then split apart.
        expr_list = [arg for c in cons for arg in c.args]
        problem_data_tensor = extractor.affine(expr_list)
        Afull, bfull = canon.get_matrix_and_offset_from_unparameterized_tensor(
            problem_data_tensor, new_var.size)
        if 0 not in Afull.shape and 0 not in bfull.shape:
            Afull = cvxtypes.constant()(Afull)
            bfull = cvxtypes.constant()(np.atleast_1d(bfull))

        new_cons = []
        offset = 0
        for orig_con, con in zip(problem.constraints, cons):
            arg_list = []
            for arg in con.args:
                A = Afull[offset:offset + arg.size, :]
                b = bfull[offset:offset + arg.size]
                arg_list.append(reshape(A @ new_var + b, arg.shape))
                offset += arg.size
            new_constraint = con.copy(arg_list)
            new_cons.append(new_constraint)

        inverse_data.constraints = new_cons
        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = problems.problem.Problem(Minimize(new_obj), new_cons)
        return new_prob, inverse_data
Exemplo n.º 8
0
    def apply(self, problem):
        inverse_data = InverseData(problem)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        new_obj, new_var, r = self.stuffed_objective(problem, extractor)
        inverse_data.r = r
        # Lower equality and inequality to Zero and NonPos.
        cons = []
        for con in problem.constraints:
            if isinstance(con, Equality):
                con = lower_equality(con)
            elif isinstance(con, Inequality):
                con = lower_inequality(con)
            elif isinstance(con, SOC) and con.axis == 1:
                con = SOC(con.args[0],
                          con.args[1].T,
                          axis=0,
                          constr_id=con.constr_id)
            cons.append(con)

        # Batch expressions together, then split apart.
        expr_list = [arg for con in cons for arg in con.args]
        Afull, bfull = extractor.affine(expr_list)
        new_cons = []
        offset = 0
        for con in cons:
            arg_list = []
            for arg in con.args:
                A = Afull[offset:offset + arg.size, :]
                b = bfull[offset:offset + arg.size]
                arg_list.append(reshape(A * new_var + b, arg.shape))
                offset += arg.size
            new_cons.append(con.copy(arg_list))
            inverse_data.cons_id_map[con.id] = new_cons[-1].id

        # Map of old constraint id to new constraint id.
        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = problems.problem.Problem(Minimize(new_obj), new_cons)
        return new_prob, inverse_data
Exemplo n.º 9
0
    def apply(self, problem):
        inverse_data = InverseData(problem)

        canon_objective, canon_constraints = self.canonicalize_tree(
            problem.objective)

        for constraint in problem.constraints:
            # canon_constr is the constraint rexpressed in terms of
            # its canonicalized arguments, and aux_constr are the constraints
            # generated while canonicalizing the arguments of the original
            # constraint
            canon_constr, aux_constr = self.canonicalize_tree(constraint)
            canon_constraints += aux_constr + [canon_constr]
            inverse_data.cons_id_map.update({constraint.id: canon_constr.id})

        new_problem = problems.problem.Problem(canon_objective,
                                               canon_constraints)
        return new_problem, inverse_data
Exemplo n.º 10
0
    def stuffed_objective(self, problem, inverse_data):
        # We need to copy the problem because we are changing atoms in the
        # expression tree
        problem_copy = problems.problem.Problem(
            Minimize(problem.objective.expr.tree_copy()),
            [con.tree_copy() for con in problem.constraints])
        inverse_data_of_copy = InverseData(problem_copy)
        extractor = CoeffExtractor(inverse_data_of_copy)
        # extract to x.T * P * x + q.T * x, store r
        P, q, r = extractor.quad_form(problem_copy.objective.expr)

        # concatenate all variables in one vector
        boolean, integer = extract_mip_idx(problem.variables())
        x = Variable(inverse_data.x_length, boolean=boolean, integer=integer)
        new_obj = QuadForm(x, P) + q.T * x

        inverse_data.r = r
        return new_obj, x
Exemplo n.º 11
0
    def apply(self, problem):
        inverse_data = InverseData(problem)

        leaf_map = {}
        real_obj, imag_obj = self.canonicalize_tree(
            problem.objective, inverse_data.real2imag, leaf_map)
        assert imag_obj is None

        constrs = []
        for constraint in problem.constraints:
            real_constr, imag_constr = self.canonicalize_tree(
                constraint, inverse_data.real2imag, leaf_map)
            if real_constr is not None:
                constrs.append(real_constr)
            if imag_constr is not None:
                constrs.append(imag_constr)

        new_problem = problems.problem.Problem(real_obj,
                                               constrs)
        return new_problem, inverse_data
Exemplo n.º 12
0
    def apply(self, problem):
        """Returns a stuffed problem.

        The returned problem is a minimization problem in which every
        constraint in the problem has affine arguments that are expressed in
        the form A @ x + b.


        Parameters
        ----------
        problem: The problem to stuff; the arguments of every constraint
            must be affine
        constraints: A list of constraints, whose arguments are affine

        Returns
        -------
        Problem
            The stuffed problem
        InverseData
            Data for solution retrieval
        """
        inverse_data = InverseData(problem)
        # Form the constraints
        extractor = CoeffExtractor(inverse_data)
        new_obj, new_var, r = self.stuffed_objective(problem, extractor)
        inverse_data.r = r
        # Lower equality and inequality to Zero and NonPos.
        cons = []
        for con in problem.constraints:
            if isinstance(con, Equality):
                con = lower_equality(con)
            elif isinstance(con, Inequality):
                con = lower_inequality(con)
            elif isinstance(con, SOC) and con.axis == 1:
                con = SOC(con.args[0], con.args[1].T, axis=0,
                          constr_id=con.constr_id)
            cons.append(con)

        # Batch expressions together, then split apart.
        expr_list = [arg for c in cons for arg in c.args]
        Afull, bfull = extractor.affine(expr_list)
        if 0 not in Afull.shape and 0 not in bfull.shape:
            Afull = cvxtypes.constant()(Afull)
            bfull = cvxtypes.constant()(bfull)

        new_cons = []
        offset = 0
        for con in cons:
            arg_list = []
            for arg in con.args:
                A = Afull[offset:offset+arg.size, :]
                b = bfull[offset:offset+arg.size]
                arg_list.append(reshape(A*new_var + b, arg.shape))
                offset += arg.size
            new_cons.append(con.copy(arg_list))
            # Map old constraint id to new constraint id.
            inverse_data.cons_id_map[con.id] = new_cons[-1].id

        inverse_data.minimize = type(problem.objective) == Minimize
        new_prob = problems.problem.Problem(Minimize(new_obj), new_cons)
        return new_prob, inverse_data
Exemplo n.º 13
0
    def apply(self, problem):
        """
        Construct QP problem data stored in a dictionary.
        The QP has the following form

            minimize      1/2 x' P x + q' x
            subject to    A x =  b
                          F x <= g

        """
        inverse_data = InverseData(problem)

        obj = problem.objective
        # quadratic part of objective is x.T * P * x but solvers expect
        # 0.5*x.T * P * x.
        P = 2 * obj.expr.args[0].args[1].value
        q = obj.expr.args[1].args[0].value.flatten()

        # Get number of variables
        n = problem.size_metrics.num_scalar_variables

        # TODO(akshayka): This dependence on ConicSolver is hacky; something
        # should change here.
        eq_cons = [c for c in problem.constraints if type(c) == Zero]
        if eq_cons:
            eq_coeffs = list(
                zip(*[
                    ConicSolver.get_coeff_offset(con.expr) for con in eq_cons
                ]))
            A = sp.vstack(eq_coeffs[0])
            b = -np.concatenate(eq_coeffs[1])
        else:
            A, b = sp.csr_matrix((0, n)), -np.array([])

        ineq_cons = [c for c in problem.constraints if type(c) == NonPos]
        if ineq_cons:
            ineq_coeffs = list(
                zip(*[
                    ConicSolver.get_coeff_offset(con.expr) for con in ineq_cons
                ]))
            F = sp.vstack(ineq_coeffs[0])
            g = -np.concatenate(ineq_coeffs[1])
        else:
            F, g = sp.csr_matrix((0, n)), -np.array([])

        # Create dictionary with problem data
        variables = problem.variables()[0]
        data = {}
        data[s.P] = sp.csc_matrix(P)
        data[s.Q] = q
        data[s.A] = sp.csc_matrix(A)
        data[s.B] = b
        data[s.F] = sp.csc_matrix(F)
        data[s.G] = g
        data[s.BOOL_IDX] = [t[0] for t in variables.boolean_idx]
        data[s.INT_IDX] = [t[0] for t in variables.integer_idx]
        data['n_var'] = n
        data['n_eq'] = A.shape[0]
        data['n_ineq'] = F.shape[0]

        inverse_data.sorted_constraints = eq_cons + ineq_cons

        # Add information about integer variables
        inverse_data.is_mip = \
            len(data[s.BOOL_IDX]) > 0 or len(data[s.INT_IDX]) > 0

        return data, inverse_data