Example #1
0
def transform_norm_p(expr):
    p = expr.p
    x = only_arg(expr)
    t = epi_var(expr, "norm_p", size=(1,1))

    if p == float("inf"):
        return t, [expression.leq_constraint(x, t),
                   expression.leq_constraint(expression.negate(x), t)]

    if p == 1:
        return transform_expr(expression.sum_entries(expression.abs_val(x)))

    if p == 2:
        return t, [expression.soc_constraint(t, x)]

    r = epi_var(expr, "norm_p_r", size=dims(x))
    t1 = expression.multiply(expression.ones(*dims(x)), t)

    if p < 0:
        p, _ = power_tools.pow_neg(p)
        p = Fraction(p)
        constrs = gm_constrs(t1, [x, r], (-p/(1-p), 1/(1-p)))
    elif 0 < p < 1:
        p, _ = power_tools.pow_mid(p)
        p = Fraction(p)
        constrs = gm_constrs(r, [x, t1], (p, 1-p))
    elif p > 1:
        abs_x, constrs = transform_expr(expression.abs_val(x))
        p, _ = power_tools.pow_high(p)
        p = Fraction(p)
        constrs += gm_constrs(abs_x, [r, t1], (1/p, 1-1/p))

    constrs.append(expression.eq_constraint(expression.sum_entries(r), t))
    return t, constrs
Example #2
0
def transform_abs(expr):
    x = only_arg(expr)
    t = epi_var(expr, "abs")
    return t, [
        expression.leq_constraint(x, t),
        expression.leq_constraint(expression.negate(x), t)
    ]
Example #3
0
def transform_sum_largest(expr):
    x = only_arg(expr)
    k = expr.k
    q = epi_var(expr, "sum_largest")
    t = epi_var(expr, "sum_largest_t", size=dims(x))

    obj = expression.add(
        expression.sum_entries(t),
        expression.multiply(expression.scalar_constant(k), q))
    constr = [
        expression.leq_constraint(x, expression.add(t, q)),
        expression.leq_constraint(expression.scalar_constant(0), t)]

    return obj, constr
Example #4
0
def transform_sum_largest(expr):
    x = only_arg(expr)
    k = expr.k
    q = epi_var(expr, "sum_largest")
    t = epi_var(expr, "sum_largest_t", size=dims(x))

    obj = expression.add(expression.sum_entries(t),
                         expression.multiply(expression.scalar_constant(k), q))
    constr = [
        expression.leq_constraint(x, expression.add(t, q)),
        expression.leq_constraint(expression.scalar_constant(0), t)
    ]

    return obj, constr
Example #5
0
def epi(f_expr, t_expr):
    """An expression for an epigraph constraint.

    The constraint depends on the curvature of f:
      - f convex,  I(f(x) <= t)
      - f concave, I(f(x) >= t)
      - f affine,  I(f(x) == t)
    """
    f_curvature = f_expr.dcp_props.curvature.curvature_type
    if f_curvature == Curvature.CONVEX:
        return expression.leq_constraint(f_expr, t_expr)
    elif f_curvature == Curvature.CONCAVE:
        return expression.leq_constraint(negate(f_expr), negate(t_expr))
    elif f_curvature == Curvature.AFFINE:
        return expression.eq_constraint(f_expr, t_expr);
    raise TransformError("Unknown curvature", f_expr)
Example #6
0
def epigraph(expr):
    f_expr, t_expr = get_epigraph(expr)
    if f_expr:
        for rule in BASE_RULES:
            result = rule(f_expr)

            if result.match:
                epi_function = result.prox_expr.prox_function
                epi_function.epigraph = True
                epi_function.arg_size.add().CopyFrom(Size(dim=dims(t_expr)))

                linear_t_expr = linear.transform_expr(t_expr)
                if linear_t_expr.affine_props.scalar:
                    constrs = []
                else:
                    linear_t_expr, constrs = epi_transform(
                        linear_t_expr, "scalar")

                return MatchResult(
                    True,
                    expression.prox_function(
                        epi_function, *(result.prox_expr.arg + [linear_t_expr])),
                    result.raw_exprs + constrs)

        # No epigraph transform found, do conic transformation
        obj, constrs = conic.transform_expr(f_expr)
        return MatchResult(
            True,
            None,
            [expression.leq_constraint(obj, t_expr)] + constrs)

    # Not in epigraph form
    return MatchResult(False)
