Skip to content

Commit

Permalink
[WIP] Implement GAMReader
Browse files Browse the repository at this point in the history
  • Loading branch information
oyamad committed Nov 27, 2024
1 parent 9b6cc51 commit bcf8bd3
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 31 deletions.
1 change: 1 addition & 0 deletions quantecon/game_theory/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
from .logitdyn import LogitDynamics
from .polymatrix_game import PolymatrixGame
from .howson_lcp import polym_lcp_solver
from .game_converters import GAMReader, qe_nfg_from_gam_file
149 changes: 118 additions & 31 deletions quantecon/game_theory/game_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,124 @@
[[-19., -19., 1.], [ -8., -8., 2.], [ 3., 3., 3.]]]]
"""
import numpy as np
from .normal_form_game import Player, NormalFormGame

from .normal_form_game import NormalFormGame
from itertools import product

def str2num(s):
if '.' in s:
return float(s)
return int(s)


class GAMReader:
"""
Reader object that converts a game in GameTracer gam format into
a NormalFormGame.
"""
@classmethod
def from_file(cls, file_path):
"""
Read from a gam format file.
Parameters
----------
file_path : str
Path to gam file.
Returns
-------
NormalFormGame
Examples
--------
Save a gam format string in a temporary file:
>>> import tempfile
>>> fname = tempfile.mkstemp()[1]
>>> with open(fname, mode='w') as f:
... f.write(\"\"\"\\
... 2
... 3 2
...
... 3 2 0 3 5 6 3 2 3 2 6 1\"\"\")
Read the file:
>>> g = GAMReader.from_file(fname)
>>> print(g)
2-player NormalFormGame with payoff profile array:
[[[3, 3], [3, 2]],
[[2, 2], [5, 6]],
[[0, 3], [6, 1]]]
"""
with open(file_path, 'r') as f:
string = f.read()
return cls.parse(string)

@classmethod
def from_url(cls, url):
"""
Read from a URL.
"""
import urllib.request
with urllib.request.urlopen(url) as response:
string = response.read().decode()
return cls.parse(string)

@classmethod
def from_string(cls, string):
"""
Read from a gam format string.
Parameters
----------
string : str
String in gam format.
Returns
-------
NormalFormGame
Examples
--------
>>> string = \"\"\"\\
... 2
... 3 2
...
... 3 2 0 3 5 6 3 2 3 2 6 1\"\"\"
>>> g = GAMReader.from_string(string)
>>> print(g)
2-player NormalFormGame with payoff profile array:
[[[3, 3], [3, 2]],
[[2, 2], [5, 6]],
[[0, 3], [6, 1]]]
"""
return cls.parse(string)

@staticmethod
def parse(string):
tokens = string.split()

N = int(tokens.pop(0))
nums_actions = tuple(int(tokens.pop(0)) for _ in range(N))
payoffs = np.array([str2num(s) for s in tokens])

na = np.prod(nums_actions)
payoffs2d = payoffs.reshape(N, na)
players = [
Player(
payoffs2d[i, :].reshape(nums_actions, order='F').transpose(
list(range(i, N)) + list(range(i))
)
) for i in range(N)
]

return NormalFormGame(players)


def qe_nfg_from_gam_file(filename: str) -> NormalFormGame:
Expand All @@ -51,32 +166,4 @@ def qe_nfg_from_gam_file(filename: str) -> NormalFormGame:
http://dags.stanford.edu/Games/gametracer.html
"""
with open(filename, 'r') as file:
lines = file.readlines()
combined = [
token
for line in lines
for token in line.split()
]

i = iter(combined)
players = int(next(i))
actions = [int(next(i)) for _ in range(players)]

nfg = NormalFormGame(actions)

entries = [
{
tuple(reversed(action_combination)): float(next(i))
for action_combination in product(
*[range(a) for a in actions])
}
for _ in range(players)
]

for action_combination in product(*[range(a) for a in actions]):
nfg[action_combination] = tuple(
entries[p][action_combination] for p in range(players)
)

return nfg
return GAMReader.from_file(filename)

0 comments on commit bcf8bd3

Please sign in to comment.