Add tutorial: finding non-principal branches of the QRE correspondence - #1023
Open
darraghmoran2025 wants to merge 3 commits into
Open
Add tutorial: finding non-principal branches of the QRE correspondence#1023darraghmoran2025 wants to merge 3 commits into
darraghmoran2025 wants to merge 3 commits into
Conversation
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.
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 todoc/references.biband the notebook to the advanced-tutorials toctree indoc/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_branchstops 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 theincludelist atpyproject.toml:68. Happy to fix that in a separate PR if you'd like.