예제 #1
0
 def set_affine_constraints(G, h, y, K_aff):
     constraints = []
     i = 0
     if K_aff[a2d.ZERO]:
         dim = K_aff[a2d.ZERO]
         constraints.append(G[i:i + dim, :] @ y == h[i:i + dim])
         i += dim
     if K_aff[a2d.NONNEG]:
         dim = K_aff[a2d.NONNEG]
         constraints.append(G[i:i + dim, :] @ y <= h[i:i + dim])
         i += dim
     for dim in K_aff[a2d.SOC]:
         expr = h[i:i + dim] - G[i:i + dim, :] @ y
         constraints.append(SOC(expr[0], expr[1:]))
         i += dim
     if K_aff[a2d.EXP]:
         dim = 3 * K_aff[a2d.EXP]
         expr = cp.reshape(h[i:i + dim] - G[i:i + dim, :] @ y,
                           (dim // 3, 3),
                           order='C')
         constraints.append(ExpCone(expr[:, 0], expr[:, 1], expr[:, 2]))
         i += dim
     if K_aff[a2d.POW3D]:
         alpha = np.array(K_aff[a2d.POW3D])
         expr = cp.reshape(h[i:] - G[i:, :] @ y, (alpha.size, 3), order='C')
         constraints.append(
             PowCone3D(expr[:, 0], expr[:, 1], expr[:, 2], alpha))
     return constraints
예제 #2
0
def pow_nd_canon(con, args):
    """
    con : PowConeND
        We can extract metadata from this.
        For example, con.alpha and con.axis.
    args : tuple of length two
        W,z = args[0], args[1]
    """
    alpha, axis = con.get_data()
    alpha = alpha.value
    W, z = args
    if axis == 1:
        W = W.T
        alpha = alpha.T
    if W.ndim == 1:
        W = reshape(W, (W.size, 1))
        alpha = np.reshape(alpha, (W.size, 1))
    n, k = W.shape
    if n == 2:
        can_con = PowCone3D(W[0, :], W[1, :], z, alpha[0, :])
    else:
        T = Variable(shape=(n - 2, k))
        x_3d, y_3d, z_3d, alpha_3d = [], [], [], []
        for j in range(k):
            x_3d.append(W[:-1, j])
            y_3d.append(T[:, j])
            y_3d.append(W[n - 1, j])
            z_3d.append(z[j])
            z_3d.append(T[:, j])
            r_nums = alpha[:, j]
            r_dens = np.cumsum(r_nums[::-1])[::-1]
            # ^ equivalent to [np.sum(alpha[i:, j]) for i in range(n)]
            r = r_nums / r_dens
            alpha_3d.append(r[:n - 1])
        x_3d = hstack(x_3d)
        y_3d = hstack(y_3d)
        z_3d = hstack(z_3d)
        alpha_p3d = hstack(alpha_3d)
        # TODO: Ideally we should construct x,y,z,alpha_p3d by
        #   applying suitable sparse matrices to W,z,T, rather
        #   than using the hstack atom. (hstack will probably
        #   result in longer compile times).
        can_con = PowCone3D(x_3d, y_3d, z_3d, alpha_p3d)
    # Return a single PowCone3D constraint defined over all auxiliary
    # variables needed for the reduction to go through.
    # There are no "auxiliary constraints" beyond this one.
    return can_con, []
예제 #3
0
 def test_pow3d_constraint(self) -> None:
     n = 3
     np.random.seed(0)
     alpha = 0.275
     x, y, z = Variable(n), Variable(n), Variable(n)
     con = PowCone3D(x, y, z, alpha)
     # check violation against feasible values
     x0, y0 = 0.1 + np.random.rand(n), 0.1 + np.random.rand(n)
     z0 = x0**alpha * y0**(1 - alpha)
     z0[1] *= -1
     x.value, y.value, z.value = x0, y0, z0
     viol = con.residual()
     self.assertLessEqual(viol, 1e-7)
     # check violation against infeasible values
     x1 = x0.copy()
     x1[0] *= -0.9
     x.value = x1
     viol = con.residual()
     self.assertGreaterEqual(viol, 0.99 * abs(x1[0]))
     # check invalid constraint data
     with self.assertRaises(ValueError):
         con = PowCone3D(x, y, z, 1.001)
     with self.assertRaises(ValueError):
         con = PowCone3D(x, y, z, -0.00001)
예제 #4
0
 def set_direct_constraints(y, K_dir):
     constraints = []
     i = K_dir[a2d.FREE]
     if K_dir[a2d.NONNEG]:
         dim = K_dir[a2d.NONNEG]
         constraints.append(y[i:i + dim] >= 0)
         i += dim
     for dim in K_dir[a2d.SOC]:
         constraints.append(SOC(y[i], y[i + 1:i + dim]))
         i += dim
     if K_dir[a2d.EXP]:
         dim = 3 * K_dir[a2d.EXP]
         expr = cp.reshape(y[i:i + dim], (dim // 3, 3), order='C')
         constraints.append(ExpCone(expr[:, 0], expr[:, 1], expr[:, 2]))
         i += dim
     if K_dir[a2d.POW3D]:
         alpha = np.array(K_dir[a2d.POW3D])
         expr = cp.reshape(y[i:], (alpha.size, 3), order='C')
         constraints.append(
             PowCone3D(expr[:, 0], expr[:, 1], expr[:, 2], alpha))
     return constraints
예제 #5
0
    def simulate_chain(in_prob):
        # Get a ParamConeProg object
        reductions = [Dcp2Cone(), CvxAttr2Constr(), ConeMatrixStuffing()]
        chain = Chain(None, reductions)
        cone_prog, inv_prob2cone = chain.apply(in_prob)

        # Dualize the problem, reconstruct a high-level cvxpy problem for the dual.
        # Solve the problem, invert the dualize reduction.
        cone_prog = ConicSolver().format_constraints(cone_prog,
                                                     exp_cone_order=[0, 1, 2])
        data, inv_data = a2d.Dualize.apply(cone_prog)
        A, b, c, K_dir = data[s.A], data[s.B], data[s.C], data['K_dir']
        y = cp.Variable(shape=(A.shape[1], ))
        constraints = [A @ y == b]
        i = K_dir[a2d.FREE]
        dual_prims = {a2d.FREE: y[:i], a2d.SOC: []}
        if K_dir[a2d.NONNEG]:
            dim = K_dir[a2d.NONNEG]
            dual_prims[a2d.NONNEG] = y[i:i + dim]
            constraints.append(y[i:i + dim] >= 0)
            i += dim
        for dim in K_dir[a2d.SOC]:
            dual_prims[a2d.SOC].append(y[i:i + dim])
            constraints.append(SOC(y[i], y[i + 1:i + dim]))
            i += dim
        if K_dir[a2d.DUAL_EXP]:
            exp_len = 3 * K_dir[a2d.DUAL_EXP]
            dual_prims[a2d.DUAL_EXP] = y[i:i + exp_len]
            y_de = cp.reshape(y[i:i + exp_len], (exp_len // 3, 3),
                              order='C')  # fill rows first
            constraints.append(
                ExpCone(-y_de[:, 1], -y_de[:, 0],
                        np.exp(1) * y_de[:, 2]))
            i += exp_len
        if K_dir[a2d.DUAL_POW3D]:
            alpha = np.array(K_dir[a2d.DUAL_POW3D])
            dual_prims[a2d.DUAL_POW3D] = y[i:]
            y_dp = cp.reshape(y[i:], (alpha.size, 3),
                              order='C')  # fill rows first
            pow_con = PowCone3D(y_dp[:, 0] / alpha, y_dp[:, 1] / (1 - alpha),
                                y_dp[:, 2], alpha)
            constraints.append(pow_con)
        objective = cp.Maximize(c @ y)
        dual_prob = cp.Problem(objective, constraints)
        dual_prob.solve(solver='SCS', eps=1e-8)
        dual_prims[a2d.FREE] = dual_prims[a2d.FREE].value
        if K_dir[a2d.NONNEG]:
            dual_prims[a2d.NONNEG] = dual_prims[a2d.NONNEG].value
        dual_prims[a2d.SOC] = [expr.value for expr in dual_prims[a2d.SOC]]
        if K_dir[a2d.DUAL_EXP]:
            dual_prims[a2d.DUAL_EXP] = dual_prims[a2d.DUAL_EXP].value
        if K_dir[a2d.DUAL_POW3D]:
            dual_prims[a2d.DUAL_POW3D] = dual_prims[a2d.DUAL_POW3D].value
        dual_duals = {s.EQ_DUAL: constraints[0].dual_value}
        dual_sol = cp.Solution(dual_prob.status, dual_prob.value, dual_prims,
                               dual_duals, dict())
        cone_sol = a2d.Dualize.invert(dual_sol, inv_data)

        # Pass the solution back up the solving chain.
        in_prob_sol = chain.invert(cone_sol, inv_prob2cone)
        in_prob.unpack(in_prob_sol)