def test_convex_hull_method(self): np.random.seed(3) # cube from n-dimensions to n-1-dimensions for n in range(2, 6): x_min = - np.ones(n) x_max = - x_min p = Polyhedron.from_bounds(x_min, x_max) E = np.vstack(( np.eye(n-1), - np.eye(n-1) )) f = np.ones(2*(n-1)) vertices = [np.array(v) for v in product([1., -1.], repeat=n-1)] E_chm, f_chm, vertices_chm = convex_hull_method(p.A, p.b, range(n-1)) p_chm = Polyhedron(E_chm, f_chm) p_chm.remove_redundant_inequalities() self.assertTrue(same_rows( np.column_stack((E, f)), np.column_stack((p_chm.A, p_chm.b)) )) self.assertTrue(same_vectors(vertices, vertices_chm)) # test with random polytopes wiith m facets m = 10 # dimension of the higher dimensional polytope for n in range(3, 6): # dimension of the lower dimensional polytope for n_proj in range(2, n): # higher dimensional polytope A = np.random.randn(m, n) b = np.random.rand(m) p = Polyhedron(A, b) # if not empty or unbounded if p.vertices is not None: points = [v[:n_proj] for v in p.vertices] p = Polyhedron.from_convex_hull(points) # check half spaces p.remove_redundant_inequalities() E_chm, f_chm, vertices_chm = convex_hull_method(A, b, range(n_proj)) p_chm = Polyhedron(E_chm, f_chm) p_chm.remove_redundant_inequalities() self.assertTrue(same_rows( np.column_stack((p.A, p.b)), np.column_stack((p_chm.A, p_chm.b)) )) # check vertices self.assertTrue(same_vectors(p.vertices, vertices_chm))
def test_remove_redundant_inequalities(self): # minimal facets only inequalities A = np.array([[1., 1.], [-1., 1.], [0., -1.], [0., 1.], [0., 1.], [2., 2.]]) b = np.array([[1.], [1.], [1.], [1.], [2.], [2.]]) p = Polyhedron(A, b) mf = set(p.minimal_facets()) self.assertTrue(mf == set([1, 2, 0]) or mf == set([1, 2, 5])) # add nasty redundant inequality A = np.zeros((1, 2)) b = np.ones((1, 1)) p.add_inequality(A, b) mf = set(p.minimal_facets()) self.assertTrue(mf == set([1, 2, 0]) or mf == set([1, 2, 5])) # remove redundant facets p.remove_redundant_inequalities() A_min = np.array([[-1., 1.], [0., -1.], [1., 1.]]) b_min = np.array([[1.], [1.], [1.]]) self.assertTrue( same_rows(np.hstack((A_min, b_min)), np.hstack((p.A, p.b)))) # both inequalities and equalities x_min = -np.ones((2, 1)) x_max = -x_min p = Polyhedron.from_bounds(x_min, x_max) C = np.ones((1, 2)) d = np.ones((1, 1)) p.add_equality(C, d) self.assertEqual([2, 3], sorted(p.minimal_facets())) p.remove_redundant_inequalities() A_min = np.array([[1., 0.], [0., 1.]]) b_min = np.array([[1.], [1.]]) self.assertTrue( same_rows(np.hstack((A_min, b_min)), np.hstack((p.A, p.b)))) # add (redundant) inequality coincident with the equality p.add_inequality(C, d) p.remove_redundant_inequalities() self.assertTrue( same_rows(np.hstack((A_min, b_min)), np.hstack((p.A, p.b)))) # add (redundant) inequality p.add_inequality(np.array([[-1., 1.]]), np.array([[1.1]])) p.remove_redundant_inequalities() self.assertTrue( same_rows(np.hstack((A_min, b_min)), np.hstack((p.A, p.b)))) # add unfeasible equality (raises: 'empty polyhedron, cannot remove redundant inequalities.') C = np.ones((1, 2)) d = -np.ones((1, 1)) p.add_equality(C, d) self.assertRaises(ValueError, p.remove_redundant_inequalities) # empty polyhderon (raises: 'empty polyhedron, cannot remove redundant inequalities.') x_min = np.ones((2, 1)) x_max = np.zeros((2, 1)) p = Polyhedron.from_bounds(x_min, x_max) self.assertRaises(ValueError, p.remove_redundant_inequalities)