X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=dunshire%2Ferrors.py;h=424f3e62352848c7f673375e401da18c25cdbb98;hb=299bf2d606eb245ec78f2e20826836c0bb5bfc07;hp=b63344a0311e9c843cdeb189c903902de4a2179b;hpb=bdb596b84a06d0c97e39d42586a51fc36ba44186;p=dunshire.git diff --git a/dunshire/errors.py b/dunshire/errors.py index b63344a..424f3e6 100644 --- a/dunshire/errors.py +++ b/dunshire/errors.py @@ -49,6 +49,9 @@ class GameUnsolvableException(Exception): Parameters ---------- + game : SymmetricLinearGame + A copy of the game whose solution failed. + solution_dict : dict The solution dictionary returned from the failed cone program. @@ -87,7 +90,8 @@ class GameUnsolvableException(Exception): e1 = [1.0000000] [0.1000000], e2 = [3.0000000] - [0.1000000]. + [0.1000000], + Condition((L, K, e1, e2)) = 4.155... CVXOPT returned: dual infeasibility: None dual objective: 1.0 @@ -114,7 +118,7 @@ class GameUnsolvableException(Exception): """ def __init__(self, game, solution_dict): """ - Create a new GameUnsolvableException object. + Create a new :class:`GameUnsolvableException` object. """ super().__init__() self._game = game @@ -127,7 +131,7 @@ class GameUnsolvableException(Exception): The returned representation highlights the "status" field of the CVXOPT dictionary, since that should explain what went - wrong. The game details and full CVXOPT solution dictionary is + wrong. The game details and full CVXOPT solution dictionary are included after the status. """ tpl = 'Solution failed with result "{:s}."\n' \ @@ -137,3 +141,76 @@ class GameUnsolvableException(Exception): # Indent the whole dict by two spaces. cvx_str = '\n '.join(cvx_lines) return tpl.format(self._solution_dict['status'], self._game, cvx_str) + + +class PoorScalingException(Exception): + """ + An exception raised when poor scaling leads to solution errors. + + Under certain circumstances, a problem that should be solvable can + trigger errors in CVXOPT. The end result is the following + :class:`ValueError`:: + + Traceback (most recent call last): + ... + return math.sqrt(x[offset] - a) * math.sqrt(x[offset] + a) + ValueError: math domain error + + This happens when one of the arguments to :func:`math.sqrt` is + negative, but the underlying cause is elusive. We're blaming it on + "poor scaling," whatever that means. + + Similar issues have been discussed a few times on the CVXOPT mailing + list; for example, + + 1. https://groups.google.com/forum/#!msg/cvxopt/TeQGdc2b4Xc/j5_mQME_rvUJ + 2. https://groups.google.com/forum/#!topic/cvxopt/HZrRfaoM0pk + 3. https://groups.google.com/forum/#!topic/cvxopt/riFSxB31zU4 + + Parameters + ---------- + + game : SymmetricLinearGame + A copy of the game whose solution failed. + + 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) + >>> print(PoorScalingException(G)) + Solution failed due to poor scaling. + 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], + Condition((L, K, e1, e2)) = 4.155... + + """ + def __init__(self, game): + """ + Create a new :class:`PoorScalingException` object. + """ + super().__init__() + self._game = game + + + def __str__(self): + """ + Return a string representation of this exception. + + Pretty much all we can say is that there was poor scaling; that + is, that CVXOPT failed. The game details are included after + that. + """ + tpl = 'Solution failed due to poor scaling.\n' \ + '{!s}\n' + return tpl.format(self._game)