Skip to content

Commit

Permalink
Resolve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
d-kad committed Jul 20, 2024
1 parent ae01060 commit 4c0b3fb
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 26 deletions.
39 changes: 20 additions & 19 deletions src/pygambit/game.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ class Game:
See Also
--------
from_dict : Create strategic game and set player labels
to_array: Generate the payoff tables for players represented as numpy arrays
"""
g = cython.declare(Game)
arrays = [np.array(a) for a in arrays]
Expand All @@ -336,36 +337,36 @@ class Game:
g.title = title
return g

def to_arrays(self) -> typing.List[np.array]:
"""Reverse function to from_arrays:
def to_arrays(self, dtype: typing.Type = Rational) -> typing.List[np.array]:
"""Generate the payoff tables for players represented as numpy arrays.

To_arrays, for a given game, generates players’ payoff tables represented as numpy arrays.
The number of produced arrays is equal to the number of players.
Parameters
----------
dtype : type
The type to which payoff values will be converted and
the resulting arrays will be of that dtype

Returns
-------
list of np.arrays
list of np.array

Raises
------
UndefinedOperationError
If the game does not have a tree representation.
See Also
--------
from_arrays : Create game from list-like of array-like
"""
arrays = []

if self.is_tree:
raise UndefinedOperationError(
"Operation only defined for games with a strategic representation"
)

if len(self.players) == 0:
raise RuntimeError("There are no players in the game")

shape = tuple(len(player.strategies) for player in self.players)
for player in self.players:
array = np.zeros(shape=shape)
array = np.zeros(shape=shape, dtype=object)
for profile in itertools.product(*(range(s) for s in shape)):
array[profile] = self[profile][player]
try:
array[profile] = dtype(self[profile][player])
except (ValueError, TypeError, IndexError, KeyError):
raise ValueError(
f"Payoff '{self[profile][player]}' cannot be \
converted to requested type '{dtype}'"
) from None
arrays.append(array)
return arrays

Expand Down
23 changes: 16 additions & 7 deletions tests/test_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,31 @@ def test_from_arrays():
assert len(game.players[1].strategies) == 2


def test_extensive_form_to_arrays():
game = gbt.Game.new_tree()
with pytest.raises(ValueError):
_ = game.to_arrays()


def test_empty_array_to_arrays():
game = gbt.Game.from_arrays([])
a = game.to_arrays()
assert len(a) == 1
assert (a[0] == np.array([])).all()


def test_different_num_representations_to_arrays():
def test_to_arrays_wrong_type():
m = np.array([[8, 2], [10, 5]])
game = gbt.Game.from_arrays(m, m.transpose())
with pytest.raises(ValueError):
_ = game.to_arrays(dtype=dict)


def test_different_num_representations_to_arrays_fraction():
game = gbt.Game.from_arrays([1, 2 / 1, "6/2", 0.25, ".99"])
A = game.to_arrays()[0]
correct_output = [gbt.Rational(1, 1), gbt.Rational(2, 1), gbt.Rational(3, 1),
gbt.Rational(1, 4), gbt.Rational(99, 100)]
assert (correct_output == A).all()


def test_different_num_representations_to_arrays_float():
game = gbt.Game.from_arrays([1, 2 / 1, "6/2", 0.25, ".99"])
A = game.to_arrays(dtype=float)[0]
correct_output = [1.0, 2.0, 3.0, 0.25, 0.99]
assert (correct_output == A).all()

Expand Down

0 comments on commit 4c0b3fb

Please sign in to comment.