Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_bi_matrix_init(self, A, B):
"""Test that can create a bi matrix game"""
g = nash.Game(A, B)
self.assertEqual(g.payoff_matrices, (A, B))
if np.array_equal(A, -B): # Check if A or B are non zero
self.assertTrue(g.zero_sum)
else:
self.assertFalse(g.zero_sum)
# Can also init with lists
A = A.tolist()
B = B.tolist()
g = nash.Game(A, B)
self.assertTrue(np.array_equal(g.payoff_matrices[0], np.asarray(A)))
self.assertTrue(np.array_equal(g.payoff_matrices[1], np.asarray(B)))
def test_fictitious_play(self, A, B, seed):
"""Test for the fictitious play algorithm"""
g = nash.Game(A, B)
iterations = 25
np.random.seed(seed)
expected_outcome = tuple(
nashpy.learning.fictitious_play.fictitious_play(
*g.payoff_matrices, iterations=iterations
)
)
np.random.seed(seed)
outcome = tuple(g.fictitious_play(iterations=iterations))
assert len(outcome) == iterations + 1
assert len(expected_outcome) == iterations + 1
for plays, expected_plays in zip(outcome, expected_outcome):
row_play, column_play = plays
expected_row_play, expected_column_play = expected_plays
assert np.array_equal(row_play, expected_row_play)
assert np.array_equal(column_play, expected_column_play)
def test_support_enumeration_for_deg_bi_matrix_game_with_low_tol(self):
A = np.array([[0, 0], [0, 0]])
g = nash.Game(A)
with warnings.catch_warnings(record=True) as w:
obtained_equilibria = list(g.support_enumeration(tol=0))
self.assertEqual(len(obtained_equilibria), 4)
self.assertGreater(len(w), 0)
self.assertEqual(w[-1].category, RuntimeWarning)
def test_get_item(self):
"""Test solve indifference"""
A = np.array([[1, -1], [-1, 1]])
g = nash.Game(A)
row_strategy = [0, 1]
column_strategy = [1, 0]
self.assertTrue(
np.array_equal(g[row_strategy, column_strategy], np.array((-1, 1)))
)
row_strategy = [1 / 2, 1 / 2]
column_strategy = [1 / 2, 1 / 2]
self.assertTrue(
np.array_equal(g[row_strategy, column_strategy], np.array((0, 0)))
)
def test_particular_lemke_howson_raises_warning(self):
"""
This is a degenerate game so the algorithm fails.
This was raised in
https://github.com/drvinceknight/Nashpy/issues/35
"""
A = np.array([[-1, -1, -1], [0, 0, 0], [-1, -1, -10000]])
B = np.array([[-1, -1, -1], [0, 0, 0], [-1, -1, -10000]])
game = nash.Game(A, B)
with warnings.catch_warnings(record=True) as w:
eqs = game.lemke_howson(initial_dropped_label=0)
self.assertEqual(len(eqs[0]), 2)
self.assertEqual(len(eqs[1]), 4)
self.assertGreater(len(w), 0)
self.assertEqual(w[-1].category, RuntimeWarning)
for obtained, expected in zip(
obtained_equilibria, expected_equilibria
):
for s1, s2 in zip(obtained, expected):
self.assertTrue(
np.array_equal(s1, s2),
msg="obtained: {} !=expected: {}".format(
obtained, expected
),
)
self.assertGreater(len(w), 0)
self.assertEqual(w[-1].category, RuntimeWarning)
A = np.array([[3, 3], [2, 5], [0, 6]])
B = np.array([[3, 3], [2, 6], [3, 1]])
g = nash.Game(A, B)
expected_equilibria = [
(np.array([1, 0, 0]), np.array([1, 0])),
(np.array([0, 1 / 3, 2 / 3]), np.array([1 / 3, 2 / 3])),
]
with warnings.catch_warnings(record=True) as w:
obtained_equilibria = list(g.support_enumeration())
for obtained, expected in zip(
obtained_equilibria, expected_equilibria
):
for s1, s2 in zip(obtained, expected):
self.assertTrue(
np.allclose(s1, s2),
msg="obtained: {} !=expected: {}".format(
obtained, expected
),
)
def _update_d(p):
p = np.reshape(p, [-1])
result = self.destructive_mixture_d(p)
return p, result
if self.config.nash_method == 'support':
try:
u = next(nash.Game(payoffa, payoffb).support_enumeration())
except(StopIteration):
print("Nashpy 'support' iteration failed. Using 1,0,0...")
u = [list(np.zeros(len(self.sds))), list(np.zeros(len(self.sgs)))]
u[0][0]=1.
u[1][0]=1.
elif self.config.nash_method == 'lemke':
u = next(nash.Game(payoffa, payoffb).lemke_howson_enumeration())
else:
try:
u = next(nash.Game(payoffa, payoffb).vertex_enumeration())
except(StopIteration, scipy.spatial.qhull.QhullError):
print("Nashpy 'vertex' iteration failed. Using 1,0,0...")
u = [list(np.zeros(len(self.sds))), list(np.zeros(len(self.sgs)))]
u[0][0]=1.
u[1][0]=1.
if len(u[0]) != len(self.sgs):
return [None,None,None,None]
p1, p1result = _update_g(u[0])
p2, p2result = _update_d(u[1])
return p1, p1result, p2, p2result
"""
Code to draw plot for the documentation.
This plots a divergent fictitious play example.
The code should match the reference code in the documentation.
"""
import matplotlib.pyplot as plt
import nashpy as nash
import numpy as np
A = np.array([[0, 1, 0], [0, 0, 1], [1, 0, 0]])
B = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]])
game = nash.Game(A, B)
iterations = 10000
np.random.seed(0)
play_counts = tuple(game.fictitious_play(iterations=iterations))
plt.figure()
probabilities = [
row_play_counts / np.sum(row_play_counts)
for row_play_counts, col_play_counts in play_counts
]
for number, strategy in enumerate(zip(*probabilities)):
plt.plot(strategy, label=f"$s_{number}$")
plt.xlabel("Iteration")
plt.ylabel("Probability")
plt.legend()
if self.config.nash_method == 'support':
try:
u = next(nash.Game(payoffa, payoffb).support_enumeration())
except(StopIteration):
print("Nashpy 'support' iteration failed. Using 1,0,0...")
u = [list(np.zeros(len(self.sds))), list(np.zeros(len(self.sgs)))]
u[0][0]=1.
u[1][0]=1.
elif self.config.nash_method == 'lemke':
u = next(nash.Game(payoffa, payoffb).lemke_howson_enumeration())
else:
try:
u = next(nash.Game(payoffa, payoffb).vertex_enumeration())
except(StopIteration, scipy.spatial.qhull.QhullError):
print("Nashpy 'vertex' iteration failed. Using 1,0,0...")
u = [list(np.zeros(len(self.sds))), list(np.zeros(len(self.sgs)))]
u[0][0]=1.
u[1][0]=1.
if len(u[0]) != len(self.sgs):
return [None,None,None,None]
p1, p1result = _update_g(u[0])
p2, p2result = _update_d(u[1])
return p1, p1result, p2, p2result