]> gitweb.michael.orlitzky.com - dunshire.git/blobdiff - src/dunshire/errors.py
Print the game data along with every GameUnsolvableException.
[dunshire.git] / src / dunshire / errors.py
index 322479f0d39320ede35977969d7e95577bdce79e..b63344a0311e9c843cdeb189c903902de4a2179b 100644 (file)
@@ -12,7 +12,8 @@ def _pretty_format_dict(dictionary):
 
     The dictionary is also sorted so that it can be tested repeatably.
 
-    EXAMPLES:
+    Examples
+    --------
 
         >>> d = {'foo': 1.234, 'bar': matrix([1,2,3])}
         >>> print(_pretty_format_dict(d))
@@ -39,13 +40,27 @@ def _pretty_format_dict(dictionary):
 
 class GameUnsolvableException(Exception):
     """
-    Every linear game has a solution (this follows from a general
-    min-max theorem). If we can't solve the conic program associated
-    with a linear game, then something is wrong with either the model of
-    the input.
+    An exception raised when a game cannot be solved.
 
-    EXAMPLES:
+    Every linear game has a solution. If we can't solve the conic
+    program associated with a linear game, then something is wrong with
+    either the model or the input, and this exception should be raised.
 
+    Parameters
+    ----------
+
+    solution_dict : dict
+        The solution dictionary returned from the failed cone program.
+
+    Examples
+    --------
+
+       >>> from dunshire import *
+       >>> K = IceCream(2)
+       >>> L = [[1,2],[3,4]]
+       >>> e1 = [1, 0.1]
+       >>> e2 = [3, 0.1]
+       >>> G = SymmetricLinearGame(L,K,e1,e2)
        >>> d = {'residual as dual infeasibility certificate': None,
        ...      'y': matrix([1,1]),
        ...      'dual slack': 8.779496368228267e-10,
@@ -61,9 +76,18 @@ class GameUnsolvableException(Exception):
        ...      'dual objective': 1.0,
        ...      'primal objective': None,
        ...      'gap': None,
-       ...      'residual as primal infeasibility certificate': 3.986246886102996e-09}
-       >>> print(GameUnsolvableException(d))
+       ...      'residual as primal infeasibility certificate':
+       ...          3.986246886102996e-09}
+       >>> print(GameUnsolvableException(G,d))
        Solution failed with result "primal infeasible."
+       The linear game (L, K, e1, e2) where
+         L = [ 1  2]
+             [ 3  4],
+         K = Lorentz "ice cream" cone in the real 2-space,
+         e1 = [1.0000000]
+              [0.1000000],
+         e2 = [3.0000000]
+              [0.1000000].
        CVXOPT returned:
          dual infeasibility: None
          dual objective: 1.0
@@ -88,17 +112,12 @@ class GameUnsolvableException(Exception):
            [ 0]
            [ 0]
     """
-    def __init__(self, solution_dict):
+    def __init__(self, game, solution_dict):
         """
         Create a new GameUnsolvableException object.
-
-        INPUT:
-
-        - ``solution_dict`` -- the solution dictionary returned from the
-          cone program.
-
         """
         super().__init__()
+        self._game = game
         self._solution_dict = solution_dict
 
 
@@ -108,11 +127,13 @@ class GameUnsolvableException(Exception):
 
         The returned representation highlights the "status" field of the
         CVXOPT dictionary, since that should explain what went
-        wrong. The full CVXOPT solution dictionary is included after the
-        status.
+        wrong. The game details and full CVXOPT solution dictionary is
+        included after the status.
         """
         tpl = 'Solution failed with result "{:s}."\n' \
+              '{!s}\n' \
               'CVXOPT returned:\n  {!s}'
         cvx_lines = _pretty_format_dict(self._solution_dict).splitlines()
-        cvx_str = '\n  '.join(cvx_lines) # Indent the whole dict by two spaces.
-        return tpl.format(self._solution_dict['status'], cvx_str)
+        # Indent the whole dict by two spaces.
+        cvx_str = '\n  '.join(cvx_lines)
+        return tpl.format(self._solution_dict['status'], self._game, cvx_str)