]> 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.
 
 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
     --------
 
     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,
        >>> 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}
        ...      'gap': None,
        ...      'residual as primal infeasibility certificate':
        ...          3.986246886102996e-09}
-       >>> print(GameUnsolvableException(d))
+       >>> print(GameUnsolvableException(G,d))
        Solution failed with result "primal infeasible."
        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
        CVXOPT returned:
          dual infeasibility: None
          dual objective: 1.0
@@ -98,11 +112,12 @@ class GameUnsolvableException(Exception):
            [ 0]
            [ 0]
     """
            [ 0]
            [ 0]
     """
-    def __init__(self, solution_dict):
+    def __init__(self, game, solution_dict):
         """
         Create a new GameUnsolvableException object.
         """
         super().__init__()
         """
         Create a new GameUnsolvableException object.
         """
         super().__init__()
+        self._game = game
         self._solution_dict = solution_dict
 
 
         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
 
         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' \
         """
         tpl = 'Solution failed with result "{:s}."\n' \
+              '{!s}\n' \
               'CVXOPT returned:\n  {!s}'
         cvx_lines = _pretty_format_dict(self._solution_dict).splitlines()
               '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)
         # 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']:
         # 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
         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:
             # 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):
             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)
 
 
         return Solution(p1_value, p1_optimal, p2_optimal)