Skip to content

Commit 9bd154f

Browse files
Add shell infrastructure for Herings-Peeters (2001) solver (#967)
1 parent 1f6b4a1 commit 9bd154f

8 files changed

Lines changed: 123 additions & 1 deletion

File tree

Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ gtracer_SOURCES = \
313313
src/solvers/gtracer/gnm.cc \
314314
src/solvers/gtracer/ipa.cc
315315

316+
hp_SOURCES = \
317+
src/solvers/hp/hp.h \
318+
src/solvers/hp/hp.cc
319+
316320
if IS_WIN32
317321
AM_LDFLAGS = -static -static-libgcc -static-libstdc++
318322
endif

doc/references.bib

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ @article{GovWil04
3838
category = {articles_equilibria}
3939
}
4040

41+
@article{HerPee01,
42+
author = {Herings, P. J.-J. and Peeters, R. J. A. P.},
43+
title = {A differentiable homotopy to compute {N}ash equilibria of n-person games},
44+
journal = {Economic Theory},
45+
volume = {18},
46+
pages = {159--185},
47+
year = {2001},
48+
category = {articles_equilibria}
49+
}
50+
4151
@article{HalPas21,
4252
author = {Halpern, J. Y. and Pass, R.},
4353
title = {Sequential equilibrium in games of imperfect recall},

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def run(self) -> None:
100100
cppgambit_gtracer = solver_library_config("cppgambit_gtracer", ["gtracer", "ipa", "gnm"])
101101
cppgambit_simpdiv = solver_library_config("cppgambit_simpdiv", ["simpdiv"])
102102
cppgambit_enumpoly = solver_library_config("cppgambit_enumpoly", ["nashsupport", "enumpoly"])
103+
cppgambit_hp = solver_library_config("cppgambit_hp", ["hp"])
103104

104105

105106
libgambit = setuptools.Extension(
@@ -117,7 +118,7 @@ def run(self) -> None:
117118
setuptools.setup(
118119
cmdclass={"build_py": GambitBuildPy},
119120
libraries=[cppgambit_bimatrix, cppgambit_liap, cppgambit_logit, cppgambit_simpdiv,
120-
cppgambit_gtracer, cppgambit_enumpoly,
121+
cppgambit_gtracer, cppgambit_enumpoly, cppgambit_hp,
121122
cppgambit_games, cppgambit_core],
122123
ext_modules=Cython.Build.cythonize(libgambit,
123124
language_level="3str",

src/pygambit/gambit.pxd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ cdef extern from "solvers/logit/logit.h":
621621
double getitem "operator[]"(int) except +IndexError
622622

623623

624+
cdef extern from "solvers/hp/hp.h":
625+
stdlist[c_MixedStrategyProfile[double]] HPStrategySolve(c_Game) except +RuntimeError
626+
627+
624628
cdef extern from "nash.h":
625629
stdlist[c_MixedBehaviorProfile[double]] LogitBehaviorSolveWrapper(
626630
c_Game, double, double, double

src/pygambit/nash.pxi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,7 @@ def _logit_behavior_branch(game: Game,
368368
p.thisptr = profile_ptr
369369
ret.append(p)
370370
return ret
371+
372+
373+
def _hp_strategy_solve(game: Game) -> list[MixedStrategyProfileDouble]:
374+
return _convert_mspd(HPStrategySolve(game.game))

src/pygambit/nash.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,3 +804,32 @@ def logit_solve(
804804
equilibria=equilibria,
805805
parameters={"first_step": first_step, "max_accel": max_accel},
806806
)
807+
808+
809+
def hp_solve(
810+
game: libgbt.Game,
811+
) -> NashComputationResult:
812+
"""Compute Nash equilibria of a game using :cite:p:`HerPee01`
813+
814+
Returns an approximation to the limiting point on the principal branch of
815+
the homotopy path for the game.
816+
817+
Parameters
818+
----------
819+
game : Game
820+
The game to compute equilibria in.
821+
822+
Returns
823+
-------
824+
res : NashComputationResult
825+
The result represented as a ``NashComputationResult`` object.
826+
"""
827+
equilibria = libgbt._hp_strategy_solve(game)
828+
return NashComputationResult(
829+
game=game,
830+
method="hp",
831+
rational=False,
832+
use_strategic=True,
833+
equilibria=equilibria,
834+
parameters={},
835+
)

src/solvers/hp/hp.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// This file is part of Gambit
3+
// Copyright (c) 1994-2026, The Gambit Project (https://www.gambit-project.org)
4+
//
5+
// FILE: src/solvers/hp/hp.cc
6+
// Computation of a Nash equilibria using a differentiable homotopy
7+
//
8+
// This program is free software; you can redistribute it and/or modify
9+
// it under the terms of the GNU General Public License as published by
10+
// the Free Software Foundation; either version 2 of the License, or
11+
// (at your option) any later version.
12+
//
13+
// This program is distributed in the hope that it will be useful,
14+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
// GNU General Public License for more details.
17+
//
18+
// You should have received a copy of the GNU General Public License
19+
// along with this program; if not, write to the Free Software
20+
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21+
//
22+
23+
#include <iostream>
24+
#include "gambit.h"
25+
#include "solvers/hp/hp.h"
26+
27+
namespace Gambit {
28+
std::list<MixedStrategyProfile<double>> HPStrategySolve(const Game &p_game)
29+
{
30+
std::list<MixedStrategyProfile<double>> result;
31+
const StrategySupportProfile support(p_game);
32+
33+
const MixedStrategyProfile<double> trivial_profile = support.NewMixedStrategyProfile<double>();
34+
35+
result.push_back(trivial_profile);
36+
return result;
37+
}
38+
} // namespace Gambit

src/solvers/hp/hp.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// This file is part of Gambit
3+
// Copyright (c) 1994-2026, The Gambit Project (http://www.gambit-project.org)
4+
//
5+
// FILE: src/solvers/hp/hp.h
6+
// Computation of a Nash equilibria using a differentiable homotopy
7+
//
8+
// This program is free software; you can redistribute it and/or modify
9+
// it under the terms of the GNU General Public License as published by
10+
// the Free Software Foundation; either version 2 of the License, or
11+
// (at your option) any later version.
12+
//
13+
// This program is distributed in the hope that it will be useful,
14+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
// GNU General Public License for more details.
17+
//
18+
// You should have received a copy of the GNU General Public License
19+
// along with this program; if not, write to the Free Software
20+
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21+
//
22+
23+
#ifndef HP_H
24+
#define HP_H
25+
26+
#include <list>
27+
28+
namespace Gambit {
29+
std::list<MixedStrategyProfile<double>> HPStrategySolve(const Game &p_game);
30+
} // namespace Gambit
31+
32+
#endif // HP_H

0 commit comments

Comments
 (0)