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) """ x = arg_objs[0] axis = data[0] t = lu.create_var(size) # sum(exp(x - t)) <= 1 if axis is None: prom_t = lu.promote(t, x.size) expr = lu.sub_expr(x, prom_t) obj, constraints = exp.graph_implementation([expr], x.size) obj = lu.sum_entries(obj) elif axis == 0: prom_size = (x.size[0], 1) ones = lu.create_const(np.ones(prom_size), prom_size) prom_t = lu.mul_expr(ones, t, x.size) expr = lu.sub_expr(x, prom_t) obj, constraints = exp.graph_implementation([expr], x.size) const_size = (1, x.size[0]) ones = lu.create_const(np.ones(const_size), const_size) obj = lu.mul_expr(ones, obj, size) else: # axis == 1 prom_size = (1, x.size[1]) ones = lu.create_const(np.ones(prom_size), prom_size) prom_t = lu.rmul_expr(t, ones, x.size) expr = lu.sub_expr(x, prom_t) obj, constraints = exp.graph_implementation([expr], x.size) const_size = (x.size[1], 1) ones = lu.create_const(np.ones(const_size), const_size) obj = lu.rmul_expr(obj, ones, size) ones = lu.create_const(np.ones(size), size) constraints += [lu.create_leq(obj, ones)] return (t, constraints)
def graph_implementation(arg_objs, size, data=None): # min 1-sqrt(2z-z^2) # s.t. x>=0, z<=1, z = x+s, s<=0 x = arg_objs[0] z = lu.create_var(size) s = lu.create_var(size) zeros = lu.create_const(np.mat(np.zeros(size)),size) ones = lu.create_const(np.mat(np.ones(size)),size) z2, constr_square = power.graph_implementation([z],size, (2, (Fraction(1,2), Fraction(1,2)))) two_z = lu.sum_expr([z,z]) sub = lu.sub_expr(two_z, z2) sq, constr_sqrt = power.graph_implementation([sub],size, (Fraction(1,2), (Fraction(1,2), Fraction(1,2)))) obj = lu.sub_expr(ones, sq) constr = [lu.create_eq(z, lu.sum_expr([x,s]))]+[lu.create_leq(zeros,x)]+[lu.create_leq(z, ones)]+[lu.create_leq(s,zeros)]+constr_square+constr_sqrt return (obj, constr)
def qol_elemwise(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) """ x = arg_objs[0] y = arg_objs[1] t = lu.create_var(x.size) two = lu.create_const(2, (1, 1)) constraints = [SOC_Elemwise(lu.sum_expr([y, t]), [lu.sub_expr(y, t), lu.mul_expr(two, x, x.size)]), lu.create_geq(y)] return (t, constraints)
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) """ A = arg_objs[0] n, _ = A.size # Requires that A is symmetric. obj, constraints = transpose.graph_implementation([A], (n, n)) # A == A.T constraints.append(lu.create_eq(A, obj)) # SDP constraint. t = lu.create_var((1, 1)) prom_t = lu.promote(t, (n, 1)) # I*t - A expr = lu.sub_expr(A, lu.diag_vec(prom_t)) return (t, [SDP(expr)] + constraints)
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)
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) """ # Promote scalars. for idx, arg in enumerate(arg_objs): if arg.size != size: arg_objs[idx] = lu.promote(arg, size) x = arg_objs[0] y = arg_objs[1] v = lu.create_var(x.size) two = lu.create_const(2, (1, 1)) # SOC(x + y, [y - x, 2*v]) constraints = [ SOC_Elemwise(lu.sum_expr([x, y]), [lu.sub_expr(y, x), lu.mul_expr(two, v, v.size)]) ] # 0 <= x, 0 <= y constraints += [lu.create_geq(x), lu.create_geq(y)] return (v, constraints)
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) """ x = arg_objs[0] y = arg_objs[1] t = lu.create_var((1, 1)) constraints = [ExpCone(t, x, y), lu.create_geq(y)] # 0 <= y # -t - x + y obj = lu.sub_expr(y, lu.sum_expr([x, t])) return (obj, constraints)
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) """ x = arg_objs[0] t = lu.create_var((1, 1)) # sum(exp(x - t)) prom_t = lu.promote(t, x.size) expr = lu.sub_expr(x, prom_t) obj, constraints = exp.graph_implementation([expr], x.size) obj, constr = sum_entries.graph_implementation([obj], (1, 1)) # obj <= 1 one = lu.create_const(1, (1, 1)) constraints += constr + [lu.create_leq(obj, one)] return (t, constraints)
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) """ x = arg_objs[0] y = arg_objs[1] # Known to be a scalar. v = lu.create_var((1, 1)) two = lu.create_const(2, (1, 1)) constraints = [SOC(lu.sum_expr([y, v]), [lu.sub_expr(y, v), lu.mul_expr(two, x, x.size)]), lu.create_geq(y)] return (v, constraints)
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) """ x = arg_objs[0] t = lu.create_var(size) # log(1 + exp(x)) <= t <=> exp(-t) + exp(x - t) <= 1 obj0, constr0 = exp.graph_implementation([lu.neg_expr(t)], size) obj1, constr1 = exp.graph_implementation([lu.sub_expr(x, t)], size) lhs = lu.sum_expr([obj0, obj1]) ones = lu.create_const(np.mat(np.ones(size)), size) constr = constr0 + constr1 + [lu.create_leq(lhs, ones)] return (t, constr)
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) """ A = arg_objs[0] n, _ = A.size # SDP constraint. t = lu.create_var((1, 1)) prom_t = lu.promote(t, (n, 1)) # I*t - A expr = lu.sub_expr(lu.diag_vec(prom_t), A) return (t, [SDP(expr)])
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) """ x = arg_objs[0] y = arg_objs[1] # Known to be a scalar. v = lu.create_var((1, 1)) two = lu.create_const(2, (1, 1)) constraints = [ SOC(lu.sum_expr([y, v]), [lu.sub_expr(y, v), lu.mul_expr(two, x, x.size)]), lu.create_geq(y) ] return (v, constraints)
def qol_elemwise(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) """ x = arg_objs[0] y = arg_objs[1] t = lu.create_var(x.size) two = lu.create_const(2, (1, 1)) constraints = [ SOC_Elemwise( lu.sum_expr([y, t]), [lu.sub_expr(y, t), lu.mul_expr(two, x, x.size)]), lu.create_geq(y) ] return (t, constraints)
def gm(t, x, y): length = t.size[0] * t.size[1] return SOC_Axis( lu.reshape(lu.sum_expr([x, y]), (length, 1)), lu.vstack([ lu.reshape(lu.sub_expr(x, y), (1, length)), lu.reshape(lu.mul_expr(two, t, t.size), (1, length)) ], (2, length)), 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) """ x = arg_objs[0] t = lu.create_var(size) # log(1 + exp(x)) <= t <=> exp(-t) + exp(x - t) <= 1 ''' obj0, constr0 = exp.graph_implementation([lu.neg_expr(t)], size) obj1, constr1 = exp.graph_implementation([lu.sub_expr(x, t)], size) lhs = lu.sum_expr([obj0, obj1]) ones = lu.create_const(np.mat(np.ones(size)), size) constr = constr0 + constr1 + [lu.create_leq(lhs, ones)] ''' s = data[0] if isinstance(s, Parameter): s = lu.create_param(s, (1, 1)) else: # M is constant. s = lu.create_const(s, (1, 1)) #Wrong sign? obj0, constr0 = exp.graph_implementation([lu.neg_expr(t)], size) obj1, constr1 = exp.graph_implementation([lu.sub_expr(s, lu.sum_expr([t, x]))], size) obj2, constr2 = exp.graph_implementation([lu.sub_expr(lu.neg_expr(s), lu.sum_expr([t, x]))], size) obj3, constr3 = exp.graph_implementation([lu.sub_expr(lu.neg_expr(t), lu.mul_expr(2, x, size))], size) lhs = lu.sum_expr([obj0, obj1, obj2, obj3]) ones = lu.create_const(np.mat(np.ones(size)), size) constr = constr0 + constr1 + constr2 + constr3 + [lu.create_leq(lhs, ones)] return (t, constr)
def gm(t, x, y): length = t.size[0]*t.size[1] return SOC_Axis(lu.reshape(lu.sum_expr([x, y]), (length, 1)), lu.vstack([ lu.reshape(lu.sub_expr(x, y), (1, length)), lu.reshape(lu.mul_expr(two, t, t.size), (1, length)) ], (2, length)), 0)
def graph_implementation(arg_objs, size, data=None): # min 1-sqrt(2z-z^2) # s.t. x>=0, z<=1, z = x+s, s<=0 x = arg_objs[0] z = lu.create_var(size) s = lu.create_var(size) zeros = lu.create_const(np.mat(np.zeros(size)), size) ones = lu.create_const(np.mat(np.ones(size)), size) z2, constr_square = power.graph_implementation( [z], size, (2, (Fraction(1, 2), Fraction(1, 2)))) two_z = lu.sum_expr([z, z]) sub = lu.sub_expr(two_z, z2) sq, constr_sqrt = power.graph_implementation( [sub], size, (Fraction(1, 2), (Fraction(1, 2), Fraction(1, 2)))) obj = lu.sub_expr(ones, sq) constr = [lu.create_eq(z, lu.sum_expr([x, s]))] + [ lu.create_leq(zeros, x) ] + [lu.create_leq(z, ones)] + [lu.create_leq(s, zeros) ] + constr_square + constr_sqrt return (obj, constr)
def gm(t, x, y): return SOC_Elemwise(lu.sum_expr([x, y]), [lu.sub_expr(x, y), lu.mul_expr(two, t, t.size)])