Example #7
0
def epigraph(expr):
    f_expr, t_expr = get_epigraph(expr)
    if f_expr:
        for rule in BASE_RULES:
            result = rule(f_expr)

            if result.match:
                epi_function = result.prox_expr.prox_function
                epi_function.epigraph = True
                epi_function.arg_size.add().CopyFrom(Size(dim=dims(t_expr)))

                linear_t_expr = linear.transform_expr(t_expr)
                if linear_t_expr.affine_props.scalar:
                    constrs = []
                else:
                    linear_t_expr, constrs = epi_transform(
                        linear_t_expr, "scalar")

                return MatchResult(
                    True,
                    expression.prox_function(
                        epi_function, *(result.prox_expr.arg + [linear_t_expr])),
                    result.raw_exprs + constrs)

        # No epigraph transform found, do conic transformation
        obj, constrs = conic.transform_expr(f_expr)
        return MatchResult(
            True,
            None,
            [expression.leq_constraint(obj, t_expr)] + constrs)

    # Not in epigraph form
    return MatchResult(False)
Example #8
0
def transform_max_entries(expr):
    x = only_arg(expr)
    m, n = dims(x)
    t = epi_var(expr, "max_entries")
    if not expr.has_axis:
        return t, [expression.leq_constraint(x, t)]
    if expr.axis == 0:
        return t, [
            expression.leq_constraint(
                x, expression.multiply(expression.ones(m, 1), t))]
    if expr.axis == 1:
        return t, [
            expression.leq_constraint(
                x, expression.multiply(t, expression.ones(1, n)))]

    raise TransformError("unknown axis attribute", expr)
Example #9
0
def transform_norm_p(expr):
    p = expr.p
    x = only_arg(expr)
    t = epi_var(expr, "norm_p")

    if p == float("inf"):
        return t, [
            expression.leq_constraint(x, t),
            expression.leq_constraint(expression.negate(x), t)
        ]

    if p == 1:
        return transform_expr(expression.sum_entries(expression.abs_val(x)))

    if p == 2:
        if not expr.has_axis:
            return t, [
                expression.soc_constraint(t, expression.reshape(x, 1, dim(x)))
            ]
        if expr.axis == 0:
            return t, [
                expression.soc_constraint(expression.reshape(t, dim(x, 1), 1),
                                          expression.transpose(x))
            ]
        if expr.axis == 1:
            return t, [expression.soc_constraint(t, x)]

    r = epi_var(expr, "norm_p_r", size=dims(x))
    t1 = expression.multiply(expression.ones(*dims(x)), t)

    if p < 0:
        p, _ = power_tools.pow_neg(p)
        p = Fraction(p)
        constrs = gm_constrs(t1, [x, r], (-p / (1 - p), 1 / (1 - p)))
    elif 0 < p < 1:
        p, _ = power_tools.pow_mid(p)
        p = Fraction(p)
        constrs = gm_constrs(r, [x, t1], (p, 1 - p))
    elif p > 1:
        abs_x, constrs = transform_expr(expression.abs_val(x))
        p, _ = power_tools.pow_high(p)
        p = Fraction(p)
        constrs += gm_constrs(abs_x, [r, t1], (1 / p, 1 - 1 / p))

    constrs.append(expression.eq_constraint(expression.sum_entries(r), t))
    return t, constrs
Example #10
0
def epi(f_expr, t_expr):
    """An expression for an epigraph constraint.

    The constraint depends on the curvature of f:
      - f convex,  I(f(x) <= t)
      - f concave, I(f(x) >= t)
      - f affine,  I(f(x) == t)
    """
    f_curvature = f_expr.dcp_props.curvature.curvature_type
    if f_curvature == Curvature.CONVEX:
        return expression.leq_constraint(f_expr, t_expr)
    elif f_curvature == Curvature.CONCAVE:
        return expression.leq_constraint(expression.negate(f_expr),
                                         expression.negate(t_expr))
    elif f_curvature == Curvature.AFFINE:
        return expression.eq_constraint(f_expr, t_expr)
    raise TransformError(
        "Unknown curvature: %s" % Curvature.Type.Name(f_curvature), f_expr)
Example #11
0
def transform_max_entries(expr):
    x = only_arg(expr)
    m, n = dims(x)
    t = epi_var(expr, "max_entries")
    if not expr.has_axis:
        return t, [expression.leq_constraint(x, t)]
    if expr.axis == 0:
        return t, [
            expression.leq_constraint(
                x, expression.multiply(expression.ones(m, 1), t))
        ]
    if expr.axis == 1:
        return t, [
            expression.leq_constraint(
                x, expression.multiply(t, expression.ones(1, n)))
        ]

    raise TransformError("unknown axis attribute", expr)
Example #12
0
def transform_quad_over_lin(expr):
    assert len(expr.arg) == 2
    x, y = expr.arg
    assert dim(y) == 1

    t = epi_var(expr, "qol", size=(1,1))
    return t, [
        expression.soc_constraint(
            expression.add(y, t),
            expression.vstack(
                expression.add(y, expression.negate(t)),
                expression.reshape(
                    expression.multiply(expression.scalar_constant(2), x),
                    dim(x), 1))),
        expression.leq_constraint(expression.scalar_constant(0), y)]
