blob: f5e478311efb07fc1a9361280ce1aa4cb10577ff [file] [log] [blame]
#!/usr/bin/python
import numpy
from numpy.testing import *
import unittest
import frc971.control_loops.python.polytope as polytope
__author__ = 'Austin Schuh (austin.linux@gmail.com)'
def MakePoint(*args):
"""Makes a point from a set of arguments."""
return numpy.matrix([[arg] for arg in args])
class TestHPolytope(unittest.TestCase):
def setUp(self):
"""Builds a simple box polytope."""
self.H = numpy.matrix([[1, 0],
[-1, 0],
[0, 1],
[0, -1]])
self.k = numpy.matrix([[12],
[12],
[12],
[12]])
self.p = polytope.HPolytope(self.H, self.k)
def test_Hk(self):
"""Tests that H and k are saved correctly."""
assert_array_equal(self.p.H, self.H)
assert_array_equal(self.p.k, self.k)
def test_IsInside(self):
"""Tests IsInside for various points."""
inside_points = [
MakePoint(0, 0),
MakePoint(6, 6),
MakePoint(12, 6),
MakePoint(-6, 10)]
outside_points = [
MakePoint(14, 0),
MakePoint(-14, 0),
MakePoint(0, 14),
MakePoint(0, -14),
MakePoint(14, -14)]
for inside_point in inside_points:
self.assertTrue(self.p.IsInside(inside_point),
msg='Point is' + str(inside_point))
for outside_point in outside_points:
self.assertFalse(self.p.IsInside(outside_point),
msg='Point is' + str(outside_point))
def AreVertices(self, p, vertices):
"""Checks that all the vertices are on corners of the set."""
for i in range(vertices.shape[0]):
# Check that all the vertices have the correct number of active
# constraints.
lmda = p.H * vertices[i,:].T - p.k
num_active_constraints = 0
for j in range(lmda.shape[0]):
# Verify that the constraints are either active, or not violated.
if numpy.abs(lmda[j, 0]) <= 1e-9:
num_active_constraints += 1
else:
self.assertLessEqual(lmda[j, 0], 0.0)
self.assertEqual(p.ndim, num_active_constraints)
def HasSamePoints(self, expected, actual):
"""Verifies that the points in expected are in actual."""
found_points = set()
self.assertEqual(expected.shape, actual.shape)
for index in range(expected.shape[0]):
expected_point = expected[index, :]
for actual_index in range(actual.shape[0]):
actual_point = actual[actual_index, :]
if numpy.abs(expected_point - actual_point).max() <= 1e-4:
found_points.add(actual_index)
break
self.assertEqual(len(found_points), actual.shape[0],
msg="Expected:\n" + str(expected) + "\nActual:\n" + str(actual))
def test_Skewed_Nonsym_Vertices(self):
"""Tests the vertices of a severely skewed space."""
self.H = numpy.matrix([[10, -1],
[-1, -1],
[-1, 10],
[10, 10]])
self.k = numpy.matrix([[2],
[2],
[2],
[2]])
self.p = polytope.HPolytope(self.H, self.k)
vertices = self.p.Vertices()
self.AreVertices(self.p, vertices)
self.HasSamePoints(
numpy.matrix([[0., 0.2],
[0.2, 0.],
[-2., 0.],
[0., -2.]]),
vertices)
def test_Vertices_Nonsym(self):
"""Tests the vertices of a nonsymetric space."""
self.k = numpy.matrix([[6],
[12],
[2],
[10]])
self.p = polytope.HPolytope(self.H, self.k)
vertices = self.p.Vertices()
self.AreVertices(self.p, vertices)
self.HasSamePoints(
numpy.matrix([[6., 2.],
[6., -10.],
[-12., -10.],
[-12., 2.]]),
vertices)
def test_Vertices(self):
"""Tests the vertices of a nonsymetric space."""
self.HasSamePoints(self.p.Vertices(),
numpy.matrix([[12., 12.],
[12., -12.],
[-12., -12.],
[-12., 12.]]))
def test_concat(self):
"""Tests that the concat function works for simple inputs."""
self.assertEqual(["asd", "qwe"],
list(
polytope._PiecewiseConcat(["a", "q"], ["s", "w"],
["d", "e"])))
def test_str(self):
"""Verifies that the str method works for the provided p."""
self.assertEqual('[[ 1 0] [[12] \n'
' [-1 0] [[x0] <= [12] \n'
' [ 0 1] [x1]] [12] \n'
' [ 0 -1]] [12]] ',
str(self.p))
def MakePWithDims(self, num_constraints, num_dims):
"""Makes a zeroed out polytope with the correct size."""
self.p = polytope.HPolytope(
numpy.matrix(numpy.zeros((num_constraints, num_dims))),
numpy.matrix(numpy.zeros((num_constraints, 1))))
def test_few_constraints_odd_constraint_even_dims_str(self):
"""Tests printing out the set with odd constraints and even dimensions."""
self.MakePWithDims(num_constraints=5, num_dims=2)
self.assertEqual('[[ 0. 0.] [[ 0.] \n'
' [ 0. 0.] [[x0] [ 0.] \n'
' [ 0. 0.] [x1]] <= [ 0.] \n'
' [ 0. 0.] [ 0.] \n'
' [ 0. 0.]] [ 0.]] ',
str(self.p))
def test_few_constraints_odd_constraint_small_dims_str(self):
"""Tests printing out the set with odd constraints and odd dimensions."""
self.MakePWithDims(num_constraints=5, num_dims=1)
self.assertEqual('[[ 0.] [[ 0.] \n'
' [ 0.] [ 0.] \n'
' [ 0.] [[x0]] <= [ 0.] \n'
' [ 0.] [ 0.] \n'
' [ 0.]] [ 0.]] ',
str(self.p))
def test_few_constraints_odd_constraint_odd_dims_str(self):
"""Tests printing out the set with odd constraints and odd dimensions."""
self.MakePWithDims(num_constraints=5, num_dims=3)
self.assertEqual('[[ 0. 0. 0.] [[ 0.] \n'
' [ 0. 0. 0.] [[x0] [ 0.] \n'
' [ 0. 0. 0.] [x1] <= [ 0.] \n'
' [ 0. 0. 0.] [x2]] [ 0.] \n'
' [ 0. 0. 0.]] [ 0.]] ',
str(self.p))
def test_many_constraints_even_constraint_odd_dims_str(self):
"""Tests printing out the set with even constraints and odd dimensions."""
self.MakePWithDims(num_constraints=2, num_dims=3)
self.assertEqual('[[ 0. 0. 0.] [[x0] [[ 0.] \n'
' [ 0. 0. 0.]] [x1] <= [ 0.]] \n'
' [x2]] ',
str(self.p))
if __name__ == '__main__':
unittest.main()