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
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, []
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)
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
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)