Example #13
0
def transform_quad_over_lin(expr):
    assert len(expr.arg) == 2
    x, y = expr.arg
    assert dim(y) == 1

    t = epi_var(expr, "qol", size=(1, 1))
    return t, [
        expression.soc_constraint(
            expression.add(y, t),
            expression.hstack(
                expression.add(y, expression.negate(t)),
                expression.reshape(
                    expression.multiply(expression.scalar_constant(2), x), 1,
                    dim(x)))),
        expression.leq_constraint(expression.scalar_constant(0), y)
    ]
Example #14
0
def epigraph(expr):
    f_expr, t_expr = get_epigraph(expr)
    if f_expr:
        for rule in BASE_RULES:
            result = rule(f_expr)

            if result.match:
                epi_function = result.prox_expr.prox_function
                epi_function.epigraph = True

                return MatchResult(
                    True, expression.prox_function(epi_function, *(result.prox_expr.arg + [t_expr])), result.raw_exprs
                )

        # No epigraph transform found, do conic transformation
        obj, constrs = conic.transform_expr(f_expr)
        return MatchResult(True, None, [expression.leq_constraint(obj, t_expr)] + constrs)

    # Not in epigraph form
    return MatchResult(False)
Example #15
0
def convert_constraint(constraint):
    if isinstance(constraint, EqConstraint):
        return expression.eq_constraint(convert_expression(constraint.args[0]),
                                        convert_expression(constraint.args[1]))
    elif isinstance(constraint, PSDConstraint):
        return expression.psd_constraint(
            convert_expression(constraint.args[0]),
            convert_expression(constraint.args[1]))
    elif isinstance(constraint, LeqConstraint):
        return expression.leq_constraint(
            convert_expression(constraint.args[0]),
            convert_expression(constraint.args[1]))
    elif isinstance(constraint, SOC_Elemwise):
        return expression.soc_elemwise_constraint(
            convert_expression(constraint.t),
            *[convert_expression(x) for x in constraint.x_elems])
    elif isinstance(constraint, SOC):
        return expression.soc_contraint(
            convert_expression(constraint.t),
            expression.vstack(
                *[convert_expression(x) for x in constraint.x_elems]))

    raise RuntimeError("Unknown constraint: %s" % type(constraint))
Example #16
0
def convert_constraint(constraint):
    if isinstance(constraint, EqConstraint):
        return expression.eq_constraint(
            convert_expression(constraint.args[0]),
            convert_expression(constraint.args[1]))
    elif isinstance(constraint, PSDConstraint):
        return expression.psd_constraint(
            convert_expression(constraint.args[0]),
            convert_expression(constraint.args[1]))
    elif isinstance(constraint, LeqConstraint):
        return expression.leq_constraint(
            convert_expression(constraint.args[0]),
            convert_expression(constraint.args[1]))
    elif isinstance(constraint, SOC_Elemwise):
        return expression.soc_elemwise_constraint(
            convert_expression(constraint.t),
            *[convert_expression(x) for x in constraint.x_elems])
    elif isinstance(constraint, SOC):
        return expression.soc_contraint(
            convert_expression(constraint.t),
            expression.vstack(
                *[convert_expression(x) for x in constraint.x_elems]))

    raise RuntimeError("Unknown constraint: %s" % type(constraint))
Example #17
0
def transform_exp(expr):
    x = only_arg(expr)
    t = epi_var(expr, "exp")
    return t, [expression.leq_constraint(expr, t)]
Example #18
0
def transform_min_elementwise(expr):
    t = epi_var(expr, "min_elementwise")
    return t, [expression.leq_constraint(t, x) for x in expr.arg]
Example #19
0
def transform_min_elementwise(expr):
    t = epi_var(expr, "min")
    return t, [expression.leq_constraint(t, x) for x in expr.arg]
Example #20
0
def transform_max_elementwise(expr):
    t = epi_var(expr, "max")
    return t, [expression.leq_constraint(x, t) for x in expr.arg]
Example #21
0
def transform_exp(expr):
    x = only_arg(expr)
    t = epi_var(expr, "exp")
    return t, [expression.leq_constraint(expr, t)]
Example #22
0
def transform_abs(expr):
    x = only_arg(expr)
    t = epi_var(expr, "abs")
    return t, [expression.leq_constraint(x, t),
               expression.leq_constraint(expression.negate(x), t)]
Example #23
0
def transform_log(expr):
    x = only_arg(expr)
    t = epi_var(expr, "log")
    return t, [expression.leq_constraint(expression.exp(t), x)]
Example #24
0
def transform_log(expr):
    x = only_arg(expr)
    t = epi_var(expr, "log")
    return t, [expression.leq_constraint(expression.exp(t), x)]