예제 #1
0
    def test_cartesian_product(self):

        # simple case
        n = 2
        x_min = -np.ones((n, 1))
        x_max = -x_min
        p1 = Polyhedron.from_bounds(x_min, x_max)
        C = np.ones((1, n))
        d = np.zeros((1, 1))
        p1.add_equality(C, d)
        p2 = p1.cartesian_product(p1)

        # derive the cartesian product
        x_min = -np.ones((2 * n, 1))
        x_max = -x_min
        p3 = Polyhedron.from_bounds(x_min, x_max)
        C = block_diag(*[np.ones((1, n))] * 2)
        d = np.zeros((2, 1))
        p3.add_equality(C, d)

        # compare results
        self.assertTrue(
            same_rows(np.hstack((p2.A, p2.b)), np.hstack((p3.A, p3.b))))
        self.assertTrue(
            same_rows(np.hstack((p2.C, p2.d)), np.hstack((p3.C, p3.d))))
예제 #2
0
    def test_from_convex_hull(self):

        # simple 2d
        points = [
            np.array([0.,0.]),
            np.array([1.,0.]),
            np.array([0.,1.])
        ]
        p = Polyhedron.from_convex_hull(points)
        A = np.array([
            [-1., 0.],
            [0., -1.],
            [1., 1.],
            ])
        b = np.array([0.,0.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))

        # simple 3d
        points = [
            np.array([0.,0.,0.]),
            np.array([1.,0.,0.]),
            np.array([0.,1.,0.]),
            np.array([0.,0.,1.])
        ]
        p = Polyhedron.from_convex_hull(points)
        A = np.array([
            [-1., 0., 0.],
            [0., -1., 0.],
            [0., 0., -1.],
            [1., 1., 1.],
            ])
        b = np.array([0.,0.,0.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))

        # another 2d with internal point
        points = [
            np.array([0.,0.]),
            np.array([1.,0.]),
            np.array([0.,1.]),
            np.array([1.,1.]),
            np.array([.5,.5]),
        ]
        p = Polyhedron.from_convex_hull(points)
        A = np.array([
            [-1., 0.],
            [0., -1.],
            [1., 0.],
            [0., 1.],
            ])
        b = np.array([0.,0.,1.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))
예제 #3
0
    def test_normalize(self):

        # construct polyhedron
        A = np.array([[0.,2.],[0.,-3.]])
        b = np.array([2.,0.])
        C = np.ones((1, 2))
        d = np.ones(1)
        p = Polyhedron(A, b, C, d)

        # normalize
        p.normalize()
        A = np.array([[0., 1.], [0., -1.]])
        b = np.array([1., 0.])
        C = np.ones((1, 2))/np.sqrt(2.)
        d = np.ones(1)/np.sqrt(2.)
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b)),
            normalize=False
            ))
        self.assertTrue(same_rows(
            np.column_stack((C, d)),
            np.column_stack((p.C, p.d)),
            normalize=False
            ))
예제 #4
0
    def test_add_functions(self):

        # add inequalities
        A = np.eye(2)
        b = np.ones(2)
        p = Polyhedron(A, b)
        A = np.ones((1, 2))
        b = np.ones(1)
        p.add_inequality(A, b)
        A = np.ones((1, 1))
        b = 3. * np.ones(1)
        p.add_inequality(A, b, [1])
        A = np.array([[1., 0.], [0., 1.], [1., 1.], [0., 1.]])
        b = np.array([1., 1., 1., 3.])
        self.assertTrue(
            same_rows(np.column_stack((A, b)), np.column_stack((p.A, p.b))))
        c = np.ones(2)
        self.assertRaises(ValueError, p.add_inequality, A, c)

        # add equalities
        A = np.eye(2)
        b = np.ones(2)
        p.add_equality(A, b)
        A = 3. * np.ones((1, 1))
        b = np.ones(1)
        p.add_equality(A, b, [0])
        A = np.array([[1., 0.], [0., 1.], [3., 0.]])
        b = np.array([[1.], [1.], [1.]])
        self.assertTrue(
            same_rows(np.column_stack((A, b)), np.column_stack((p.C, p.d))))
        b = np.ones(2)
        self.assertRaises(ValueError, p.add_equality, A, b)

        # add lower bounds
        A = np.zeros((0, 2))
        b = np.zeros(0)
        p = Polyhedron(A, b)
        p.add_lower_bound(-np.ones(2))
        p.add_upper_bound(2 * np.ones(2))
        p.add_bounds(-3 * np.ones(2), 3 * np.ones(2))
        p.add_lower_bound(-4 * np.ones(1), [0])
        p.add_upper_bound(5 * np.ones(1), [0])
        p.add_bounds(-6 * np.ones(1), 6 * np.ones(1), [1])
        A = np.array([[-1., 0.], [0., -1.], [1., 0.], [0., 1.], [-1., 0.],
                      [0., -1.], [1., 0.], [0., 1.], [-1., 0.], [1., 0.],
                      [0., -1.], [0., 1.]])
        b = np.array([1., 1., 2., 2., 3., 3., 3., 3., 4., 5., 6., 6.])
        self.assertTrue(
            same_rows(np.column_stack((A, b)), np.column_stack((p.A, p.b))))

        # wrong size bounds
        A = np.eye(3)
        b = np.ones(3)
        p = Polyhedron(A, b)
        x = np.zeros(1)
        indices = [0, 1]
        self.assertRaises(ValueError, p.add_lower_bound, x, indices)
        self.assertRaises(ValueError, p.add_upper_bound, x, indices)
        self.assertRaises(ValueError, p.add_bounds, x, x, indices)
