Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TEST: Increase coverage on game_theory #343

Merged
merged 8 commits into from
Oct 1, 2017
97 changes: 95 additions & 2 deletions quantecon/game_theory/tests/test_mclennan_tourky.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@

"""
import numpy as np
from nose.tools import ok_
from numpy.testing import assert_allclose
from nose.tools import ok_, raises
from quantecon.game_theory import Player, NormalFormGame, mclennan_tourky
from quantecon.game_theory.mclennan_tourky import _best_response_selection, \
_flatten_action_profile, \
_is_epsilon_nash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be something like

from quantecon.game_theory.mclennan_tourky import (
    _best_response_selection, _flatten_action_profile, _is_epsilon_nash
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @oyamad I didn't know you could use ( like this.



class TestMclennanTourky():
Expand Down Expand Up @@ -54,13 +58,102 @@ def test_pure_nash(self):
NE, res = mclennan_tourky(d['g'], init=init, full_output=True)
ok_(res.num_iter==1)

def test_epsilon_nash(self):

class TestMclennanTourkyInvalidInputs():
def setUp(self):
self.bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
self.g = NormalFormGame(self.bimatrix)

@raises(TypeError)
def test_mclennan_tourky_invalid_g(self):
mclennan_tourky(self.bimatrix)

@raises(TypeError)
def test_mclennan_tourky_invalid_init_type(self):
mclennan_tourky(self.g, 1)

@raises(ValueError)
def test_mclennan_tourky_invalid_init_length(self):
mclennan_tourky(self.g, [1])


class TestEpsilonNash():
def setUp(self):
def anti_coordination(N, v):
payoff_array = np.empty((2,)*N)
payoff_array[0, :] = 1
payoff_array[1, :] = 0
payoff_array[1].flat[0] = v
g = NormalFormGame((Player(payoff_array),)*N)
return g

def p_star(N, v):
# Unique symmetric NE mixed action: [p_star, 1-p_star]
return 1 / (v**(1/(N-1)))

def epsilon_nash_interval(N, v, epsilon):
# Necessary, but not sufficient, condition: lb < p < ub
lb = p_star(N, v) - epsilon / ((N-1)*(v**(1/(N-1))-1))
ub = p_star(N, v) + epsilon / (N-1)
return lb, ub

self.game_dicts = []
v = 2
epsilon = 1e-5

Ns = [2, 3, 4]
for N in Ns:
g = anti_coordination(N, v)
lb, ub = epsilon_nash_interval(N, v, epsilon)
d = {'g': g,
'epsilon': epsilon,
'lb': lb,
'ub': ub}
self.game_dicts.append(d)

self.bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
self.g = NormalFormGame(self.bimatrix)

def test_epsilon_nash_with_full_output(self):
for d in self.game_dicts:
NE, res = \
mclennan_tourky(d['g'], epsilon=d['epsilon'], full_output=True)
for i in range(d['g'].N):
ok_(d['lb'] < NE[i][0] < d['ub'])

def test_epsilon_nash_without_full_output(self):
for d in self.game_dicts:
NE = mclennan_tourky(d['g'], epsilon=d['epsilon'],
full_output=False)
for i in range(d['g'].N):
ok_(d['lb'] < NE[i][0] < d['ub'])

def test_is_epsilon_nash_no_indptr(self):
ok_(_is_epsilon_nash([1., 0., 0., 1., 0.], self.g, 1e-5))


def test_flatten_action_profile():
unflattened_actions = [[1/3, 1/3, 1/3], [1/2, 1/2]]
flattened_actions = [1/3, 1/3, 1/3, 1/2, 1/2]
test_obj = _flatten_action_profile(unflattened_actions, [0, 3, 5])
assert_allclose(test_obj, flattened_actions)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be assert_array_equal?



def test_best_response_selection_no_indptr():
bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
g = NormalFormGame(bimatrix)

test_obj = _best_response_selection([1/3, 1/3, 1/3, 1/2,1/2], g)
expected_output = np.array([0., 1., 0., 0., 1.])

assert_allclose(test_obj, expected_output)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be assert_array_equal?



if __name__ == '__main__':
import sys
Expand Down
10 changes: 9 additions & 1 deletion quantecon/game_theory/tests/test_support_enumeration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""
import numpy as np
from numpy.testing import assert_allclose
from nose.tools import eq_
from nose.tools import eq_, raises
from quantecon.util import check_random_state
from quantecon.game_theory import Player, NormalFormGame, support_enumeration

Expand Down Expand Up @@ -71,6 +71,14 @@ def test_no_error_skew_sym(self):
NEs = support_enumeration(g)


@raises(TypeError)
def test_support_enumeration_invalid_g():
bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
support_enumeration(bimatrix)


if __name__ == '__main__':
import sys
import nose
Expand Down
19 changes: 18 additions & 1 deletion quantecon/game_theory/tests/test_vertex_enumeration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""
import numpy as np
from numpy.testing import assert_allclose, assert_array_equal
from nose.tools import eq_
from nose.tools import eq_, raises
from quantecon.game_theory import NormalFormGame, vertex_enumeration
from quantecon.game_theory.vertex_enumeration import _BestResponsePolytope

Expand Down Expand Up @@ -46,6 +46,14 @@ def test_vertex_enumeration(self):
assert_allclose(action_computed, action)


@raises(TypeError)
def test_vertex_enumeration_invalid_g():
bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
vertex_enumeration(bimatrix)


class TestBestResponsePolytope:
def setUp(self):
# From von Stengel 2007 in Algorithmic Game Theory
Expand Down Expand Up @@ -98,6 +106,15 @@ def test_best_response_polytope(self):
assert_allclose(vertices_computed, self.vertices_P, atol=1e-15)


@raises(TypeError)
def test_best_response_polytope_invalid_player_instance():
bimatrix = [[(3, 3), (3, 2)],
[(2, 2), (5, 6)],
[(0, 3), (6, 1)]]
g = NormalFormGame(bimatrix)
_BestResponsePolytope(g)


if __name__ == '__main__':
import sys
import nose
Expand Down