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
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
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)]
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) ]
def transform_power(expr): p = expr.p if p == 1: return transform_expr(only_arg(expr)) if p == 0: return expression.scalar_constant(1) raise TransformError("Unexpected power exponent", expr)
def transform_norm_nuc(expr): X = only_arg(expr) m, n = dims(X) T = epi_var(expr, "norm_nuc", size=(m+n, m+n)) obj = expression.multiply( expression.scalar_constant(0.5), expression.trace(T)) return obj, [ expression.semidefinite(T), expression.eq_constraint(expression.index(T, 0, m, m, m+n), X)]
def transform_norm_nuc(expr): X = only_arg(expr) m, n = dims(X) T = epi_var(expr, "norm_nuc", size=(m + n, m + n)) obj = expression.multiply(expression.scalar_constant(0.5), expression.trace(T)) return obj, [ expression.semidefinite(T), expression.eq_constraint(expression.index(T, 0, m, m, m + n), X) ]
def transform_huber(expr): n = epi_var(expr, "huber_n") s = epi_var(expr, "huber_s") # n**2 + 2*M*|s| t, constr = transform_expr( expression.add( expression.power(n, 2), expression.multiply(expression.scalar_constant(2 * expr.M), expression.abs_val(s)))) # x == s + n x = only_arg(expr) constr.append(expression.eq_constraint(x, expression.add(s, n))) return t, constr
def transform_huber(expr): n = epi_var(expr, "huber_n") s = epi_var(expr, "huber_s") # n**2 + 2*M*|s| t, constr = transform_expr( expression.add( expression.power(n, 2), expression.multiply( expression.scalar_constant(2*expr.M), expression.abs_val(s)))) # x == s + n x = only_arg(expr) constr.append(expression.eq_constraint(x, expression.add(s, n))) return t, constr
def transform_power(expr): p = expr.p if p == 1: return only_arg(expr) one = expression.scalar_constant(1, size=dims(expr)) if p == 0: return one, [] t = epi_var(expr, "power") x = only_arg(expr) if p < 0: p, w = power_tools.pow_neg(p) constrs = gm_constrs(one, [x, t], w) if 0 < p < 1: p, w = power_tools.pow_mid(p) constrs = gm_constrs(t, [x, one], w) if p > 1: p, w = power_tools.pow_high(p) constrs = gm_constrs(x, [t, one], w) return t, constrs
def gm(t, x, y): return expression.soc_elemwise_constraint( expression.add(x, y), expression.add(x, expression.negate(y)), expression.multiply(expression.scalar_constant(2), t))
def transform_indicator(expr): return expression.scalar_constant(0, size=dims(expr)), [expr]