]>
gitweb.michael.orlitzky.com - dunshire.git/blob - dunshire/errors.py
b5eb6291f221c9bcfb0e79ac4ec87ebfd3fe4096
2 Errors that can occur when solving a linear game.
5 from cvxopt
import matrix
8 def _pretty_format_dict(dictionary
):
10 Return a pretty-formatted string representation of a dictionary
11 containing CVXOPT matrices.
13 The dictionary is also sorted so that it can be tested repeatably.
18 >>> d = {'foo': 1.234, 'bar': matrix([1,2,3])}
19 >>> print(_pretty_format_dict(d))
28 for (key
, value
) in sorted(dictionary
.items()):
29 if isinstance(value
, matrix
):
30 # Display matrices on their own lines, indented.
31 result
+= '{:s}:'.format(key
)
32 colvec
= '\n{!s}'.format(value
)
33 result
+= '\n '.join(colvec
.splitlines())
36 result
+= '{:s}: {!s}\n'.format(key
, value
)
38 return result
.rstrip('\n') # Kills trailing newlines on matrices.
41 class GameUnsolvableException(Exception):
43 An exception raised when a game cannot be solved.
45 Every linear game has a solution. If we can't solve the conic
46 program associated with a linear game, then something is wrong with
47 either the model or the input, and this exception should be raised.
52 game : SymmetricLinearGame
53 A copy of the game whose solution failed.
56 The solution dictionary returned from the failed cone program.
61 >>> from dunshire import *
66 >>> G = SymmetricLinearGame(L,K,e1,e2)
67 >>> d = {'residual as dual infeasibility certificate': None,
68 ... 'y': matrix([1,1]),
69 ... 'dual slack': 8.779496368228267e-10,
70 ... 'z': matrix([1,1,0,0]),
72 ... 'primal infeasibility': None,
73 ... 'status': 'primal infeasible',
74 ... 'dual infeasibility': None,
75 ... 'relative gap': None,
77 ... 'primal slack': None,
79 ... 'dual objective': 1.0,
80 ... 'primal objective': None,
82 ... 'residual as primal infeasibility certificate':
83 ... 3.986246886102996e-09}
84 >>> print(GameUnsolvableException(G,d))
85 Solution failed with result "primal infeasible."
86 The linear game (L, K, e1, e2) where
89 K = Lorentz "ice cream" cone in the real 2-space,
95 dual infeasibility: None
97 dual slack: 8.779496368228267e-10
100 primal infeasibility: None
101 primal objective: None
104 residual as dual infeasibility certificate: None
105 residual as primal infeasibility certificate: 3.986246886102996e-09
107 status: primal infeasible
118 def __init__(self
, game
, solution_dict
):
120 Create a new :class:`GameUnsolvableException` object.
124 self
._solution
_dict
= solution_dict
129 Return a string representation of this exception.
131 The returned representation highlights the "status" field of the
132 CVXOPT dictionary, since that should explain what went
133 wrong. The game details and full CVXOPT solution dictionary are
134 included after the status.
136 tpl
= 'Solution failed with result "{:s}."\n' \
138 'CVXOPT returned:\n {!s}'
139 cvx_lines
= _pretty_format_dict(self
._solution
_dict
).splitlines()
140 # Indent the whole dict by two spaces.
141 cvx_str
= '\n '.join(cvx_lines
)
142 return tpl
.format(self
._solution
_dict
['status'], self
._game
, cvx_str
)
145 class PoorScalingException(Exception):
147 An exception raised when poor scaling leads to solution errors.
149 Under certain circumstances, a problem that should be solvable can
150 trigger errors in CVXOPT. The end result is the following
151 :class:`ValueError`::
153 Traceback (most recent call last):
155 return math.sqrt(x[offset] - a) * math.sqrt(x[offset] + a)
156 ValueError: math domain error
158 This happens when one of the arguments to :func:`math.sqrt` is
159 negative, but the underlying cause is elusive. We're blaming it on
160 "poor scaling," whatever that means.
162 Similar issues have been discussed a few times on the CVXOPT mailing
165 1. https://groups.google.com/forum/#!msg/cvxopt/TeQGdc2b4Xc/j5_mQME_rvUJ
166 2. https://groups.google.com/forum/#!topic/cvxopt/HZrRfaoM0pk
167 3. https://groups.google.com/forum/#!topic/cvxopt/riFSxB31zU4
172 game : SymmetricLinearGame
173 A copy of the game whose solution failed.
178 >>> from dunshire import *
180 >>> L = [[1,2],[3,4]]
183 >>> G = SymmetricLinearGame(L,K,e1,e2)
184 >>> print(PoorScalingException(G))
185 Solution failed due to poor scaling.
186 The linear game (L, K, e1, e2) where
189 K = Lorentz "ice cream" cone in the real 2-space,
196 def __init__(self
, game
):
198 Create a new :class:`PoorScalingException` object.
206 Return a string representation of this exception.
208 Pretty much all we can say is that there was poor scaling; that
209 is, that CVXOPT failed. The game details are included after
212 tpl
= 'Solution failed due to poor scaling.\n' \
214 return tpl
.format(self
._game
)