diff --git a/quantecon/game_theory/__init__.py b/quantecon/game_theory/__init__.py index f8aea8bce..66bcf8b1a 100644 --- a/quantecon/game_theory/__init__.py +++ b/quantecon/game_theory/__init__.py @@ -5,7 +5,9 @@ """ from .normal_form_game import Player, NormalFormGame from .normal_form_game import pure2mixed, best_response_2p -from .random import random_game, covariance_game +from .random import ( + random_game, covariance_game, random_pure_actions, random_mixed_actions +) from .pure_nash import pure_nash_brute, pure_nash_brute_gen from .support_enumeration import support_enumeration, support_enumeration_gen from .lemke_howson import lemke_howson diff --git a/quantecon/game_theory/random.py b/quantecon/game_theory/random.py index 2ec24cede..bc1fb74a0 100644 --- a/quantecon/game_theory/random.py +++ b/quantecon/game_theory/random.py @@ -2,10 +2,12 @@ Generate random NormalFormGame instances. """ + import numpy as np from .normal_form_game import Player, NormalFormGame from ..util import check_random_state +from ..random import probvec def random_game(nums_actions, random_state=None): @@ -92,3 +94,60 @@ def covariance_game(nums_actions, rho, random_state=None): random_state.multivariate_normal(mean, cov, nums_actions) g = NormalFormGame(payoff_profile_array) return g + + +def random_pure_actions(nums_actions, random_state=None): + """ + Return a tuple of random pure actions (integers). + + Parameters + ---------- + nums_actions : tuple(int) + Tuple of the numbers of actions, one for each player. + + random_state : int or np.random.RandomState, optional + Random seed (integer) or np.random.RandomState instance to set + the initial state of the random number generator for + reproducibility. If None, a randomly initialized RandomState is + used. + + Returns + ------- + action_profile : Tuple(int) + Tuple of actions, one for each player. + + """ + random_state = check_random_state(random_state) + action_profile = tuple( + [random_state.randint(num_actions) for num_actions in nums_actions] + ) + return action_profile + + +def random_mixed_actions(nums_actions, random_state=None): + """ + Return a tuple of random mixed actions (vectors of floats). + + Parameters + ---------- + nums_actions : tuple(int) + Tuple of the numbers of actions, one for each player. + + random_state : int or np.random.RandomState, optional + Random seed (integer) or np.random.RandomState instance to set + the initial state of the random number generator for + reproducibility. If None, a randomly initialized RandomState is + used. + + Returns + ------- + action_profile : tuple(ndarray(float, ndim=1)) + Tuple of mixed_actions, one for each player. + + """ + random_state = check_random_state(random_state) + action_profile = tuple( + [probvec(1, num_actions, random_state).ravel() + for num_actions in nums_actions] + ) + return action_profile diff --git a/quantecon/game_theory/tests/test_random.py b/quantecon/game_theory/tests/test_random.py index 54fa25bfe..83d1a846f 100644 --- a/quantecon/game_theory/tests/test_random.py +++ b/quantecon/game_theory/tests/test_random.py @@ -4,9 +4,11 @@ """ import numpy as np from numpy.testing import assert_allclose, assert_raises -from nose.tools import eq_ +from nose.tools import eq_, ok_ -from quantecon.game_theory import random_game, covariance_game +from quantecon.game_theory import ( + random_game, covariance_game, random_pure_actions, random_mixed_actions +) def test_random_game(): @@ -59,6 +61,25 @@ def test_covariance_game_value_error(): assert_raises(ValueError, covariance_game, nums_actions, rho) +def test_random_pure_actions(): + nums_actions = (2, 3, 4) + N = len(nums_actions) + seed = 1234 + action_profiles = [ + random_pure_actions(nums_actions, seed) for i in range(2) + ] + for i in range(N): + ok_(action_profiles[0][i] < nums_actions[i]) + eq_(action_profiles[0], action_profiles[1]) + + +def test_random_mixed_actions(): + nums_actions = (2, 3, 4) + seed = 1234 + action_profile = random_mixed_actions(nums_actions, seed) + eq_(tuple([len(action) for action in action_profile]), nums_actions) + + if __name__ == '__main__': import sys import nose