pynamo-egt 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynamo_egt-0.3.1/LICENSE +21 -0
- pynamo_egt-0.3.1/PKG-INFO +436 -0
- pynamo_egt-0.3.1/README.md +382 -0
- pynamo_egt-0.3.1/pynamo_egt/__init__.py +28 -0
- pynamo_egt-0.3.1/pynamo_egt/_one_dimensional.py +260 -0
- pynamo_egt-0.3.1/pynamo_egt/analysis.py +865 -0
- pynamo_egt-0.3.1/pynamo_egt/drawer.py +1868 -0
- pynamo_egt-0.3.1/pynamo_egt/dynamics.py +365 -0
- pynamo_egt-0.3.1/pynamo_egt/examples.py +506 -0
- pynamo_egt-0.3.1/pynamo_egt/export.py +493 -0
- pynamo_egt-0.3.1/pynamo_egt/game.py +417 -0
- pynamo_egt-0.3.1/pynamo_egt/interactive.py +686 -0
- pynamo_egt-0.3.1/pynamo_egt.egg-info/PKG-INFO +436 -0
- pynamo_egt-0.3.1/pynamo_egt.egg-info/SOURCES.txt +25 -0
- pynamo_egt-0.3.1/pynamo_egt.egg-info/dependency_links.txt +1 -0
- pynamo_egt-0.3.1/pynamo_egt.egg-info/requires.txt +14 -0
- pynamo_egt-0.3.1/pynamo_egt.egg-info/top_level.txt +1 -0
- pynamo_egt-0.3.1/pyproject.toml +50 -0
- pynamo_egt-0.3.1/setup.cfg +4 -0
- pynamo_egt-0.3.1/tests/test_analysis.py +110 -0
- pynamo_egt-0.3.1/tests/test_drawer.py +231 -0
- pynamo_egt-0.3.1/tests/test_dynamics.py +118 -0
- pynamo_egt-0.3.1/tests/test_export.py +84 -0
- pynamo_egt-0.3.1/tests/test_game.py +72 -0
- pynamo_egt-0.3.1/tests/test_one_dimensional.py +127 -0
- pynamo_egt-0.3.1/tests/test_package.py +27 -0
- pynamo_egt-0.3.1/tests/test_static_equilibria.py +86 -0
pynamo_egt-0.3.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pyNamo contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pynamo-egt
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: pyNamo-EGT: plotting and analysis tools for replicator dynamics in evolutionary games.
|
|
5
|
+
Author: Slimane Dridi, Benjamin Giraudon
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 pyNamo contributors
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Repository, https://github.com/SlimaneD/pynamo
|
|
29
|
+
Project-URL: Issues, https://github.com/SlimaneD/pynamo/issues
|
|
30
|
+
Classifier: Development Status :: 3 - Alpha
|
|
31
|
+
Classifier: Intended Audience :: Science/Research
|
|
32
|
+
Classifier: Intended Audience :: Education
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Topic :: Scientific/Engineering
|
|
37
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
38
|
+
Requires-Python: >=3.12
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
License-File: LICENSE
|
|
41
|
+
Requires-Dist: matplotlib
|
|
42
|
+
Requires-Dist: numpy
|
|
43
|
+
Requires-Dist: pandas
|
|
44
|
+
Requires-Dist: scipy
|
|
45
|
+
Requires-Dist: sympy
|
|
46
|
+
Provides-Extra: notebook
|
|
47
|
+
Requires-Dist: ipykernel; extra == "notebook"
|
|
48
|
+
Requires-Dist: ipympl; extra == "notebook"
|
|
49
|
+
Requires-Dist: ipywidgets; extra == "notebook"
|
|
50
|
+
Requires-Dist: jupyter; extra == "notebook"
|
|
51
|
+
Provides-Extra: dev
|
|
52
|
+
Requires-Dist: pytest; extra == "dev"
|
|
53
|
+
Dynamic: license-file
|
|
54
|
+
|
|
55
|
+
# pyNamo-EGT
|
|
56
|
+
|
|
57
|
+
[](https://mybinder.org/v2/gh/SlimaneD/pynamo/master?filepath=tutorial.ipynb)
|
|
58
|
+
[](https://colab.research.google.com/github/SlimaneD/pynamo/blob/master/tutorial_colab.ipynb)
|
|
59
|
+
|
|
60
|
+
pyNamo-EGT is a Python package for plotting and analyzing replicator dynamics
|
|
61
|
+
in evolutionary games. It focuses on game classes whose state spaces can be
|
|
62
|
+
visualized directly, producing phase portraits on simplices with trajectories,
|
|
63
|
+
speed fields, vector fields, equilibria, and stability information.
|
|
64
|
+
|
|
65
|
+
The package is designed for researchers, teachers, and students who want clear,
|
|
66
|
+
publication-quality diagrams of theoretical phase portraits. Its high-level
|
|
67
|
+
interface is built for Jupyter notebooks and produces informative figures with
|
|
68
|
+
minimal code, while still exposing fine-grained controls for plotting details.
|
|
69
|
+
|
|
70
|
+
## Start Here
|
|
71
|
+
|
|
72
|
+
There are three main ways to try pyNamo-EGT.
|
|
73
|
+
|
|
74
|
+
**1. Full interactive tutorial in Binder**
|
|
75
|
+
|
|
76
|
+
Use Binder if you want the closest experience to a local Jupyter notebook,
|
|
77
|
+
including the interactive widget and rotatable 3D Matplotlib figures:
|
|
78
|
+
|
|
79
|
+
[Launch the Binder tutorial](https://mybinder.org/v2/gh/SlimaneD/pynamo/master?filepath=tutorial.ipynb)
|
|
80
|
+
|
|
81
|
+
Binder runs in the browser and does not require a local installation. First launch
|
|
82
|
+
can take a few minutes while Binder builds the environment.
|
|
83
|
+
|
|
84
|
+
Interactive 3D plots may occasionally appear blank in Binder. Try rerunning the
|
|
85
|
+
plotting cell. If the issue persists, replace `%matplotlib widget` with
|
|
86
|
+
`%matplotlib inline` in that plotting cell for a static preview without rotation.
|
|
87
|
+
SVG/PDF export quality is unaffected.
|
|
88
|
+
|
|
89
|
+
**2. Faster static tutorial in Google Colab**
|
|
90
|
+
|
|
91
|
+
Use Colab if you want a faster browser-based preview of the tutorial:
|
|
92
|
+
|
|
93
|
+
[Open the Colab tutorial](https://colab.research.google.com/github/SlimaneD/pynamo/blob/master/tutorial_colab.ipynb)
|
|
94
|
+
|
|
95
|
+
The Colab notebook supports ordinary plotting cells, but not the interactive
|
|
96
|
+
widget or rotatable 3D Matplotlib figures.
|
|
97
|
+
|
|
98
|
+
**3. Local installation from GitHub**
|
|
99
|
+
|
|
100
|
+
Use a local installation if you want to use pyNamo-EGT in your own notebooks or
|
|
101
|
+
modify the code:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/SlimaneD/pynamo.git
|
|
105
|
+
cd pynamo
|
|
106
|
+
pip install ".[notebook]"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Features
|
|
110
|
+
|
|
111
|
+
- One-population symmetric 2×2 phase lines and one-parameter bifurcation diagrams, with customizable phase-line labels and curve styles.
|
|
112
|
+
- Replicator dynamics for asymmetric 2-player / 2-strategy games (`2Pop2S`), symmetric 2-player / 3-strategy games (`1Pop3S`), symmetric 2-player / 4-strategy games (`1Pop4S`), and asymmetric 3-player / 2-strategy games (`3Pop2S`).
|
|
113
|
+
- A curated catalogue of built-in example games with descriptions, references, parameter notes, and explanations of what each example illustrates.
|
|
114
|
+
- Matplotlib phase portraits with trajectories, equilibria, speed fields, vector fields, and optional colored faces for 3D state spaces.
|
|
115
|
+
- Reproducible grid-based default trajectories, with automatic one-dimensional flow arrows on triangle and square boundaries.
|
|
116
|
+
- Equilibrium analysis with linear stability classification, Nash equilibria, strict Nash equilibria, and ESS checks where applicable.
|
|
117
|
+
- A Jupyter widget for quick exploration of built-in example games.
|
|
118
|
+
|
|
119
|
+
## Requirements
|
|
120
|
+
|
|
121
|
+
- Python 3.12+
|
|
122
|
+
- `numpy`, `scipy`, `matplotlib`, `sympy`, `pandas`
|
|
123
|
+
- Optional for notebooks/widgets: `jupyter`, `ipykernel`, `ipywidgets`, `ipympl`
|
|
124
|
+
|
|
125
|
+
Install dependencies in a virtual environment:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
python -m venv .venv
|
|
129
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
130
|
+
pip install numpy scipy matplotlib sympy pandas ipywidgets ipympl
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Installation
|
|
134
|
+
|
|
135
|
+
pyNamo-EGT is currently distributed from GitHub. For ordinary notebook use, install with:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pip install ".[notebook]"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For core functionality only, without notebook/widget dependencies:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pip install .
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For development tests:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install ".[dev]"
|
|
151
|
+
python -m pytest -q
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## First use
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
import matplotlib.pyplot as plt
|
|
158
|
+
|
|
159
|
+
import pynamo_egt as pn
|
|
160
|
+
|
|
161
|
+
fig, ax = pn.phase_portrait(pn.examples.games.good_rps)
|
|
162
|
+
plt.show()
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`pn.phase_portrait` returns ordinary Matplotlib objects, so figures can be
|
|
166
|
+
modified or saved with standard Matplotlib commands:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
fig.savefig("good_rps.svg", bbox_inches="tight")
|
|
170
|
+
fig.savefig("good_rps.pdf", bbox_inches="tight")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Built-In Examples
|
|
174
|
+
|
|
175
|
+
Built-in games are available through `pn.examples.games`:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
g = pn.examples.games.battle_of_the_sexes
|
|
179
|
+
same_game = pn.examples.games("battle_of_the_sexes")
|
|
180
|
+
pn.examples.games.by_class("2Pop2S")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Each catalogue game carries metadata:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
g = pn.examples.games.chaotic_four_strategy_game
|
|
187
|
+
g.describe()
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
You can also use the module-level helper:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
pn.examples.describe(g)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The metadata include the game description, reference, parameter values, and the
|
|
197
|
+
main mathematical point illustrated by the example.
|
|
198
|
+
|
|
199
|
+
## Game Classes
|
|
200
|
+
|
|
201
|
+
Game-class identifiers use population counts (`Pop`) and strategies per population
|
|
202
|
+
(`S`), rather than the number of players in an interaction. A symmetric two-player
|
|
203
|
+
interaction can be modeled in one population or in two separate populations.
|
|
204
|
+
|
|
205
|
+
pyNamo currently supports five game classes:
|
|
206
|
+
|
|
207
|
+
- `1Pop2S`: symmetric 2-player / 2-strategy games in one population, represented by one `2 x 2` payoff matrix.
|
|
208
|
+
- `2Pop2S`: 2-player / 2-strategy games, represented by one payoff matrix per player. In each matrix, rows are that player's own strategies and columns are the opponent's strategies.
|
|
209
|
+
- `1Pop3S`: symmetric 2-player / 3-strategy games, represented by one `3 x 3` payoff matrix.
|
|
210
|
+
- `1Pop4S`: symmetric 2-player / 4-strategy games, represented by one `4 x 4` payoff matrix.
|
|
211
|
+
- `3Pop2S`: 3-player / 2-strategy games, represented by one `2 x 2 x 2` payoff tensor per player.
|
|
212
|
+
|
|
213
|
+
For asymmetric 2-strategy games, each coordinate in a reduced state is the
|
|
214
|
+
probability that the corresponding player uses their first listed strategy.
|
|
215
|
+
|
|
216
|
+
For symmetric 3-strategy games, initial conditions use two coordinates and the
|
|
217
|
+
third strategy frequency is inferred. For symmetric 4-strategy games, initial
|
|
218
|
+
conditions use three coordinates and the fourth strategy frequency is inferred.
|
|
219
|
+
|
|
220
|
+
## Defining Games
|
|
221
|
+
|
|
222
|
+
A symmetric 3-strategy game:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
import numpy as np
|
|
226
|
+
import pynamo_egt as pn
|
|
227
|
+
my_game = pn.Game(
|
|
228
|
+
name="My RPS Variant",
|
|
229
|
+
payoffs=np.array([
|
|
230
|
+
[0, -1, 2],
|
|
231
|
+
[2, 0, -1],
|
|
232
|
+
[-1, 2, 0],
|
|
233
|
+
], dtype=float),
|
|
234
|
+
strategy_labels=["R", "P", "S"],
|
|
235
|
+
)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
An asymmetric 2-player / 2-strategy game:
|
|
239
|
+
|
|
240
|
+
Each payoff matrix uses its recipient as the focal player. The first matrix has
|
|
241
|
+
player 1's strategies as rows and player 2's as columns; the second has player
|
|
242
|
+
2's strategies as rows and player 1's as columns.
|
|
243
|
+
|
|
244
|
+
```python
|
|
245
|
+
my_asymmetric_game = pn.Game(
|
|
246
|
+
name="My Asymmetric Game",
|
|
247
|
+
payoffs=(
|
|
248
|
+
# Player 1 rows; player 2 columns.
|
|
249
|
+
np.array([[3, 0], [1, 2]], dtype=float),
|
|
250
|
+
# Player 2 rows; player 1 columns.
|
|
251
|
+
np.array([[2, 1], [0, 3]], dtype=float),
|
|
252
|
+
),
|
|
253
|
+
player_strategy_labels=[["A", "B"], ["C", "D"]],
|
|
254
|
+
player_labels=["Player 1", "Player 2"],
|
|
255
|
+
symmetric=False,
|
|
256
|
+
)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Plot Customization
|
|
260
|
+
|
|
261
|
+
Most common plotting options are parameters of `pn.phase_portrait`:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
fig, ax = pn.phase_portrait(
|
|
265
|
+
pn.examples.games.matching_pennies,
|
|
266
|
+
starts=[[0.2, 0.7], [0.7, 0.5], [0.9, 0.9]],
|
|
267
|
+
tmax=40,
|
|
268
|
+
speed_cmap=plt.cm.cividis,
|
|
269
|
+
speed_levels=20,
|
|
270
|
+
show_vector_field=True,
|
|
271
|
+
vector_grid=18,
|
|
272
|
+
trajectory_color="black",
|
|
273
|
+
trajectory_linewidth=1.2,
|
|
274
|
+
trajectory_arrows=[0.001],
|
|
275
|
+
)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
When `starts` is omitted, pyNamo uses deterministically spaced starts. For `1Pop3S` and
|
|
279
|
+
`2Pop2S`, it also treats every invariant edge as a one-dimensional phase line
|
|
280
|
+
and places arrows halfway between consecutive edge equilibria. Control the exact
|
|
281
|
+
number of generated trajectories with `trajectory_number`; explicit `starts` override it. Use
|
|
282
|
+
`show_edge_flow=True` to combine explicit starts with boundary flow, or
|
|
283
|
+
`show_edge_flow=False` to hide boundary flow. Boundary-arrow positions are
|
|
284
|
+
determined by edge equilibria rather than the time-based `trajectory_arrows`
|
|
285
|
+
values; `trajectory_arrows=[]` hides all arrowheads.
|
|
286
|
+
|
|
287
|
+
Use one color per trajectory by passing a list:
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
fig, ax = pn.phase_portrait(
|
|
291
|
+
pn.examples.games.cyclic_mismatching_pennies,
|
|
292
|
+
starts=[[0.52, 0.50, 0.48], [0.70, 0.45, 0.35]],
|
|
293
|
+
trajectory_color=["tab:blue", "tab:orange"],
|
|
294
|
+
trajectory_arrows=[],
|
|
295
|
+
tmax=1000,
|
|
296
|
+
)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Colored faces are available for 3D state spaces:
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
fig, ax = pn.phase_portrait(
|
|
303
|
+
pn.examples.games.ownership_game,
|
|
304
|
+
show_faces=True,
|
|
305
|
+
face_alpha=0.15,
|
|
306
|
+
)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Vector fields are available for both 2D and 3D game classes. Sparse 3D vector
|
|
310
|
+
fields can be useful for exploration, but trajectories are usually clearer in
|
|
311
|
+
static publication figures.
|
|
312
|
+
|
|
313
|
+
Labels are Matplotlib text labels and can include simple LaTeX-style math
|
|
314
|
+
notation such as `"$S_1$"` or `"$x = P(A)$"`. pyNamo-EGT does not require a
|
|
315
|
+
full LaTeX installation by default; users who want full LaTeX rendering can
|
|
316
|
+
enable Matplotlib's `text.usetex` option manually.
|
|
317
|
+
|
|
318
|
+
For the full parameter documentation:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
help(pn.phase_portrait)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Equilibrium Analysis
|
|
325
|
+
|
|
326
|
+
For notebooks, use `pn.equilibrium_table`:
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
import pynamo_egt as pn
|
|
330
|
+
|
|
331
|
+
pn.equilibrium_table(pn.examples.games.good_rps)
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
For programmatic use:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
result = pn.analyze_equilibria(pn.examples.games.good_rps)
|
|
338
|
+
rows = result.to_rows()
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
For quick access to static equilibrium concepts:
|
|
342
|
+
|
|
343
|
+
```python
|
|
344
|
+
pn.rest_points_nash(game=pn.examples.games.good_rps)
|
|
345
|
+
pn.rest_points_strict_nash(game=pn.examples.games.good_rps)
|
|
346
|
+
pn.rest_points_ess(game=pn.examples.games.good_rps)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
These helpers filter the replicator rest points detected by pyNamo; they do not
|
|
350
|
+
claim to enumerate additional or non-isolated Nash-equilibrium families.
|
|
351
|
+
`rest_points_ess` returns ESS only for symmetric games.
|
|
352
|
+
|
|
353
|
+
## Stability Caveats
|
|
354
|
+
|
|
355
|
+
Stability is classified from the linearization restricted to admissible directions
|
|
356
|
+
in the state space. This is important at boundaries because outward perturbations
|
|
357
|
+
are not valid evolutionary deviations.
|
|
358
|
+
|
|
359
|
+
Some equilibria are non-hyperbolic or belong to degenerate equilibrium sets. In
|
|
360
|
+
these cases pyNamo emits warnings rather than forcing a classification. For higher-dimensional games, non-isolated
|
|
361
|
+
equilibrium manifolds are not plotted automatically; isolated equilibria are still
|
|
362
|
+
shown when they can be identified.
|
|
363
|
+
|
|
364
|
+
The category `unstable` means that linearization proves the equilibrium is not
|
|
365
|
+
stable, but does not always distinguish source from saddle. In plots, unstable
|
|
366
|
+
equilibria are drawn with the source color for visual compatibility.
|
|
367
|
+
|
|
368
|
+
## Interactive Widget
|
|
369
|
+
|
|
370
|
+
In a notebook, use:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
%matplotlib widget
|
|
374
|
+
|
|
375
|
+
import pynamo_egt as pn
|
|
376
|
+
pn.interactive.launch_replicator_widget()
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The widget lets users choose a game class and example, adjust trajectories, toggle
|
|
380
|
+
speed/vector fields, and inspect payoff data and equilibrium analysis.
|
|
381
|
+
|
|
382
|
+
If 3D rotation does not work, make sure the notebook kernel has `ipympl` installed
|
|
383
|
+
and that `%matplotlib widget` has been evaluated.
|
|
384
|
+
|
|
385
|
+
## Repository Structure
|
|
386
|
+
|
|
387
|
+
- `pynamo_egt/game.py`: core `Game` class and game-class inference.
|
|
388
|
+
- `pynamo_egt/examples.py`: curated catalogue of predefined games.
|
|
389
|
+
- `pynamo_egt/dynamics.py`: replicator vector fields and rest-point computation.
|
|
390
|
+
- `pynamo_egt/analysis.py`: equilibrium and stability analysis.
|
|
391
|
+
- `pynamo_egt/drawer.py`: plotting helpers and `phase_portrait`.
|
|
392
|
+
- `pynamo_egt/interactive.py`: Jupyter widget front-end.
|
|
393
|
+
- `tutorial.ipynb`: notebook tutorial.
|
|
394
|
+
- `tests/`: pytest test suite.
|
|
395
|
+
|
|
396
|
+
## One-population phase lines and bifurcation diagrams
|
|
397
|
+
|
|
398
|
+
```python
|
|
399
|
+
coordination = pn.Game("Coordination", [[1, 0], [0, 1]], strategy_labels=["A", "B"])
|
|
400
|
+
fig, ax = pn.phase_portrait(coordination, figsize=(8, 2.2))
|
|
401
|
+
|
|
402
|
+
fig, ax = pn.bifurcation_diagram(
|
|
403
|
+
lambda s: [[s, 0], [1, 2]],
|
|
404
|
+
parameter_range=(-1, 4),
|
|
405
|
+
parameter_values=[1],
|
|
406
|
+
phase_line_values=[0, 2, 3],
|
|
407
|
+
phase_line_labels=["I", "II", "II"],
|
|
408
|
+
stable_linestyle="-", unstable_linestyle="--",
|
|
409
|
+
)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
For phase lines, x is the first strategy's frequency. `trajectory_arrows=None`
|
|
413
|
+
centers one head between equilibria; explicit values are frequencies, and `[]`
|
|
414
|
+
hides heads. Marker styling follows the existing API. `continuum_color` styles
|
|
415
|
+
an entire stationary interval. Non-hyperbolic isolated points are classified
|
|
416
|
+
from one-sided flow without special markers or warnings.
|
|
417
|
+
|
|
418
|
+
Bifurcation diagrams sample a payoff-matrix function; they do not guarantee
|
|
419
|
+
exhaustive bifurcation detection. See the two introductory tutorial sections
|
|
420
|
+
and `help(pn.bifurcation_diagram)` for styling and parameter controls.
|
|
421
|
+
|
|
422
|
+
## Possible future directions
|
|
423
|
+
|
|
424
|
+
pyNamo focuses on analytical models whose state spaces can be visualized.
|
|
425
|
+
Natural extensions include:
|
|
426
|
+
|
|
427
|
+
- **More evolutionary dynamics and learning rules.** Refactor `dynamics.py`
|
|
428
|
+
around updating-rule objects, allowing each population or player to have its
|
|
429
|
+
own rule. Candidate additions include logit dynamics, best-response dynamics,
|
|
430
|
+
and differential equations for reinforcement learning and stochastic
|
|
431
|
+
fictitious play.
|
|
432
|
+
- **Nonlinear frequency-dependent fitness.** Accept user-defined fitness
|
|
433
|
+
functions $f_i(x)$ in addition to payoff matrices.
|
|
434
|
+
- **Equilibrium manifolds.** Detect continua of rest points, analyze their
|
|
435
|
+
stability, and plot them automatically when the result can be established
|
|
436
|
+
reliably. Report inconclusive cases explicitly.
|