Skip to content

Commit

Permalink
Add NormalFormGame.delete_action
Browse files Browse the repository at this point in the history
  • Loading branch information
oyamad committed Nov 5, 2018
1 parent f166eac commit 8703710
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
58 changes: 58 additions & 0 deletions quantecon/game_theory/normal_form_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,64 @@ def __setitem__(self, action_profile, payoff_profile):
tuple(action_profile[i:]) + tuple(action_profile[:i])
] = payoff_profile[i]

def delete_action(self, player_idx, action):
"""
Return a new `NormalFormGame` instance with the action(s)
specified by `action` deleted from the action set of the player
specified by `player_idx`. Deletion is not performed in place.
Parameters
----------
player_idx : scalar(int)
Index of the player to delete action(s) for.
action : scalar(int) or array_like(int)
Integer or array like of integers representing the action(s)
to be deleted.
Returns
-------
NormalFormGame
Copy of `self` with the action(s) deleted as specified.
Examples
--------
>>> g = NormalFormGame(
... [[(3, 0), (0, 1)], [(0, 0), (3, 1)], [(1, 1), (1, 0)]]
... )
>>> print(g)
2-player NormalFormGame with payoff profile array:
[[[3, 0], [0, 1]],
[[0, 0], [3, 1]],
[[1, 1], [1, 0]]]
Delete player `0`'s action `2` from `g`:
>>> g1 = g.delete_action(0, 2)
>>> print(g1)
2-player NormalFormGame with payoff profile array:
[[[3, 0], [0, 1]],
[[0, 0], [3, 1]]]
Then delete player `1`'s action `0` from `g1`:
>>> g2 = g1.delete_action(1, 0)
>>> print(g2)
2-player NormalFormGame with payoff profile array:
[[[0, 1]],
[[3, 1]]]
"""
# Allow negative indexing
if -self.N <= player_idx < 0:
player_idx = player_idx + self.N

players_new = tuple(
player.delete_action(action, player_idx-i)
for i, player in enumerate(self.players)
)
return NormalFormGame(players_new)

def is_nash(self, action_profile, tol=None):
"""
Return True if `action_profile` is a Nash equilibrium.
Expand Down
33 changes: 33 additions & 0 deletions quantecon/game_theory/tests/test_normal_form_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ def test_getitem(self):
assert_array_equal(self.g[action_profile],
self.BoS_bimatrix[action_profile])

def test_delete_action(self):
action_to_delete = 0
for i, player in enumerate(self.g.players):
g_new = self.g.delete_action(i, action_to_delete)
actions_to_remain = \
np.setdiff1d(np.arange(player.num_actions), action_to_delete)
assert_array_equal(
g_new.payoff_profile_array,
self.g.payoff_profile_array.take(actions_to_remain, axis=i)
)

def test_is_nash_pure(self):
ok_(not self.g.is_nash((1, 0)))

Expand Down Expand Up @@ -239,6 +250,17 @@ def setUp(self):
def test_getitem(self):
assert_array_equal(self.g[0, 0, 1], [6, 4, 1])

def test_delete_action(self):
action_to_delete = 0
for i, player in enumerate(self.g.players):
g_new = self.g.delete_action(i, action_to_delete)
actions_to_remain = \
np.setdiff1d(np.arange(player.num_actions), action_to_delete)
assert_array_equal(
g_new.payoff_profile_array,
self.g.payoff_profile_array.take(actions_to_remain, axis=i)
)

def test_is_nash_pure(self):
ok_(self.g.is_nash((0, 0, 0)))
ok_(not self.g.is_nash((0, 0, 1)))
Expand Down Expand Up @@ -382,6 +404,17 @@ def test_getitem(self):
"""Trivial game: __getitem__"""
eq_(self.g[0], 0)

def test_delete_action(self):
actions_to_delete = [1, 2]
for i, player in enumerate(self.g.players):
g_new = self.g.delete_action(i, actions_to_delete)
actions_to_remain = \
np.setdiff1d(np.arange(player.num_actions), actions_to_delete)
assert_array_equal(
g_new.payoff_profile_array,
self.g.payoff_profile_array.take(actions_to_remain, axis=i)
)

def test_is_nash_pure(self):
"""Trivial game: is_nash with pure action"""
ok_(self.g.is_nash((1,)))
Expand Down

0 comments on commit 8703710

Please sign in to comment.