X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fdunshire%2Fgames.py;fp=src%2Fdunshire%2Fgames.py;h=279afdb16036fa7c36a072ab4564f075002a0721;hb=d41f3e8b808185ef3a3e71ee64c1cd72112f4eb3;hp=65fc791b20bd0624ee714a724581eb1537fa2edf;hpb=d1638062ec3a28dc64b91f308858211db243db7b;p=dunshire.git diff --git a/src/dunshire/games.py b/src/dunshire/games.py index 65fc791..279afdb 100644 --- a/src/dunshire/games.py +++ b/src/dunshire/games.py @@ -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 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 @@ -838,3 +839,27 @@ class SymmetricLinearGameTest(TestCase): 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)