예제 #5
0
    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))
예제 #6
0
    def test_orthogonal_projection(self):
        # (more tests on projections are in geometry/test_orthogonal_projection.py)

        # unbounded polyhedron
        x_min = -np.ones((3, 1))
        p = Polyhedron.from_lower_bound(x_min)
        self.assertRaises(ValueError, p.project_to, range(2))

        # simple 3d onto 2d
        p.add_upper_bound(-x_min)
        E = np.vstack((np.eye(2), -np.eye(2)))
        f = np.ones((4, 1))
        vertices = [
            np.array(v).reshape(2, 1) for v in product([1., -1.], repeat=2)
        ]
        proj = p.project_to(range(2))
        proj.remove_redundant_inequalities()
        self.assertTrue(
            same_rows(np.hstack((E, f)), np.hstack((proj.A, proj.b))))
        self.assertTrue(same_vectors(vertices, proj.vertices))

        # lower dimensional
        C = np.array([[1., 1., 0.]])
        d = np.zeros((1, 1))
        p.add_equality(C, d)
        self.assertRaises(ValueError, p.project_to, range(2))

        # lower dimensional
        x_min = -np.ones((3, 1))
        x_max = 2. * x_min
        p = Polyhedron.from_bounds(x_min, x_max)
        self.assertRaises(ValueError, p.project_to, range(2))
예제 #7
0
    def test_intersection(self):

        # first polyhedron
        x1_min = -np.ones((2, 1))
        x1_max = -x1_min
        p1 = Polyhedron.from_bounds(x1_min, x1_max)

        # second polyhedron
        x2_min = np.zeros((2, 1))
        x2_max = 2. * np.ones((2, 1))
        p2 = Polyhedron.from_bounds(x2_min, x2_max)

        # intersection
        p3 = p1.intersection(p2)
        p3.remove_redundant_inequalities()
        p4 = Polyhedron.from_bounds(x2_min, x1_max)
        self.assertTrue(
            same_rows(np.hstack((p3.A, p3.b)), np.hstack((p4.A, p4.b))))

        # add equalities
        C1 = np.array([[1., 0.]])
        d1 = np.array([-.5])
        p1.add_equality(C1, d1)
        p3 = p1.intersection(p2)
        self.assertTrue(p3.empty)
