def test_margins_2d(self): cc = ChanceConstraint([self.U <= 0, min(self.V) >= 5]) self.U.value = np.array([[1, 2], [3, 4]]) self.V.value = np.array([[-2, 3], [-1, 2], [0, 1]]) margins = cc.margins() self.assertEqual(len(margins), 2) self.assertItemsAlmostEqual(margins[0], self.U.value, places=8) self.assertItemsAlmostEqual(margins[1], 5 - np.min(self.V.value), places=8)
def test_dcp(self): # Prob(g(x) >= 0) <= p is DCP iff g is convex. constr = [ChanceConstraint(log(self.x) >= 0, 0.5)] p = ccprob.Problem(Minimize(norm(self.x)), constr) with self.assertRaises(DCPError) as cm: p.solve() # Prob(h(x) <= 0) <= p is DCP iff h is concave. constr = [ChanceConstraint(exp(self.x) <= 5, 0.8)] p = ccprob.Problem(Minimize(norm(self.x)), constr) with self.assertRaises(DCPError) as cm: p.solve()
def test_restriction_2d(self): cc = ChanceConstraint([self.U <= 0], 0.8) self.U.value = np.array([[-1, -2], [3, 4]]) cc.slope.value = 0.5 val = np.sum(np.maximum(0.5 - self.U.value, 0)) / self.U.size - 0.5 * 0.8 self.assertItemsAlmostEqual(cc.restriction.expr.value, val)
def test_slack(self): b = np.abs(np.random.randn(*self.x.shape)) obj = sum_squares(self.x - b) constr = [ChanceConstraint(self.x >= 0, 0.8)] p = ccprob.Problem(Minimize(obj), constr) p.solve(slack=False) val_noslack = p.value slacks = [cc.slack_value for cc in p.chance_constraints] self.assertItemsAlmostEqual(slacks, len(p.chance_constraints) * [0]) p.solve(slack=True) self.assertTrue(p.value <= val_noslack) slacks = [cc.slack_value for cc in p.chance_constraints] for slack in slacks: self.assertAlmostGeq(slack, 0) # Conflicting constraints: Prob(x <= 0) >= 0.2 and x >= 1. constr += [self.x >= 1] p = ccprob.Problem(Minimize(obj), constr) with self.assertRaises(SolverError) as cm: p.solve(slack=False) # Solvable with slackened chance constraint. p.solve(slack=True) slacks = [cc.slack_value for cc in p.chance_constraints] for slack in slacks: self.assertAlmostGeq(slack, 0)
def test_solve(self): b = np.abs(np.random.randn(*self.x.shape)) obj = sum_squares(self.x - b) constr = [ChanceConstraint(self.x <= 0, 0.8)] p = ccprob.Problem(Minimize(obj), constr) p.solve() self.assertTrue( np.sum(self.x.value <= self.tolerance) <= 0.8 * self.x.size) b = np.random.randn(self.A.shape[0]) obj = sum_squares(self.A * self.x - b) constr = [ChanceConstraint(self.x >= 0, 0.8)] p = ccprob.Problem(Minimize(obj), constr) p.solve() self.assertTrue( np.sum(self.x.value >= -self.tolerance) <= 0.8 * self.x.size)
def test_2step(self): b = np.abs(np.random.randn(*self.x.shape)) obj = sum_squares(self.x - b) constr = [ChanceConstraint(self.x <= 0, 0.8)] p = ccprob.Problem(Minimize(obj), constr) p.solve(two_step=False) val_1step = p.value p.solve(two_step=True) self.assertTrue(p.value <= val_1step)
def test_probability(self): b = np.random.randn(self.A.shape[0]) obj = sum_squares(self.A * self.x - b) cc = ChanceConstraint([self.x <= 0], 0.8) pc = prob(self.x <= 0) <= 0.8 self.assertEqual(cc.size, pc.size) self.assertEqual(cc.fraction, pc.fraction) self.assertEqual(cc.max_violations, pc.max_violations) self.assertAlmostEqual( ccprob.Problem(Minimize(obj), [cc]).solve(), ccprob.Problem(Minimize(obj), [pc]).solve()) cc = ChanceConstraint([self.x >= 0], 0.8) pc = prob(self.x <= 0) >= 0.2 self.assertEqual(cc.size, pc.size) self.assertEqual(cc.fraction, pc.fraction) self.assertEqual(cc.max_violations, pc.max_violations) self.assertAlmostEqual( ccprob.Problem(Minimize(obj), [cc]).solve(), ccprob.Problem(Minimize(obj), [pc]).solve())
def test_restriction(self): cc = ChanceConstraint([self.x <= 0], 0.8) self.assertEqual(cc.restriction.shape, ()) self.assertEqual(cc.restriction.size, 1) self.assertEqual(cc.restriction.expr.value, None) self.x.value = [-1, 1] cc.slope.value = 0.5 val = np.sum(np.maximum(0.5 - self.x.value, 0)) / 2 - 0.5 * 0.8 self.assertItemsAlmostEqual(cc.restriction.expr.value, val) cc.constraints = [self.x >= 0] val = np.sum(np.maximum(0.5 - self.x.value, 0)) / 2 - 0.5 * 0.8 self.assertItemsAlmostEqual(cc.restriction.expr.value, val) cc.fraction = 0.4 cc.slope.value = 1.5 val = np.sum(np.maximum(1.5 - self.x.value, 0)) / 2 - 1.5 * 0.4 self.assertItemsAlmostEqual(cc.restriction.expr.value, val) b = np.random.randn(self.A.shape[0]) cc = ChanceConstraint([self.A * self.x == b], 0.8) self.x.value = [-1, 1] cc.slope.value = 0.5 expr = np.abs(self.A.dot(self.x.value) - b) val = np.sum(np.maximum(0.5 - expr, 0)) / expr.size - 0.5 * 0.8 self.assertItemsAlmostEqual(cc.restriction.expr.value, val)
def test_properties(self): self.assertEqual(ChanceConstraint([self.x >= 0]).size, 2) self.assertEqual( ChanceConstraint([self.x >= 0, self.y >= 0]).size, 2 + 3) self.assertEqual( ChanceConstraint([self.U >= 0, self.V >= 0]).size, 2 * 2 + 3 * 2) self.assertEqual(ChanceConstraint([self.x >= 0]).max_violations, 2) self.assertEqual( ChanceConstraint([self.x >= 0], 0.8).max_violations, 0.8 * 2) self.assertEqual( ChanceConstraint([self.x >= 0, self.y >= 0], 0.8).max_violations, 0.8 * (2 + 3)) self.assertEqual( ChanceConstraint([self.U >= 0, self.V >= 0], 0.8).max_violations, 0.8 * (2 * 2 + 3 * 2))
def test_margins(self): cc = ChanceConstraint([self.x <= 0]) self.assertItemsAlmostEqual(cc.margins(), [None]) self.x.value = [-1, 1] margins = cc.margins() self.assertEqual(len(margins), 1) self.assertItemsAlmostEqual(margins[0], self.x.value, places=8) cc.constraints = [self.x >= 0] self.assertItemsAlmostEqual(cc.margins()[0], -self.x.value, places=8) cc.constraints = [self.x >= 0, self.y <= 0] margins = cc.margins() self.assertEqual(len(margins), 2) self.assertItemsAlmostEqual(margins[0], -self.x.value, places=8) self.assertEqual(margins[1], None) self.y.value = [-5, 0, 10] self.assertItemsAlmostEqual(cc.margins()[1], self.y.value) b = np.random.randn(self.A.shape[0]) cc = ChanceConstraint([self.A * self.x == b]) self.x.value = [-1, 1] margins = cc.margins() self.assertItemsAlmostEqual(margins[0], np.abs(self.A.dot(self.x.value) - b))
def test_weights(self): cc = ChanceConstraint([self.x >= 0], 0.8) self.assertEqual(len(cc.weights), 1) self.assertItemsAlmostEqual(cc.weights[0], np.array([0.5, 0.5])) cc = ChanceConstraint([self.x >= 0], 0.8, [np.array([0, 1])]) self.assertEqual(len(cc.weights), 1) self.assertItemsAlmostEqual(cc.weights[0], np.array([0, 1])) cc = ChanceConstraint( [self.x >= 0, self.y <= 0], 0.8, [np.array([0, 0.5]), np.array([0.05, 0.1, 0.35])]) self.assertEqual(len(cc.weights), 2) self.assertItemsAlmostEqual(cc.weights[0], np.array([0, 0.5])) self.assertItemsAlmostEqual(cc.weights[1], np.array([0.05, 0.1, 0.35])) cc = ChanceConstraint([self.U >= 0], 0.8) self.assertEqual(len(cc.weights), 1) self.assertItemsAlmostEqual(cc.weights[0], np.full(self.U.shape, 1.0 / self.U.size)) with self.assertRaises(ValueError) as cm: ChanceConstraint( [self.x >= 0], 0.8, [np.array([0, 1]), np.array([1, 0])]) with self.assertRaises(ValueError) as cm: ChanceConstraint([self.x >= 0, self.y <= 0], 0.8, [np.array([0, 1])]) with self.assertRaises(ValueError) as cm: ChanceConstraint([self.x >= 0], 0.8, [np.array([0.1, 0.2, 0.7])]) with self.assertRaises(ValueError) as cm: ChanceConstraint([self.x >= 0], 0.8, [np.array([0.5])]) with self.assertRaises(ValueError) as cm: ChanceConstraint([self.y >= 0], 0.8, [np.array([-0.5, 0.5, 1.0])]) with self.assertRaises(ValueError) as cm: ChanceConstraint([self.y >= 0], 0.8, [np.array([0.25, 0.5, 0.75])]) with self.assertRaises(ValueError) as cm: ChanceConstraint( [self.U >= 0], 0.8, [np.array([[0.125, 0.125], [0.125, 0.125], [0.25, 0.25]])])