Skip to content

Commit eef30ce

Browse files
committed
test_nash_strategy_solver_w_start for simpdiv and liap in mixed strategies
1 parent 8035a6a commit eef30ce

File tree

2 files changed

+84
-23
lines changed

2 files changed

+84
-23
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ markers = [
8787
"nash_logit_behavior: tests of logit_solve in behavior strategies",
8888
"nash_gnm_strategy: tests of gnm_solve in mixed strategies",
8989
"nash_ipa_strategy: tests of lpa_solve in mixed strategies",
90+
"nash_simpdiv: tests of simpdiv_solve (in mixed strategies)",
9091
"qre_logit: tests of logit_solve and related methods",
9192
"qre_logit_lambda: tests of logit_solve_lambda",
9293
"qre_logit_branch: tests of logit_solve_branch",

tests/test_nash.py

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ class EquilibriumTestCase:
4242
prob_tol: float | gbt.Rational = Q(0)
4343

4444

45+
@dataclasses.dataclass
46+
class EquilibriumTestCaseWithStart:
47+
"""Summarising the data relevant for a test fixture of a call to an equilibrium solver
48+
that needs a starting profile."""
49+
50+
factory: typing.Callable[[], gbt.Game]
51+
solver: typing.Callable[[gbt.Game], gbt.nash.NashComputationResult]
52+
start_data: None | list
53+
expected: list
54+
regret_tol: float | gbt.Rational = Q(0)
55+
prob_tol: float | gbt.Rational = Q(0)
56+
57+
4558
@dataclasses.dataclass
4659
class QREquilibriumTestCase:
4760
"""Summarising the data relevant for a test fixture of a call to an QRE solver."""
@@ -831,6 +844,76 @@ def test_nash_strategy_solver(test_case: EquilibriumTestCase, subtests) -> None:
831844
assert abs(eq[strategy] - expected[strategy]) <= test_case.prob_tol
832845

833846

847+
##################################################################################################
848+
# NASH SOLVERS WITH START PROFILES
849+
##################################################################################################
850+
851+
LIAP_STRATEGY_CASES = [
852+
pytest.param(
853+
EquilibriumTestCaseWithStart(
854+
factory=functools.partial(games.read_from_file, "stripped_down_poker.efg"),
855+
solver=gbt.nash.liap_solve,
856+
start_data=dict(data=None, rational=False),
857+
expected=[],
858+
regret_tol=TOL_LARGE,
859+
prob_tol=TOL,
860+
),
861+
marks=pytest.mark.nash_simpdiv,
862+
id="test_simpdiv_1",
863+
),
864+
]
865+
866+
867+
SIMPDIV_CASES = [
868+
pytest.param(
869+
EquilibriumTestCaseWithStart(
870+
factory=functools.partial(games.read_from_file, "stripped_down_poker.efg"),
871+
solver=functools.partial(gbt.nash.simpdiv_solve),
872+
start_data=dict(data=None, rational=True),
873+
expected=[
874+
[
875+
d(Q(174763, 524288), Q(349525, 524288), 0, 0),
876+
d(Q(699051, 1048576), Q(349525, 1048576)),
877+
]
878+
],
879+
regret_tol=TOL_LARGE,
880+
prob_tol=TOL,
881+
),
882+
marks=pytest.mark.nash_simpdiv,
883+
id="test_simpdiv_1",
884+
),
885+
]
886+
887+
CASES = []
888+
CASES += LIAP_STRATEGY_CASES
889+
CASES += SIMPDIV_CASES
890+
891+
892+
@pytest.mark.nash
893+
@pytest.mark.parametrize("test_case", CASES, ids=lambda c: c.label)
894+
def test_nash_strategy_solver_w_start(test_case: EquilibriumTestCaseWithStart, subtests) -> None:
895+
"""Test calls of Nash solvers that start a starting profile.
896+
897+
Subtests:
898+
- Max regret no more than `test_case.regret_tol`
899+
- Equilibria are output in the expected order. Equilibria are deemed to match if the maximum
900+
difference in probabilities is no more than `test_case.prob_tol`
901+
"""
902+
game = test_case.factory()
903+
start = game.mixed_strategy_profile(**test_case.start_data)
904+
result = test_case.solver(start)
905+
with subtests.test("number of equilibria found"):
906+
assert len(result.equilibria) == len(test_case.expected)
907+
for i, (eq, exp) in enumerate(zip(result.equilibria, test_case.expected, strict=True)):
908+
with subtests.test(eq=i, check="max_regret"):
909+
assert eq.max_regret() <= test_case.regret_tol
910+
with subtests.test(eq=i, check="strategy_profile"):
911+
expected = game.mixed_strategy_profile(rational=True, data=exp)
912+
for player in game.players:
913+
for strategy in player.strategies:
914+
assert abs(eq[strategy] - expected[strategy]) <= test_case.prob_tol
915+
916+
834917
##################################################################################################
835918
# NASH SOLVER IN MIXED BEHAVIORS
836919
##################################################################################################
@@ -2375,8 +2458,6 @@ def test_nash_agent_solver(test_case: EquilibriumTestCase, subtests) -> None:
23752458

23762459
##################################################################################################
23772460
# TODO:
2378-
# The below all take a start argument that depends on the game, which doesn't immediately
2379-
# work with our current implementation of EquilibriumTestClass
23802461
##################################################################################################
23812462

23822463

@@ -2396,27 +2477,6 @@ def test_liap_agent():
23962477
assert abs(eq[action] - exp[action]) <= TOL_LARGE
23972478

23982479

2399-
def test_liap_strategy():
2400-
"""Test calls of liap for mixed strategy equilibria."""
2401-
game = games.read_from_file("stripped_down_poker.efg")
2402-
_ = gbt.nash.liap_solve(game.mixed_strategy_profile())
2403-
2404-
# NashComputationResult(method='liap', rational=False, use_strategic=True, equilibria=[],
2405-
# parameters={'start': [[0.25, 0.25, 0.25, 0.25], [0.5, 0.5]],
2406-
# 'maxregret': 0.0001, 'maxiter': 1000})
2407-
# Nothing found!
2408-
2409-
2410-
def test_simpdiv_strategy():
2411-
"""Test calls of simplicial subdivision for mixed strategy equilibria."""
2412-
game = games.read_from_file("stripped_down_poker.efg")
2413-
result = gbt.nash.simpdiv_solve(game.mixed_strategy_profile(rational=True))
2414-
assert len(result.equilibria) == 1
2415-
2416-
# [[[Rational(174763, 524288), Rational(349525, 524288), Rational(0, 1), Rational(0, 1)],
2417-
# [Rational(699051, 1048576), Rational(349525, 1048576)]]]
2418-
2419-
24202480
##################################################################################################
24212481
# QRE solvers
24222482
##################################################################################################

0 commit comments

Comments
 (0)