예제 #8
0
    def test_same_rows(self):
        np.random.seed(1)

        # test dimensions
        n = 10
        m = 5
        for i in range(10):

            # check with scaling factors
            A = np.random.rand(n, m)
            scaling = np.random.rand(n)
            B = np.multiply(A.T, scaling).T
            self.assertTrue(same_rows(A, B))

            # check without scaling factors
            B_order = list(range(n))
            shuffle(B_order)
            B = A[B_order, :]
            self.assertTrue(same_rows(A, B, normalize=False))

            # wrong check (same columns)
            scaling = np.random.rand(m)
            B = np.multiply(A, scaling)
            self.assertFalse(same_rows(A, B))
    def test_solve(self):

        # 1-dimensional mpqp
        H = dict()
        H['uu'] = np.array([[1.]])
        H['xx'] = np.zeros((1, 1))
        H['ux'] = np.zeros((1, 1))
        f = dict()
        f['u'] = np.zeros((1, 1))
        f['x'] = np.zeros((1, 1))
        g = np.zeros((1, 1))
        A = dict()
        A['u'] = np.array([[1.], [-1.], [0.], [0.]])
        A['x'] = np.array([[-1.], [1.], [1.], [-1.]])
        b = np.array([[1.], [1.], [2.], [2.]])
        mpqp = MultiParametricQuadraticProgram(H, f, g, A, b)

        # explicit solve given active set
        cr = mpqp.explicit_solve_given_active_set([])
        self.assertAlmostEqual(cr._V['xx'], 0.)
        self.assertAlmostEqual(cr._V['x'], 0.)
        self.assertAlmostEqual(cr._V['0'], 0.)
        self.assertAlmostEqual(cr._u['x'], 0.)
        self.assertAlmostEqual(cr._u['0'], 0.)
        cr = mpqp.explicit_solve_given_active_set([0])
        self.assertAlmostEqual(cr._V['xx'], 1.)
        self.assertAlmostEqual(cr._V['x'], 1.)
        self.assertAlmostEqual(cr._V['0'], .5)
        self.assertAlmostEqual(cr._u['x'], 1.)
        self.assertAlmostEqual(cr._u['0'], 1.)

        # explicit solve given point
        cr = mpqp.explicit_solve_given_point(np.array([[1.5]]))
        self.assertAlmostEqual(cr._V['xx'], 1.)
        self.assertAlmostEqual(cr._V['x'], -1.)
        self.assertAlmostEqual(cr._V['0'], .5)
        self.assertAlmostEqual(cr._u['x'], 1.)
        self.assertAlmostEqual(cr._u['0'], -1.)

        # implicit solve given point
        sol = mpqp.solve(np.array([[1.5]]))
        self.assertAlmostEqual(sol['min'], .125)
        self.assertTrue(np.allclose(sol['argmin'], 0.5))
        self.assertEqual(sol['active_set'], [1])

        # solve
        exp_sol = mpqp.explicit_solve()
        for x in [
                np.array([[.5]]),
                np.array([[1.5]]),
                np.array([[-1.5]]),
                np.array([[2.5]]),
                np.array([[-2.5]])
        ]:
            sol = mpqp.solve(x)
            if sol['min'] is not None:
                self.assertAlmostEqual(sol['min'], exp_sol.V(x))
                np.testing.assert_array_almost_equal(sol['argmin'],
                                                     exp_sol.u(x))
                np.testing.assert_array_almost_equal(
                    sol['multiplier_inequality'], exp_sol.p(x))
            else:
                self.assertTrue(exp_sol.V(x) is None)
                self.assertTrue(exp_sol.u(x) is None)
                self.assertTrue(exp_sol.p(x) is None)

        # feasible set
        fs = mpqp.get_feasible_set()
        A = np.array([[1.], [-1.]])
        b = np.array([[2.], [2.]])
        self.assertTrue(same_rows(np.hstack((A, b)), np.hstack((fs.A, fs.b))))
예제 #10
0
    def test_from_functions(self):

        # row vector input
        x = np.ones((1, 5))
        self.assertRaises(ValueError, Polyhedron.from_lower_bound, x)

        # from lower bound
        x = np.ones((2, 1))
        p = Polyhedron.from_lower_bound(x)
        A_lb = np.array([[-1., 0.], [0., -1.]])
        b_lb = np.array([[-1.], [-1.]])
        self.assertTrue(
            same_rows(np.hstack((A_lb, b_lb)), np.hstack((p.A, p.b))))

        # from upper bound
        p = Polyhedron.from_upper_bound(x)
        A_ub = np.array([[1., 0.], [0., 1.]])
        b_ub = np.array([[1.], [1.]])
        self.assertTrue(
            same_rows(np.hstack((A_ub, b_ub)), np.hstack((p.A, p.b))))

        # from upper and lower bounds
        p = Polyhedron.from_bounds(x, x)
        A = np.vstack((A_lb, A_ub))
        b = np.vstack((b_lb, b_ub))
        self.assertTrue(same_rows(np.hstack((A, b)), np.hstack((p.A, p.b))))

        # different size lower and upper bound
        y = np.ones((3, 1))
        self.assertRaises(ValueError, Polyhedron.from_bounds, x, y)

        # from lower bound of not all the variables
        indices = [1, 2]
        n = 3
        p = Polyhedron.from_lower_bound(x, indices, n)
        A_lb = np.array([[0., -1., 0.], [0., 0., -1.]])
        b_lb = np.array([[-1.], [-1.]])
        self.assertTrue(
            same_rows(np.hstack((A_lb, b_lb)), np.hstack((p.A, p.b))))

        # from lower bound of not all the variables
        indices = [0, 2]
        n = 3
        p = Polyhedron.from_upper_bound(x, indices, n)
        A_ub = np.array([[1., 0., 0.], [0., 0., 1.]])
        b_ub = np.array([[1.], [1.]])
        self.assertTrue(
            same_rows(np.hstack((A_ub, b_ub)), np.hstack((p.A, p.b))))

        # from upper and lower bounds of not all the variables
        indices = [0, 1]
        n = 3
        p = Polyhedron.from_bounds(x, x, indices, n)
        A = np.array([[-1., 0., 0.], [0., -1., 0.], [1., 0., 0.], [0., 1.,
                                                                   0.]])
        b = np.array([[-1.], [-1.], [1.], [1.]])
        self.assertTrue(same_rows(np.hstack((A, b)), np.hstack((p.A, p.b))))

        # too many indices
        indices = [1, 2, 3]
        n = 5
        self.assertRaises(ValueError, Polyhedron.from_lower_bound, x, indices,
                          n)
        self.assertRaises(ValueError, Polyhedron.from_upper_bound, x, indices,
                          n)
        self.assertRaises(ValueError, Polyhedron.from_bounds, x, x, indices, n)
