]> gitweb.michael.orlitzky.com - dunshire.git/commitdiff
Add a test for Lyapunov games over the orthant.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 13 Oct 2016 12:44:03 +0000 (08:44 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 13 Oct 2016 12:44:03 +0000 (08:44 -0400)
src/dunshire/games.py

index 65fc791b20bd0624ee714a724581eb1537fa2edf..279afdb16036fa7c36a072ab4564f075002a0721 100644 (file)
@@ -14,7 +14,8 @@ from unittest import TestCase
 from cvxopt import matrix, printing, solvers
 from cones import CartesianProduct, IceCream, NonnegativeOrthant
 from errors import GameUnsolvableException
 from cvxopt import matrix, printing, solvers
 from cones import CartesianProduct, IceCream, NonnegativeOrthant
 from errors import GameUnsolvableException
-from matrices import append_col, append_row, identity, inner_product, norm
+from matrices import (append_col, append_row, eigenvalues_re, identity,
+                      inner_product, norm)
 import options
 
 printing.options['dformat'] = options.FLOAT_FORMAT
 import options
 
 printing.options['dformat'] = options.FLOAT_FORMAT
@@ -838,3 +839,27 @@ class SymmetricLinearGameTest(TestCase):
 
         game = SymmetricLinearGame(L, K, e1, e2)
         self.assertTrue(game.solution().game_value() >= -options.ABS_TOL)
 
         game = SymmetricLinearGame(L, K, e1, e2)
         self.assertTrue(game.solution().game_value() >= -options.ABS_TOL)
+
+    def test_lyapunov_orthant(self):
+        """
+        Test that a Lyapunov game on the nonnegative orthant works.
+        """
+        (_, K, e1, e2) = _random_orthant_params()
+
+        # Ignore that L, we need a diagonal (Lyapunov-like) one.
+        L = _random_diagonal_matrix(K.dimension())
+        game = SymmetricLinearGame(L, K, e1, e2)
+        soln = game.solution()
+
+        # We only check for positive/negative stability if the game
+        # value is not basically zero. If the value is that close to
+        # zero, we just won't check any assertions.
+        L = matrix(L).trans()
+        if soln.game_value() > options.ABS_TOL:
+            # L should be positive stable
+            ps = all([eig > -options.ABS_TOL for eig in  eigenvalues_re(L)])
+            self.assertTrue(ps)
+        elif soln.game_value() < -options.ABS_TOL:
+            # L should be negative stable
+            ns = all([eig < options.ABS_TOL for eig in  eigenvalues_re(L)])
+            self.assertTrue(ns)