]> gitweb.michael.orlitzky.com - dunshire.git/commitdiff
Print the game data along with every GameUnsolvableException.
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 16 Oct 2016 04:42:48 +0000 (00:42 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 16 Oct 2016 04:42:48 +0000 (00:42 -0400)
TODO
src/dunshire/errors.py
src/dunshire/games.py

diff --git a/TODO b/TODO
index b0b503bc4465b5048b83ffbe91b375ea73ac6e09..d23728e534602656da527a224820370d1152da2d 100644 (file)
--- a/TODO
+++ b/TODO
@@ -12,4 +12,3 @@
 6. Come up with a fast heuristic (like making nu huge and taking e1 as
    our point) that finds a primal feasible point.
 
-7. Should our one exception also spit out the game parameters?
index 020186475b2a920f8425ffe0be76b3a27625de85..b63344a0311e9c843cdeb189c903902de4a2179b 100644 (file)
@@ -55,6 +55,12 @@ class GameUnsolvableException(Exception):
     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,
@@ -72,8 +78,16 @@ class GameUnsolvableException(Exception):
        ...      'gap': None,
        ...      'residual as primal infeasibility certificate':
        ...          3.986246886102996e-09}
-       >>> print(GameUnsolvableException(d))
+       >>> 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
@@ -98,11 +112,12 @@ class GameUnsolvableException(Exception):
            [ 0]
            [ 0]
     """
-    def __init__(self, solution_dict):
+    def __init__(self, game, solution_dict):
         """
         Create a new GameUnsolvableException object.
         """
         super().__init__()
+        self._game = game
         self._solution_dict = solution_dict
 
 
@@ -112,14 +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()
-
         # Indent the whole dict by two spaces.
         cvx_str = '\n  '.join(cvx_lines)
-
-        return tpl.format(self._solution_dict['status'], cvx_str)
+        return tpl.format(self._solution_dict['status'], self._game, cvx_str)
index 43fa007c61077c90ef627e9738afbaa09dcde9c1..80f5f8ae2a46d09f15e34546c511edeca286f4fa 100644 (file)
@@ -445,7 +445,7 @@ class SymmetricLinearGame:
         # worst, since they indicate that CVXOPT is convinced the
         # problem is infeasible (and that cannot happen).
         if soln_dict['status'] in ['primal infeasible', 'dual infeasible']:
-            raise GameUnsolvableException(soln_dict)
+            raise GameUnsolvableException(self, soln_dict)
         elif soln_dict['status'] == 'unknown':
             # When we get a status of "unknown", we may still be able
             # to salvage a solution out of the returned
@@ -455,9 +455,9 @@ class SymmetricLinearGame:
             # primal/dual optimal solutions are within the cone (to a
             # tolerance as well).
             if abs(p1_value - p2_value) > options.ABS_TOL:
-                raise GameUnsolvableException(soln_dict)
+                raise GameUnsolvableException(self, soln_dict)
             if (p1_optimal not in self._K) or (p2_optimal not in self._K):
-                raise GameUnsolvableException(soln_dict)
+                raise GameUnsolvableException(self, soln_dict)
 
         return Solution(p1_value, p1_optimal, p2_optimal)