예제 #11
0
    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)
예제 #12
0
    def test_add_functions(self):

        # add inequalities
        A = np.eye(2)
        b = np.ones(2)
        p = Polyhedron(A, b)
        A = np.ones((1, 2))
        b = np.ones(1)
        p.add_inequality(A, b)
        A = np.ones((1, 1))
        b = 3.*np.ones(1)
        p.add_inequality(A, b, [1])
        A = np.array([[1., 0.], [0., 1.], [1., 1.], [0., 1.]])
        b = np.array([1.,1.,1.,3.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))
        c = np.ones(2)
        self.assertRaises(ValueError, p.add_inequality, A, c)

        # add equalities
        A = np.eye(2)
        b = np.ones(2)
        p.add_equality(A, b)
        A = 3.*np.ones((1, 1))
        b = np.ones(1)
        p.add_equality(A, b, [0])
        A = np.array([[1., 0.], [0., 1.], [3., 0.]])
        b = np.array([[1.], [1.], [1.]])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.C, p.d))
            ))
        b = np.ones(2)
        self.assertRaises(ValueError, p.add_equality, A, b)

        # add lower bounds
        A = np.zeros((0, 2))
        b = np.zeros(0)
        p = Polyhedron(A, b)
        p.add_lower_bound(-np.ones(2))
        p.add_upper_bound(2*np.ones(2))
        p.add_bounds(-3*np.ones(2), 3*np.ones(2))
        p.add_lower_bound(-4*np.ones(1), [0])
        p.add_upper_bound(5*np.ones(1), [0])
        p.add_bounds(-6*np.ones(1), 6*np.ones(1), [1])
        A =np.array([[-1., 0.], [0., -1.], [1., 0.], [0., 1.], [-1., 0.], [0., -1.], [1., 0.], [0., 1.], [-1., 0.], [1., 0.], [0., -1.], [0., 1.] ])
        b = np.array([1.,1.,2.,2.,3.,3.,3.,3.,4.,5.,6.,6.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))

        # wrong size bounds
        A = np.eye(3)
        b = np.ones(3)
        p = Polyhedron(A, b)
        x = np.zeros(1)
        indices = [0, 1]
        self.assertRaises(ValueError, p.add_lower_bound, x, indices)
        self.assertRaises(ValueError, p.add_upper_bound, x, indices)
        self.assertRaises(ValueError, p.add_bounds, x, x, indices)

        # add symbolic
        n = 5
        m = 3
        A = np.random.rand(m, n)
        b = np.random.rand(m)
        C = np.random.rand(m, n)
        d = np.random.rand(m)
        P = Polyhedron(A, b)
        x = sp.Matrix([sp.Symbol('x'+str(i), real=True) for i in range(n)])
        ineq = sp.Matrix(A)*x - sp.Matrix(b)
        P.add_symbolic_inequality(x, ineq)
        np.testing.assert_array_almost_equal(P.A, np.vstack((A, A)))
        np.testing.assert_array_almost_equal(P.b, np.concatenate((b, b)))
        eq = sp.Matrix(C)*x - sp.Matrix(d)
        P.add_symbolic_equality(x, eq)
        np.testing.assert_array_almost_equal(P.C, C)
        np.testing.assert_array_almost_equal(P.d, d)

        # throw some errors here
        P = Polyhedron(A, b)
        x = sp.Matrix([sp.Symbol('x'+str(i), real=True) for i in range(n+1)])
        A1 = np.random.rand(m, n+1)
        ineq = sp.Matrix(A1)*x - sp.Matrix(b)
        self.assertRaises(ValueError, P.add_symbolic_inequality, x, ineq)
        P = Polyhedron(A, b, C, d)
        C1 = np.random.rand(m, n+1)
        eq = sp.Matrix(C1)*x - sp.Matrix(b)
        self.assertRaises(ValueError, P.add_symbolic_equality, x, eq)
