Skip to content

Add tutorial: finding non-principal branches of the QRE correspondence - #1023

Open
darraghmoran2025 wants to merge 3 commits into
gambitproject:masterfrom
darraghmoran2025:qre-approx-simulation-notebook
Open

Add tutorial: finding non-principal branches of the QRE correspondence#1023
darraghmoran2025 wants to merge 3 commits into
gambitproject:masterfrom
darraghmoran2025:qre-approx-simulation-notebook

Conversation

@darraghmoran2025

Copy link
Copy Markdown

This PR adds an advanced tutorial notebook, doc/tutorials/advanced_tutorials/quantal_response_branches.ipynb, on the simulation method of Bland (2024, SSRN 4774850) for finding branches of the logit QRE correspondence that path-following from the centroid can't reach. I've added the reference to doc/references.bib and the notebook to the advanced-tutorials toctree in doc/pygambit.rst.

The notebook works through two examples. The first is a 2x2 stag hunt: the principal branch converges to the risk-dominant equilibrium, and sampling from Bland's penalty density turns up the second branch, whose two sides converge to the payoff-dominant and mixed equilibria. Draws get polished with Newton iteration, then the branch is traced by warm-started continuation in lambda up to the fold.

The second example is the three-player 2x2x2 game of McKelvey-McLennan (1997) (doc/2x2x2.nfg, the same game the starting-points tutorial uses; nine Nash equilibria, two of them totally mixed). This one is more interesting: logit_solve_branch stops at a bifurcation around lambda = 0.597, where max regret at the returned point is still 0.213. The notebook shows what's going on directly: the principal branch has a closed form past the stopping point, and a second branch crosses it there. Sampling plus seeding at a few values of lambda finds 22 distinct LQRE, and following their branches upward reaches all nine equilibria, including both totally mixed ones.

For the lambda-elimination and the penalty I followed the author's own implementation in the online appendix (https://github.com/JamesBlandEcon/ApproxQRE). The sampler is a plain random-walk Metropolis rather than HMC so the notebook stays self-contained; the Remarks section points to HMC for larger games.

All cell outputs are computed. The notebook executes in about 25 seconds and runs under pytest tests/test_tutorials.py --run-tutorials. One thing I noticed along the way: ruff doesn't currently lint the notebooks at all, because of a quoting typo in the include list at pyproject.toml:68. Happy to fix that in a separate PR if you'd like.

Working paper SSRN 4774850, cited by the new tutorial on finding
non-principal branches of the QRE correspondence.
Illustrates the simulation-based method of Bland (2024, SSRN 4774850)
on a stag hunt: sample profiles from a penalty density concentrated on
the graph of the logit QRE correspondence (with lambda eliminated in
closed form), polish draws with Newton iteration, and trace the
non-principal branch by warm-started continuation in lambda, up to the
fold. Uses pygambit for game representation and expected payoffs.

All cell outputs are computed; the notebook executes in ~10 seconds
and is exercised by pytest --run-tutorials.
Adds a section applying the sampling method to the 2x2x2 McKelvey-McLennan
game distributed with Gambit, which has nine Nash equilibria including two
totally mixed ones.

The helper functions from the stag hunt section are already dimension-agnostic,
so they apply unchanged; the sampling loop is factored into `sample_locus` so
that it is reused rather than repeated. The 2x2 results are unaffected: the
sampling cell still reports the same 15790 of 18000 draws on the locus.

The example also documents a case where the principal branch is of no help at
all. `logit_solve_branch` stops after 17 points at lambda = 0.5968 with a max
regret of 0.21, which is a bifurcation rather than convergence. The branch has
a closed form here, since players 1 and 2 are each indifferent whenever the
other randomises uniformly, and it satisfies the logit conditions to machine
precision well past where the trace stops; a second branch is shown crossing
it at that lambda.

Branches continued from sampled seeds reach all nine equilibria, including
both totally mixed ones. The notebook executes in about 25 s, within the
timeout used by tests/test_tutorials.py.
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant