]> gitweb.michael.orlitzky.com - dunshire.git/commitdiff
Add doctests for the solution of some easy games.
authorMichael Orlitzky <michael@orlitzky.com>
Thu, 6 Oct 2016 21:10:40 +0000 (17:10 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Thu, 6 Oct 2016 21:10:40 +0000 (17:10 -0400)
TODO
src/dunshire/symmetric_linear_game.py

diff --git a/TODO b/TODO
index aaf796ff3b89f3546110c7604ee14142f2819c16..b38d65aaf32f7f348767808f0df7ea9588810446 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,3 @@
-1. Add doctests for simple examples like the ones in Dr. Gowda's paper
-   and the identity operator.
-
 2. Add unit testing for crazier things like random invertible matrices.
 
 6. Add real docstrings everywhere.
 2. Add unit testing for crazier things like random invertible matrices.
 
 6. Add real docstrings everywhere.
index 07385d7c3fd25c847a25bc7bee8f38b2b1341263..968d9ca630c0af2fa15e780747785e9705f82ddc 100644 (file)
@@ -39,11 +39,21 @@ class Solution:
           * The optimal strategy of player one.
           * The optimal strategy of player two.
 
           * The optimal strategy of player one.
           * The optimal strategy of player two.
 
-        """
+        EXAMPLES:
+
+           >>> print(Solution(10, matrix([1,2]), matrix([3,4])))
+           Game value: 10.0000000
+           Player 1 optimal:
+             [ 1]
+             [ 2]
+           Player 2 optimal:
+             [ 3]
+             [ 4]
 
 
+        """
         tpl = 'Game value: {:.7f}\n' \
               'Player 1 optimal:{:s}\n' \
         tpl = 'Game value: {:.7f}\n' \
               'Player 1 optimal:{:s}\n' \
-              'Player 2 optimal:{:s}\n'
+              'Player 2 optimal:{:s}'
 
         p1_str = '\n{!s}'.format(self.player1_optimal())
         p1_str = '\n  '.join(p1_str.splitlines())
 
         p1_str = '\n{!s}'.format(self.player1_optimal())
         p1_str = '\n  '.join(p1_str.splitlines())
@@ -122,8 +132,39 @@ class SymmetricLinearGame:
     def __str__(self):
         """
         Return a string representatoin of this game.
     def __str__(self):
         """
         Return a string representatoin of this game.
+
+        EXAMPLES:
+
+            >>> from cones import NonnegativeOrthant
+            >>> K = NonnegativeOrthant(3)
+            >>> L = [[1,-1,-12],[-5,2,-15],[-15,-3,1]]
+            >>> e1 = [1,1,1]
+            >>> e2 = [1,2,3]
+            >>> SLG = SymmetricLinearGame(L, K, e1, e2)
+            >>> print(SLG)
+            The linear game (L, K, e1, e2) where
+              L = [  1  -5 -15]
+                  [ -1   2  -3]
+                  [-12 -15   1],
+              K = Nonnegative orthant in the real 3-space,
+              e1 = [ 1]
+                   [ 1]
+                   [ 1],
+              e2 = [ 1]
+                   [ 2]
+                   [ 3].
+
         """
         """
-        return "a game"
+        tpl = 'The linear game (L, K, e1, e2) where\n' \
+              '  L = {:s},\n' \
+              '  K = {!s},\n' \
+              '  e1 = {:s},\n' \
+              '  e2 = {:s}.'
+        L_str = '\n      '.join(str(self._L).splitlines())
+        e1_str = '\n       '.join(str(self._e1).splitlines())
+        e2_str = '\n       '.join(str(self._e2).splitlines())
+        return tpl.format(L_str, str(self._K), e1_str, e2_str)
+
 
     def solution(self):
         """
 
     def solution(self):
         """
@@ -137,6 +178,49 @@ class SymmetricLinearGame:
         could *not* be solved -- which should never happen -- then a
         GameUnsolvableException is raised. It can be printed to get the
         raw output from CVXOPT.
         could *not* be solved -- which should never happen -- then a
         GameUnsolvableException is raised. It can be printed to get the
         raw output from CVXOPT.
+
+        EXAMPLES:
+
+        This example is computed in Gowda and Ravindran in the section
+        "The value of a Z-transformation":
+
+            >>> from cones import NonnegativeOrthant
+            >>> K = NonnegativeOrthant(3)
+            >>> L = [[1,-1,-12],[-5,2,-15],[-15,-3,1]]
+            >>> e1 = [1,1,1]
+            >>> e2 = [1,1,1]
+            >>> SLG = SymmetricLinearGame(L, K, e1, e2)
+            >>> print(SLG.solution())
+            Game value: -6.1724138
+            Player 1 optimal:
+              [ 0.5517241]
+              [-0.0000000]
+              [ 0.4482759]
+            Player 2 optimal:
+              [0.4482759]
+              [0.0000000]
+              [0.5517241]
+
+        The value of the following game can be computed using the fact
+        that the identity is invertible:
+
+            >>> from cones import NonnegativeOrthant
+            >>> K = NonnegativeOrthant(3)
+            >>> L = [[1,0,0],[0,1,0],[0,0,1]]
+            >>> e1 = [1,2,3]
+            >>> e2 = [4,5,6]
+            >>> SLG = SymmetricLinearGame(L, K, e1, e2)
+            >>> print(SLG.solution())
+            Game value: 0.0312500
+            Player 1 optimal:
+              [0.0312500]
+              [0.0625000]
+              [0.0937500]
+            Player 2 optimal:
+              [0.1250000]
+              [0.1562500]
+              [0.1875000]
+
         """
         # The cone "C" that appears in the statement of the CVXOPT
         # conelp program.
         """
         # The cone "C" that appears in the statement of the CVXOPT
         # conelp program.
@@ -164,7 +248,7 @@ class SymmetricLinearGame:
 
         # The matrix "A" that appears on the right-hand side of Ax = b
         # in the statement of the CVXOPT conelp program.
 
         # The matrix "A" that appears on the right-hand side of Ax = b
         # in the statement of the CVXOPT conelp program.
-        A = matrix([0, self._e1], (1, self._K.dimension() + 1), 'd')
+        A = matrix([0, self._e2], (1, self._K.dimension() + 1), 'd')
 
         # Actually solve the thing and obtain a dictionary describing
         # what happened.
 
         # Actually solve the thing and obtain a dictionary describing
         # what happened.
@@ -188,6 +272,28 @@ class SymmetricLinearGame:
     def dual(self):
         """
         Return the dual game to this game.
     def dual(self):
         """
         Return the dual game to this game.
+
+        EXAMPLES:
+
+            >>> from cones import NonnegativeOrthant
+            >>> K = NonnegativeOrthant(3)
+            >>> L = [[1,-1,-12],[-5,2,-15],[-15,-3,1]]
+            >>> e1 = [1,1,1]
+            >>> e2 = [1,2,3]
+            >>> SLG = SymmetricLinearGame(L, K, e1, e2)
+            >>> print(SLG.dual())
+            The linear game (L, K, e1, e2) where
+              L = [  1  -1 -12]
+                  [ -5   2 -15]
+                  [-15  -3   1],
+              K = Nonnegative orthant in the real 3-space,
+              e1 = [ 1]
+                   [ 2]
+                   [ 3],
+              e2 = [ 1]
+                   [ 1]
+                   [ 1].
+
         """
         return SymmetricLinearGame(self._L.trans(),
                                    self._K, # Since "K" is symmetric.
         """
         return SymmetricLinearGame(self._L.trans(),
                                    self._K, # Since "K" is symmetric.