예제 #13
0
    def test_from_functions(self):

        # row vector input
        x = np.ones((1,5))
        self.assertRaises(ValueError, Polyhedron.from_lower_bound, x)

        # from lower bound
        x = np.ones(2)
        p = Polyhedron.from_lower_bound(x)
        A_lb = np.array([[-1., 0.], [0., -1.]])
        b_lb = np.array([-1.,-1.])
        self.assertTrue(same_rows(
            np.column_stack((A_lb, b_lb)),
            np.column_stack((p.A, p.b))
            ))

        # from upper bound
        p = Polyhedron.from_upper_bound(x)
        A_ub = np.array([[1., 0.], [0., 1.]])
        b_ub = np.array([1.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A_ub, b_ub)),
            np.column_stack((p.A, p.b))
            ))

        # from upper and lower bounds
        p = Polyhedron.from_bounds(x, x)
        A = np.vstack((A_lb, A_ub))
        b = np.concatenate((b_lb, b_ub))
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))

        # different size lower and upper bound
        y = np.ones((3,1))
        self.assertRaises(ValueError, Polyhedron.from_bounds, x, y)

        # from lower bound of not all the variables
        indices = [1, 2]
        n = 3
        p = Polyhedron.from_lower_bound(x, indices, n)
        A_lb = np.array([[0., -1., 0.], [0., 0., -1.]])
        b_lb = np.array([-1.,-1.])
        self.assertTrue(same_rows(
            np.column_stack((A_lb, b_lb)),
            np.column_stack((p.A, p.b))
            ))

        # from lower bound of not all the variables
        indices = [0, 2]
        n = 3
        p = Polyhedron.from_upper_bound(x, indices, n)
        A_ub = np.array([[1., 0., 0.], [0., 0., 1.]])
        b_ub = np.array([1.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A_ub, b_ub)),
            np.column_stack((p.A, p.b))
            ))

        # from upper and lower bounds of not all the variables
        indices = [0, 1]
        n = 3
        p = Polyhedron.from_bounds(x, x, indices, n)
        A = np.array([[-1., 0., 0.], [0., -1., 0.], [1., 0., 0.], [0., 1., 0.]])
        b = np.array([-1.,-1.,1.,1.])
        self.assertTrue(same_rows(
            np.column_stack((A, b)),
            np.column_stack((p.A, p.b))
            ))

        # too many indices
        indices = [1, 2, 3]
        n = 5
        self.assertRaises(ValueError, Polyhedron.from_lower_bound, x, indices, n)
        self.assertRaises(ValueError, Polyhedron.from_upper_bound, x, indices, n)
        self.assertRaises(ValueError, Polyhedron.from_bounds, x, x, indices, n)

        # from symbolic
        n = 5
        m = 3
        x = sp.Matrix([sp.Symbol('x'+str(i), real=True) for i in range(n)])
        A = np.random.rand(m, n)
        b = np.random.rand(m)
        ineq = sp.Matrix(A)*x - sp.Matrix(b)
        P = Polyhedron.from_symbolic(x, ineq)
        np.testing.assert_array_almost_equal(P.A, A)
        np.testing.assert_array_almost_equal(P.b, b)
        C = np.random.rand(m, n)
        d = np.random.rand(m)
        eq = sp.Matrix(C)*x - sp.Matrix(d)
        P = Polyhedron.from_symbolic(x, ineq, eq)
        np.testing.assert_array_almost_equal(P.A, A)
        np.testing.assert_array_almost_equal(P.b, b)
        np.testing.assert_array_almost_equal(P.C, C)
        np.testing.assert_array_almost_equal(P.d, d)