X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fdunshire%2Fgames.py;h=65fc791b20bd0624ee714a724581eb1537fa2edf;hb=d1638062ec3a28dc64b91f308858211db243db7b;hp=76fbf7deedfec733bf4213bec000bdf449087e75;hpb=9da611019b85e58ecab8450f9a9043c6f4a184d1;p=dunshire.git diff --git a/src/dunshire/games.py b/src/dunshire/games.py index 76fbf7d..65fc791 100644 --- a/src/dunshire/games.py +++ b/src/dunshire/games.py @@ -504,7 +504,7 @@ class SymmetricLinearGame: -def _random_square_matrix(dims): +def _random_matrix(dims): """ Generate a random square (``dims``-by-``dims``) matrix, represented as a list of rows. This is used only by the @@ -512,6 +512,23 @@ def _random_square_matrix(dims): """ return [[uniform(-10, 10) for i in range(dims)] for j in range(dims)] +def _random_nonnegative_matrix(dims): + """ + Generate a random square (``dims``-by-``dims``) matrix with + nonnegative entries, represented as a list of rows. This is used + only by the :class:`SymmetricLinearGameTest` class. + """ + L = _random_matrix(dims) + return [[abs(entry) for entry in row] for row in L] + +def _random_diagonal_matrix(dims): + """ + Generate a random square (``dims``-by-``dims``) matrix with nonzero + entries only on the diagonal, represented as a list of rows. This is + used only by the :class:`SymmetricLinearGameTest` class. + """ + return [[uniform(-10, 10)*int(i == j) for i in range(dims)] + for j in range(dims)] def _random_orthant_params(): """ @@ -523,7 +540,7 @@ def _random_orthant_params(): K = NonnegativeOrthant(ambient_dim) e1 = [uniform(0.5, 10) for idx in range(K.dimension())] e2 = [uniform(0.5, 10) for idx in range(K.dimension())] - L = _random_square_matrix(K.dimension()) + L = _random_matrix(K.dimension()) return (L, K, e1, e2) @@ -550,7 +567,7 @@ def _random_icecream_params(): fudge_factor = 1.0 / (2.0*sqrt(K.dimension() - 1.0)) e1 += [fudge_factor*uniform(0, 1) for idx in range(K.dimension() - 1)] e2 += [fudge_factor*uniform(0, 1) for idx in range(K.dimension() - 1)] - L = _random_square_matrix(K.dimension()) + L = _random_matrix(K.dimension()) return (L, K, e1, e2) @@ -804,3 +821,20 @@ class SymmetricLinearGameTest(TestCase): """ (L, K, e1, e2) = _random_icecream_params() self.assert_orthogonality(L, K, e1, e2) + + + def test_positive_operator_value(self): + """ + Test that a positive operator on the nonnegative orthant gives + rise to a a game with a nonnegative value. + + This test theoretically applies to the ice-cream cone as well, + but we don't know how to make positive operators on that cone. + """ + (_, K, e1, e2) = _random_orthant_params() + + # Ignore that L, we need a nonnegative one. + L = _random_nonnegative_matrix(K.dimension()) + + game = SymmetricLinearGame(L, K, e1, e2) + self.assertTrue(game.solution().game_value() >= -options.ABS_TOL)