def test_random_matrix_addition(strats): """Test addition""" shape = tuple(strats) + (len(strats), ) payoffs1 = rand.random(shape) matg1 = matgame.matgame(payoffs1) payoffs2 = rand.random(shape) matg2 = matgame.matgame(payoffs2) assert matg1 + matg2 == matgame.matgame(payoffs1 + payoffs2)
def test_random_matrix_addition(strats): """Test addition""" shape = tuple(strats) + (len(strats),) payoffs1 = rand.random(shape) matg1 = matgame.matgame(payoffs1) payoffs2 = rand.random(shape) matg2 = matgame.matgame(payoffs2) assert matg1 + matg2 == matgame.matgame(payoffs1 + payoffs2)
def test_is_constant_sum(): """Test constant sum""" payoffs = [[[2, -1], [0, 1]], [[5, -4], [0.5, 0.5]]] matg = matgame.matgame(payoffs) assert matg.is_constant_sum() payoffs = [[[2, -1], [0, 1]], [[5, -4], [0.5, 0]]] matg = matgame.matgame(payoffs) assert not matg.is_constant_sum()
def test_is_constant_sum(): """Test constant sum""" payoffs = [[[2, -1], [0, 1]], [[5, -4], [0.5, 0.5]]] matg = matgame.matgame(payoffs) assert matg.is_constant_sum() payoffs = [[[2, -1], [0, 1]], [[5, -4], [0.5, 0]]] matg = matgame.matgame(payoffs) assert not matg.is_constant_sum()
def test_submatgame(): """Test restrict""" matrix = rand.random((2, 3, 4, 3)) matg = matgame.matgame(matrix) mask = [True, True, True, False, True, False, False, True, True] submat = matrix[:, [0, 2]][:, :, 2:].copy() smatg = matgame.matgame_names( ['r0', 'r1', 'r2'], [['s0', 's1'], ['s2', 's4'], ['s7', 's8']], submat) assert smatg == matg.restrict(mask) matg = matgame.matgame([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) mask = [True, True, True, False] matg = matgame.matgame_names( ['r0', 'r1'], [['s0', 's1'], ['s2']], [[[1, 2]], [[5, 6]]])
def test_submatgame(): """Test restrict""" matrix = rand.random((2, 3, 4, 3)) matg = matgame.matgame(matrix) mask = [True, True, True, False, True, False, False, True, True] submat = matrix[:, [0, 2]][:, :, 2:].copy() smatg = matgame.matgame_names(['r0', 'r1', 'r2'], [['s0', 's1'], ['s2', 's4'], ['s7', 's8']], submat) assert smatg == matg.restrict(mask) matg = matgame.matgame([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) mask = [True, True, True, False] matg = matgame.matgame_names(['r0', 'r1'], [['s0', 's1'], ['s2']], [[[1, 2]], [[5, 6]]])
def polymatrix_game( num_players, num_strats, matrix_game=independent_game, players_per_matrix=2): """Creates a polymatrix game Each player's payoff in each profile is a sum over independent games played against each set of opponents. Each k-tuple of players plays an instance of the specified random k-player matrix game. Parameters ---------- num_players : int The number of players. num_strats : int The number of strategies per player. matrix_game : (players_per_matrix, num_strats) -> Game, optional A function to generate games between sub groups of players. players_per_matrix : int, optional The number of players that interact simultaneously. Notes ----- The actual roles and strategies of matrix game are ignored. """ payoffs = np.zeros([num_strats] * num_players + [num_players]) for players in itertools.combinations(range(num_players), players_per_matrix): sub_payoffs = matgame.matgame_copy(matrix_game( [num_strats] * players_per_matrix)).payoff_matrix() new_shape = np.array([1] * num_players + [players_per_matrix]) new_shape[list(players)] = num_strats payoffs[..., list(players)] += sub_payoffs.reshape(new_shape) return matgame.matgame(payoffs)
def two_player_zero_sum_game(num_role_strats, distribution=default_distribution): """Generate a two-player, zero-sum game""" # Generate player 1 payoffs num_role_strats = np.broadcast_to(num_role_strats, 2) p1_payoffs = distribution(num_role_strats)[..., None] return matgame.matgame(np.concatenate([p1_payoffs, -p1_payoffs], -1))
def test_random_normalize(strats): """Test normalize""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs).normalize() assert np.allclose(matg.min_role_payoffs(), 0) assert np.allclose(matg.max_role_payoffs(), 1)
def test_random_to_from_json(strats): """Test to from json random""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) jgame = json.dumps(matg.to_json()) copy = matgame.matgame_json(json.loads(jgame)) assert matg == copy
def test_random_to_from_json(strats): """Test to from json random""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) jgame = json.dumps(matg.to_json()) copy = matgame.matgame_json(json.loads(jgame)) assert matg == copy
def test_random_normalize(strats): """Test normalize""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs).normalize() assert np.allclose(matg.min_role_payoffs(), 0) assert np.allclose(matg.max_role_payoffs(), 1)
def test_random_get_payoffs(strats): """Test random get payoffs""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) profiles = matg.random_profiles(20).reshape((4, 5, -1)) payoffs = matg.get_payoffs(profiles) assert profiles.shape == payoffs.shape assert np.all((profiles > 0) | (payoffs == 0))
def test_random_min_max(strats): """Test min and max""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) game = paygame.game_copy(matg) assert np.allclose(matg.min_strat_payoffs(), game.min_strat_payoffs()) assert np.allclose(matg.max_strat_payoffs(), game.max_strat_payoffs())
def test_profiles_payoffs(): """Test payoffs""" matg = matgame.matgame([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) copy = paygame.game_copy(matg) profs = [[1, 0, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1]] pays = [[1, 0, 2, 0], [3, 0, 0, 4], [0, 5, 6, 0], [0, 7, 0, 8]] game = paygame.game([1, 1], 2, profs, pays) assert copy == game
def test_random_get_payoffs(strats): """Test random get payoffs""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) profiles = matg.random_profiles(20).reshape((4, 5, -1)) payoffs = matg.get_payoffs(profiles) assert profiles.shape == payoffs.shape assert np.all((profiles > 0) | (payoffs == 0))
def test_random_min_max(strats): """Test min and max""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) game = paygame.game_copy(matg) assert np.allclose(matg.min_strat_payoffs(), game.min_strat_payoffs()) assert np.allclose(matg.max_strat_payoffs(), game.max_strat_payoffs())
def test_random_game_addition(strats): """Test random addition""" mpayoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(mpayoffs) payoffs = rand.random(matg.payoffs().shape) payoffs[matg.profiles() == 0] = 0 game = paygame.game_replace(matg, matg.profiles(), payoffs) assert paygame.game_copy(matg + game) == game + matg empty = rsgame.empty_copy(matg) assert matg + empty == empty
def test_random_game_addition(strats): """Test random addition""" mpayoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(mpayoffs) payoffs = rand.random(matg.payoffs().shape) payoffs[matg.profiles() == 0] = 0 game = paygame.game_replace(matg, matg.profiles(), payoffs) assert paygame.game_copy(matg + game) == game + matg empty = rsgame.empty_copy(matg) assert matg + empty == empty
def test_compress_profiles(): """Test compress profiles""" matg = matgame.matgame(rand.random((2, 3, 4, 3))) prof = [0, 1, 0, 1, 0, 1, 0, 0, 0] comp_prof = [1, 1, 0] assert np.all(comp_prof == matg.compress_profile(prof)) assert np.all(prof == matg.uncompress_profile(comp_prof)) prof = [0, 1, 1, 0, 0, 0, 0, 0, 1] comp_prof = [1, 0, 3] assert np.all(comp_prof == matg.compress_profile(prof)) assert np.all(prof == matg.uncompress_profile(comp_prof))
def test_compress_profiles(): """Test compress profiles""" matg = matgame.matgame(rand.random((2, 3, 4, 3))) prof = [0, 1, 0, 1, 0, 1, 0, 0, 0] comp_prof = [1, 1, 0] assert np.all(comp_prof == matg.compress_profile(prof)) assert np.all(prof == matg.uncompress_profile(comp_prof)) prof = [0, 1, 1, 0, 0, 0, 0, 0, 1] comp_prof = [1, 0, 3] assert np.all(comp_prof == matg.compress_profile(prof)) assert np.all(prof == matg.uncompress_profile(comp_prof))
def test_random_matgame_hash_eq(strats): """Test hash and eq""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) copy = matgame.matgame_copy(matg) assert hash(copy) == hash(matg) assert copy == matg game = paygame.game_copy(matg) copy = matgame.matgame_copy(game) assert hash(copy) == hash(matg) assert copy == matg
def test_random_matgame_hash_eq(strats): """Test hash and eq""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) copy = matgame.matgame_copy(matg) assert hash(copy) == hash(matg) assert copy == matg game = paygame.game_copy(matg) copy = matgame.matgame_copy(game) assert hash(copy) == hash(matg) assert copy == matg
def test_random_invariants(strats): """Test invariants""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) assert not matg.is_empty() assert matg.is_complete() prof = matg.random_profile() assert prof in matg for prof in matg.random_profiles(20): assert prof in matg assert np.allclose(matg.payoffs(), matg.get_payoffs(matg.profiles()))
def test_to_from_json(): """Test to and from json""" matg = matgame.matgame([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]) mjson = { 'players': { 'r0': 1, 'r1': 1 }, 'strategies': { 'r0': ['s0', 's1', 's2'], 'r1': ['s3', 's4'] }, 'payoffs': { 's0': { 's3': { 'r0': 1, 'r1': 2 }, 's4': { 'r0': 3, 'r1': 4 } }, 's1': { 's3': { 'r0': 5, 'r1': 6 }, 's4': { 'r0': 7, 'r1': 8 } }, 's2': { 's3': { 'r0': 9, 'r1': 10 }, 's4': { 'r0': 11, 'r1': 12 } } }, 'type': 'matrix.1' } assert matg.to_json() == mjson assert json.loads(json.dumps(matg.to_json())) == mjson assert matg == matgame.matgame_json(mjson)
def test_random_invariants(strats): """Test invariants""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) assert not matg.is_empty() assert matg.is_complete() prof = matg.random_profile() assert prof in matg for prof in matg.random_profiles(20): assert prof in matg assert np.allclose(matg.payoffs(), matg.get_payoffs(matg.profiles()))
def test_profiles_payoffs(): """Test payoffs""" matg = matgame.matgame([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) copy = paygame.game_copy(matg) profs = [[1, 0, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1]] pays = [[1, 0, 2, 0], [3, 0, 0, 4], [0, 5, 6, 0], [0, 7, 0, 8]] game = paygame.game([1, 1], 2, profs, pays) assert copy == game
def test_get_payoffs(): """Test get payoffs""" payoffs = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] matg = matgame.matgame(payoffs) expected = [1, 0, 2, 0] assert np.allclose(expected, matg.get_payoffs([1, 0, 1, 0])) expected = [3, 0, 0, 4] assert np.allclose(expected, matg.get_payoffs([1, 0, 0, 1])) expected = [0, 5, 6, 0] assert np.allclose(expected, matg.get_payoffs([0, 1, 1, 0])) expected = [0, 7, 0, 8] assert np.allclose(expected, matg.get_payoffs([0, 1, 0, 1]))
def test_random_compress_profiles(strats): """Test compress profiles""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) prof = matg.random_profile() copy_prof = matg.uncompress_profile(matg.compress_profile(prof)) assert np.all(prof == copy_prof) profs = matg.random_profiles(20) copy_profs = matg.uncompress_profile(matg.compress_profile(profs)) assert np.all(profs == copy_profs) profs = matg.random_profiles(20).reshape((4, 5, -1)) copy_profs = matg.uncompress_profile(matg.compress_profile(profs)) assert np.all(profs == copy_profs)
def test_get_payoffs(): """Test get payoffs""" payoffs = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] matg = matgame.matgame(payoffs) expected = [1, 0, 2, 0] assert np.allclose(expected, matg.get_payoffs([1, 0, 1, 0])) expected = [3, 0, 0, 4] assert np.allclose(expected, matg.get_payoffs([1, 0, 0, 1])) expected = [0, 5, 6, 0] assert np.allclose(expected, matg.get_payoffs([0, 1, 1, 0])) expected = [0, 7, 0, 8] assert np.allclose(expected, matg.get_payoffs([0, 1, 0, 1]))
def test_random_compress_profiles(strats): """Test compress profiles""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) prof = matg.random_profile() copy_prof = matg.uncompress_profile(matg.compress_profile(prof)) assert np.all(prof == copy_prof) profs = matg.random_profiles(20) copy_profs = matg.uncompress_profile(matg.compress_profile(profs)) assert np.all(profs == copy_profs) profs = matg.random_profiles(20).reshape((4, 5, -1)) copy_profs = matg.uncompress_profile(matg.compress_profile(profs)) assert np.all(profs == copy_profs)
def independent_game(num_role_strats, distribution=default_distribution): """Generate a random independent (asymmetric) game All payoffs are generated independently from distribution. Parameters ---------- num_role_strats : int or [int], len == num_role_players The number of strategies for each player. If an int, then it's a one player game. distribution : (shape) -> ndarray (shape) The distribution to sample payoffs from. Must take a single shape argument and return an ndarray of iid values with that shape. """ num_role_strats = np.asarray(num_role_strats, int) shape = np.append(num_role_strats, num_role_strats.size) return matgame.matgame(distribution(shape))
def test_to_from_json(): """Test to and from json""" matg = matgame.matgame( [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]) mjson = { 'players': {'r0': 1, 'r1': 1}, 'strategies': { 'r0': ['s0', 's1', 's2'], 'r1': ['s3', 's4']}, 'payoffs': { 's0': {'s3': {'r0': 1, 'r1': 2}, 's4': {'r0': 3, 'r1': 4}}, 's1': {'s3': {'r0': 5, 'r1': 6}, 's4': {'r0': 7, 'r1': 8}}, 's2': {'s3': {'r0': 9, 'r1': 10}, 's4': {'r0': 11, 'r1': 12}}}, 'type': 'matrix.1'} assert matg.to_json() == mjson assert json.loads(json.dumps(matg.to_json())) == mjson assert matg == matgame.matgame_json(mjson)
def test_random_deviations(strats): """Test random devs""" payoffs = rand.random(tuple(strats) + (len(strats), )) matg = matgame.matgame(payoffs) game = paygame.game_copy(matg) mix = matg.random_mixture() matdev = matg.deviation_payoffs(mix) gamedev = game.deviation_payoffs(mix) assert np.allclose(matdev, gamedev) matdev, matjac = matg.deviation_payoffs(mix, jacobian=True) gamedev, gamejac = game.deviation_payoffs(mix, jacobian=True) assert np.allclose(matdev, gamedev) assert np.allclose(matjac, gamejac) for mix in matg.random_mixtures(20): matdev, matjac = matg.deviation_payoffs(mix, jacobian=True) gamedev, gamejac = game.deviation_payoffs(mix, jacobian=True) assert np.allclose(matdev, gamedev) assert np.allclose(matjac, gamejac)
def test_random_deviations(strats): """Test random devs""" payoffs = rand.random(tuple(strats) + (len(strats),)) matg = matgame.matgame(payoffs) game = paygame.game_copy(matg) mix = matg.random_mixture() matdev = matg.deviation_payoffs(mix) gamedev = game.deviation_payoffs(mix) assert np.allclose(matdev, gamedev) matdev, matjac = matg.deviation_payoffs(mix, jacobian=True) gamedev, gamejac = game.deviation_payoffs(mix, jacobian=True) assert np.allclose(matdev, gamedev) assert np.allclose(matjac, gamejac) for mix in matg.random_mixtures(20): matdev, matjac = matg.deviation_payoffs(mix, jacobian=True) gamedev, gamejac = game.deviation_payoffs(mix, jacobian=True) assert np.allclose(matdev, gamedev) assert np.allclose(matjac, gamejac)
def covariant_game( num_role_strats, mean_dist=np.zeros, var_dist=np.ones, covar_dist=default_distribution): """Generate a covariant game Covariant games are asymmetric games where payoff values for each profile drawn according to multivariate normal. The multivariate normal for each profile has a constant mean drawn from `mean_dist`, constant variance drawn from`var_dist`, and constant covariance drawn from `covar_dist`. Parameters ---------- mean_dist : (shape) -> ndarray (shape) Distribution from which mean payoff for each profile is drawn. (default: lambda: 0) var_dist : (shape) -> ndarray (shape) Distribution from which payoff variance for each profile is drawn. (default: lambda: 1) covar_dist : (shape) -> ndarray (shape) Distribution from which the value of the off-diagonal covariance matrix entries for each profile is drawn. (default: uniform [-1, 1]) """ # Create sampling distributions and sample from them num_role_strats = list(num_role_strats) num_players = len(num_role_strats) shape = num_role_strats + [num_players] var = covar_dist(shape + [num_players]) diag = var.diagonal(0, num_players, num_players + 1) diag.setflags(write=True) # Hack np.copyto(diag, var_dist(shape)) # The next couple of lines do multivariate Gaussian sampling for all # payoffs simultaneously _, diag, right = np.linalg.svd(var) payoffs = rand.normal(size=shape) payoffs = np.einsum('...i,...i,...ij->...j', payoffs, np.sqrt(diag), right) payoffs += mean_dist(shape) return matgame.matgame(payoffs)
def mat(): """Matrix game""" return matgame.matgame(np.random.random((4, 3, 2, 3)))
def test_non_zero_sum_mixture_welfare(): """Test nonzero mixed welfare""" game = matgame.matgame([[[3.5, 2.5]]]) assert np.isclose(regret.mixed_social_welfare(game, [1, 1]), 6), \ "Didn't properly sum welfare"
def mat(): """Matrix game""" return matgame.matgame(np.random.random((4, 3, 2, 3)))
def test_matgame_repr(): """Test repr""" matg = matgame.matgame(rand.random((2, 1))) assert repr(matg) == 'MatrixGame([2])' matg = matgame.matgame(rand.random((2, 3, 2))) assert repr(matg) == 'MatrixGame([2 3])'
def test_non_zero_sum_profile_welfare(): """Test nonzero profile welfare""" game = matgame.matgame([[[3.5, 2.5]]]) assert np.isclose(regret.pure_social_welfare(game, [1, 1]), 6), \ "didn't properly sum welfare"
def test_matgame_repr(): """Test repr""" matg = matgame.matgame(rand.random((2, 1))) assert repr(matg) == 'MatrixGame([2])' matg = matgame.matgame(rand.random((2, 3, 2))) assert repr(matg) == 'MatrixGame([2 3])'