]> gitweb.michael.orlitzky.com - dunshire.git/commitdiff
Take the condition number into account when evaluating test results.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 3 Nov 2016 18:29:21 +0000 (14:29 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 3 Nov 2016 18:29:21 +0000 (14:29 -0400)
This adds a ``modifier`` parameter to the assert_within_tol() method
used in the SymmetricLinearGame unit tests. The condition number of
the game is always passed in as the modifier, and that lets us allow a
larger tolerance for nasty matrices.

test/symmetric_linear_game_test.py

index da72fd03cca7215602ff81174a906795ffc189a9..936a7e869283b4fd9ee2e82ddccefa5ef7253658 100644 (file)
@@ -36,12 +36,28 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
     """
     Tests for the SymmetricLinearGame and Solution classes.
     """
-    def assert_within_tol(self, first, second):
+    def assert_within_tol(self, first, second, modifier=1):
         """
         Test that ``first`` and ``second`` are equal within a multiple of
         our default tolerances.
+
+        Parameters
+        ----------
+
+        first : float
+            The first number to compare.
+
+        second : float
+            The second number to compare.
+
+        modifier : float
+            A scaling factor (default: 1) applied to the default
+            ``EPSILON`` for this comparison. If you have a poorly-
+            conditioned matrix, for example, you may want to set this
+            greater than one.
+
         """
-        self.assertTrue(abs(first - second) < EPSILON)
+        self.assertTrue(abs(first - second) < EPSILON*modifier)
 
 
     def assert_solution_exists(self, G):
@@ -52,7 +68,7 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
 
         expected = inner_product(G._L*soln.player1_optimal(),
                                  soln.player2_optimal())
-        self.assert_within_tol(soln.game_value(), expected)
+        self.assert_within_tol(soln.game_value(), expected, G.condition())
 
 
 
@@ -113,7 +129,7 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
         (alpha, H) = random_nn_scaling(G)
         value1 = G.solution().game_value()
         value2 = H.solution().game_value()
-        self.assert_within_tol(alpha*value1, value2)
+        self.assert_within_tol(alpha*value1, value2, H.condition())
 
 
     def test_scaling_orthant(self):
@@ -151,10 +167,12 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
         (alpha, H) = random_translation(G)
         value2 = H.solution().game_value()
 
-        self.assert_within_tol(value1 + alpha, value2)
+        self.assert_within_tol(value1 + alpha, value2, H.condition())
 
         # Make sure the same optimal pair works.
-        self.assert_within_tol(value2, inner_product(H._L*x_bar, y_bar))
+        self.assert_within_tol(value2,
+                               inner_product(H._L*x_bar, y_bar),
+                               H.condition())
 
 
     def test_translation_orthant(self):
@@ -193,11 +211,14 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
         y_bar = soln1.player2_optimal()
         soln2 = H.solution()
 
-        self.assert_within_tol(-soln1.game_value(), soln2.game_value())
+        self.assert_within_tol(-soln1.game_value(),
+                               soln2.game_value(),
+                               H.condition())
 
         # Make sure the switched optimal pair works.
         self.assert_within_tol(soln2.game_value(),
-                               inner_product(M*y_bar, x_bar))
+                               inner_product(M*y_bar, x_bar),
+                               H.condition())
 
 
     def test_opposite_game_orthant(self):
@@ -229,10 +250,10 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
         value = soln.game_value()
 
         ip1 = inner_product(y_bar, G._L*x_bar - value*G._e1)
-        self.assert_within_tol(ip1, 0)
+        self.assert_within_tol(ip1, 0, G.condition())
 
         ip2 = inner_product(value*G._e2 - G._L.trans()*y_bar, x_bar)
-        self.assert_within_tol(ip2, 0)
+        self.assert_within_tol(ip2, 0, G.condition())
 
 
     def test_orthogonality_orthant(self):
@@ -290,7 +311,9 @@ class SymmetricLinearGameTest(TestCase): # pylint: disable=R0904
 
         # The dual game's value should always equal the primal's.
         dualsoln = G.dual().solution()
-        self.assert_within_tol(dualsoln.game_value(), soln.game_value())
+        self.assert_within_tol(dualsoln.game_value(),
+                               soln.game_value(),
+                               G.condition())
 
 
     def test_lyapunov_orthant(self):