Ejemplo n.º 1
0
    def test_socp(self):
        """Test SOCP problems.
        """
        for solver in self.solvers:
            # Basic.
            p = Problem(Minimize(self.b), [pnorm(self.x, p=2) <= self.b])
            pmod = Problem(Minimize(self.b), [SOC(self.b, self.x)])
            self.assertTrue(ConeMatrixStuffing().accepts(pmod))
            p_new = ConeMatrixStuffing().apply(pmod)
            if not solver.accepts(p_new[0]):
                return
            result = p.solve(solver.name())
            sltn = solve_wrapper(solver, p_new[0])
            self.assertAlmostEqual(sltn.opt_val, result)
            inv_sltn = ConeMatrixStuffing().invert(sltn, p_new[1])
            self.assertAlmostEqual(inv_sltn.opt_val, result)
            for var in p.variables():
                self.assertItemsAlmostEqual(inv_sltn.primal_vars[var.id],
                                            var.value)

            # More complex.
            p = Problem(Minimize(self.b), [pnorm(self.x/2 + self.y[:2], p=2) <= self.b+5,
                                           self.x >= 1, self.y == 5])
            pmod = Problem(Minimize(self.b), [SOC(self.b+5, self.x/2 + self.y[:2]),
                                              self.x >= 1, self.y == 5])
            self.assertTrue(ConeMatrixStuffing().accepts(pmod))
            result = p.solve(solver.name())
            p_new = ConeMatrixStuffing().apply(pmod)
            sltn = solve_wrapper(solver, p_new[0])
            self.assertAlmostEqual(sltn.opt_val, result, places=2)
            inv_sltn = ConeMatrixStuffing().invert(sltn, p_new[1])
            self.assertAlmostEqual(inv_sltn.opt_val, result, places=2)
            for var in p.variables():
                self.assertItemsAlmostEqual(inv_sltn.primal_vars[var.id],
                                            var.value, places=2)
Ejemplo n.º 2
0
    def graph_implementation(arg_objs, size, data=None):
        """Reduces the atom to an affine expression and list of constraints.

        Parameters
        ----------
        arg_objs : list
            LinExpr for each argument.
        size : tuple
            The size of the resulting expression.
        data :
            Additional data required by the atom.

        Returns
        -------
        tuple
            (LinOp for objective, list of constraints)
        """
        # TODO use log for n != 2.
        v = lu.create_var((1, 1))
        x = arg_objs[0]
        y = arg_objs[1]
        two = lu.create_const(2, (1, 1))
        # SOC(x + y, [y - x, 2*v])
        constraints = [
            SOC(lu.sum_expr([x, y]),
                [lu.sub_expr(y, x),
                 lu.mul_expr(two, v, (1, 1))])
        ]
        # 0 <= x, 0 <= y
        constraints += [lu.create_geq(x), lu.create_geq(y)]
        return (v, constraints)
Ejemplo n.º 3
0
def soc_canon(expr, real_args, imag_args, real2imag):
    # Imaginary.
    if real_args[1] is None:
        output = [SOC(real_args[0], imag_args[1],
                      axis=expr.axis, constr_id=real2imag[expr.id])]
    elif imag_args[1] is None:  # Real
        output = [SOC(real_args[0], real_args[1],
                      axis=expr.axis, constr_id=expr.id)]
    else:  # Complex.
        orig_shape = real_args[1].shape
        real = real_args[1].flatten()
        imag = imag_args[1].flatten()
        flat_X = Variable(real.shape)
        inner_SOC = SOC(flat_X,
                        vstack([real, imag]),
                        axis=0)
        real_X = reshape(flat_X, orig_shape)
        outer_SOC = SOC(real_args[0], real_X,
                        axis=expr.axis, constr_id=expr.id)
        output = [inner_SOC, outer_SOC]
    return output, None
Ejemplo n.º 4
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
Ejemplo n.º 5
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
Ejemplo n.º 6
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