]>
gitweb.michael.orlitzky.com - dunshire.git/blob - errors.py
61fe43d243b65d51595baa09c75e797c002fe306
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,
94 Condition((L, K, e1, e2)) = 8.311277.
96 dual infeasibility: None
98 dual slack: 8.779496368228267e-10
101 primal infeasibility: None
102 primal objective: None
105 residual as dual infeasibility certificate: None
106 residual as primal infeasibility certificate: 3.986246886102996e-09
108 status: primal infeasible
119 def __init__(self
, game
, solution_dict
):
121 Create a new :class:`GameUnsolvableException` object.
125 self
._solution
_dict
= solution_dict
130 Return a string representation of this exception.
132 The returned representation highlights the "status" field of the
133 CVXOPT dictionary, since that should explain what went
134 wrong. The game details and full CVXOPT solution dictionary are
135 included after the status.
137 tpl
= 'Solution failed with result "{:s}."\n' \
139 'CVXOPT returned:\n {!s}'
140 cvx_lines
= _pretty_format_dict(self
._solution
_dict
).splitlines()
141 # Indent the whole dict by two spaces.
142 cvx_str
= '\n '.join(cvx_lines
)
143 return tpl
.format(self
._solution
_dict
['status'], self
._game
, cvx_str
)
146 class PoorScalingException(Exception):
148 An exception raised when poor scaling leads to solution errors.
150 Under certain circumstances, a problem that should be solvable can
151 trigger errors in CVXOPT. The end result is the following
152 :class:`ValueError`::
154 Traceback (most recent call last):
156 return math.sqrt(x[offset] - a) * math.sqrt(x[offset] + a)
157 ValueError: math domain error
159 This happens when one of the arguments to :func:`math.sqrt` is
160 negative, but the underlying cause is elusive. We're blaming it on
161 "poor scaling," whatever that means.
163 Similar issues have been discussed a few times on the CVXOPT mailing
166 1. https://groups.google.com/forum/#!msg/cvxopt/TeQGdc2b4Xc/j5_mQME_rvUJ
167 2. https://groups.google.com/forum/#!topic/cvxopt/HZrRfaoM0pk
168 3. https://groups.google.com/forum/#!topic/cvxopt/riFSxB31zU4
173 game : SymmetricLinearGame
174 A copy of the game whose solution failed.
179 >>> from dunshire import *
181 >>> L = [[1,2],[3,4]]
184 >>> G = SymmetricLinearGame(L,K,e1,e2)
185 >>> print(PoorScalingException(G))
186 Solution failed due to poor scaling.
187 The linear game (L, K, e1, e2) where
190 K = Lorentz "ice cream" cone in the real 2-space,
195 Condition((L, K, e1, e2)) = 8.311277.
198 def __init__(self
, game
):
200 Create a new :class:`PoorScalingException` object.
208 Return a string representation of this exception.
210 Pretty much all we can say is that there was poor scaling; that
211 is, that CVXOPT failed. The game details are included after
214 tpl
= 'Solution failed due to poor scaling.\n' \
216 return tpl
.format(self
._game
)