X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=dunshire%2Fgames.py;h=ae1426a2c611f7e315f94fc5fea0e98f1da0905b;hb=cd77ba5250ed98ece623730c26af845366847487;hp=bb808cb592d8e013d390e69ee1b6527fc64db583;hpb=2132f293d3ab198630f9fa26151eed52b21512fb;p=dunshire.git diff --git a/dunshire/games.py b/dunshire/games.py index bb808cb..ae1426a 100644 --- a/dunshire/games.py +++ b/dunshire/games.py @@ -322,6 +322,8 @@ class SymmetricLinearGame: if not self._e2 in K: raise ValueError('the point e2 must lie in the interior of K') + # Initial value of cached method. + self._L_specnorm_value = None def __str__(self): @@ -821,7 +823,7 @@ class SymmetricLinearGame: """ p = self.e2() / (norm(self.e2()) ** 2) dist = self.K().ball_radius(self.e1()) - nu = - specnorm(self.L())/(dist*norm(self.e2())) + nu = - self._L_specnorm()/(dist*norm(self.e2())) x = matrix([nu, p], (self.dimension() + 1, 1)) s = - self._G()*x @@ -834,7 +836,7 @@ class SymmetricLinearGame: """ q = self.e1() / (norm(self.e1()) ** 2) dist = self.K().ball_radius(self.e2()) - omega = specnorm(self.L())/(dist*norm(self.e1())) + omega = self._L_specnorm()/(dist*norm(self.e1())) y = matrix([omega]) z2 = q z1 = y*self.e2() - self.L().trans()*z2 @@ -843,6 +845,23 @@ class SymmetricLinearGame: return {'y': y, 'z': z} + def _L_specnorm(self): + """ + Compute the spectral norm of ``L`` and cache it. + """ + if self._L_specnorm_value is None: + self._L_specnorm_value = specnorm(self.L()) + return self._L_specnorm_value + + def epsilon_scale(self, solution): + # Don't return anything smaller than 1... we can't go below + # out "minimum tolerance." + norm_p1_opt = norm(solution.player1_optimal()) + norm_p2_opt = norm(solution.player2_optimal()) + scale = self._L_specnorm()*(norm_p1_opt + norm_p2_opt) + return max(1, scale) + + def solution(self): """ Solve this linear game and return a :class:`Solution`.