Skip to content
204 changes: 96 additions & 108 deletions src/lemke/bimatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,13 @@

import fractions
import random # random.seed
import sys
from functools import wraps

import click
import numpy as np

from . import columnprint, lemke, randomstart, utils


# for debugging
def printglobals():
globs = [x for x in globals() if "__" not in x]
for var in globs:
value = str(globals()[var])
if "<" not in value:
print(" " + str(var) + "=", value)


# file format:
# <m> <n>
# m*n entries of A, separated by blanks / newlines
Expand All @@ -27,87 +18,6 @@ def printglobals():

# defaults
# MAXDIM = 2000 # largest allowed value for m and n; not used yet
gamefilename = "game"
gz0 = False
LHstring = "" # empty means LH not called
seed = -1
trace = -1 # negative: no tracing
# accuracy = DEFAULT_accuracy = 1000
accuracy = 1000


# amends defaults
def processArguments():
global gamefilename, gz0, LHstring, seed, trace, accuracy
arglist = sys.argv[1:]
setLH = False
settrace = False
setaccuracy = False
setseed = False
setdecimals = False
showhelp = False
for s in arglist:
if s[0] == "-":
# discard optional argument-parameters
if setLH or settrace or setseed:
setLH = settrace = setseed = False
if s == "-LH":
setLH = True
LHstring = "1-"
elif s == "-trace":
settrace = True
trace = 0
elif s == "-seed":
setseed = True
seed = 0
elif s == "-accuracy":
setaccuracy = True
elif s == "-decimals":
setdecimals = True
elif s == "-z0":
gz0 = True
elif s == "-?" or s == "-help":
showhelp = True
else: # any other "-" argument
showhelp = True
print("! unknown option: ", repr(s))
else: # s not starting with "-"
if setLH:
setLH = False
LHstring = s
elif settrace:
settrace = False
trace = int(s)
elif setseed:
setseed = False
seed = int(s)
elif setdecimals:
setdecimals = False
utils.setdecimals(int(s))
elif setaccuracy:
setaccuracy = False
accuracy = int(s)
else:
gamefilename = s
if showhelp:
helpstring = (
"""usage: bimatrix.py [options]
options:
<filename> here: """
+ repr(gamefilename)
+ """, must not start with '-'
-LH [<range>] : Lemke-Howson with missing labels, e.g. '1,3-5,7-' ('' = all)
-trace [<num>]: tracing procedure, <num> no. of priors, 0 = centroid
-seed [<num>] : random seed, default: None
-accuracy <n> : accuracy prior, <n>=denominator, here """
+ str(accuracy)
+ """
-decimals <d> : allowed payoff digits in input after decimal point, default 4
-?, -help: show this help and exit"""
)
print(helpstring)
exit(0)
return


# list generated from string s such as "1-3,10,4-7", all not
Expand Down Expand Up @@ -257,8 +167,6 @@ def runLH(self, droppedlabel):
return tuple(getequil(tabl))

def LH(self, LHstring):
if LHstring == "":
return
m = self.A.numrows
n = self.A.numcolumns
lhset = {} # dict of equilibria and list by which label found
Expand All @@ -284,9 +192,9 @@ def runtrace(self, xprior, yprior):
tabl.runlemke()
return tuple(getequil(tabl))

def tracing(self, trace):
def tracing(self, trace, seed=None, accuracy=1000):
if trace < 0:
return
raise ValueError("Number of priors must be a positive integer")
Comment thread
rahulsavani marked this conversation as resolved.
Outdated
m = self.A.numrows
n = self.A.numcolumns
trset = {} # dict of equilibria, how often found
Expand All @@ -298,7 +206,7 @@ def tracing(self, trace):
trace = 1 # for percentage
else:
for k in range(trace):
if seed >= 0:
if seed is not None:
random.seed(10 * trace * seed + k)
x = randomstart.randInSimplex(m)
xprior = randomstart.roundArray(x, accuracy)
Expand Down Expand Up @@ -364,15 +272,95 @@ def submatrix(A, rowset, colset):
return B


@click.group(
context_settings={"help_option_names": ["-?", "-h", "--help"]},
)
def main():
processArguments()
printglobals()

G = bimatrix(gamefilename)
print(G)
G.LH(LHstring)
G.tracing(trace)


if __name__ == "__main__":
main()
"""Find Nash equilibria of a bimatrix game."""
Comment on lines +285 to +289
pass


def common_options(f):
@click.argument(
"filename",
type=click.Path(exists=True, readable=True, file_okay=True, dir_okay=False),
)
@click.option(
"--decimals",
default=4,
show_default=True,
help="Allowed payoff digits in input after decimal point",
)
# @click.option(
# "--z0",
# is_flag=True,
# help="Show value of z0 at each step",
# )
@wraps(f)
def wrapper(*args, decimals, **kwargs):
utils.setdecimals(decimals)
return f(*args, **kwargs)
return wrapper
Comment thread
rahulsavani marked this conversation as resolved.


@main.command()
@common_options
@click.option(
"--labels",
default="1-",
help="Missing labels, e.g. 1,3-5,7- "
"[default: all labels]",
)
def lh(filename, labels):
"""Find equilibria using the Lemke-Howson algorithm."""

# for debugging
print("filename:", filename)
print("labels:", labels)
print()

G = bimatrix(filename)
Comment thread
rahulsavani marked this conversation as resolved.
Outdated
G.LH(labels)


@main.command()
@common_options
@click.option(
"--priors",
type=click.IntRange(min=1),
help="Number of random priors",
)
@click.option(
"--seed",
type=int,
help="Random seed",
)
@click.option(
"--accuracy",
default=1000,
show_default=True,
help="Denominator x: each random prior is rounded to the nearest multiple of 1/x",
)
def trace(filename, priors, seed, accuracy):
"""
Find equilibria using the tracing procedure.

Without --priors, uses the centroid.
With --priors N, uses N random starting points.
"""

# for debugging
print("file:", filename)
print("priors:", priors)
print("seed:", seed)
print("accuracy:", accuracy)
print()

G = bimatrix(filename)

if priors is None:
if seed is not None or accuracy != 1000:
raise click.UsageError("--seed and --accuracy require --priors")
G.tracing(0)
else:
G.tracing(priors, seed, accuracy)
Comment thread
rahulsavani marked this conversation as resolved.
Outdated
Loading