
# EGTTools β Evolutionary Game Theory Toolbox
[](https://pypi.org/project/egttools/)
[](https://egttools.readthedocs.io/)
[](https://efernandez.eu/EGTTools/)
[](https://github.com/Socrats/EGTTools/actions/workflows/wheels.yml)
[](https://gitter.im/EGTTools/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[](https://mybinder.org/v2/gh/Socrats/EGTTools/HEAD?labpath=docs%2Fexamples)
[](https://zenodo.org/badge/latestdoi/242180332)
EGTTools is a modular toolbox for simulating and analyzing **evolutionary dynamics** in strategic environments. It
combines **analytical methods** (replicator dynamics, fixation probabilities) and **numerical simulations** (Monte Carlo
with parallel C++ backends) under a unified interface.
---
## π Table of Contents
Testing & Continuous Integration
- [Features](#-features)
- [Installation](#-installation)
- [Platform Notes](#-platform-notes)
- [Advanced Configuration](#-advanced-configuration-blas-openmp-vcpkg)
- [Build from Source](#-build-from-source-with-vcpkg)
- [Usage Examples](#-usage-examples)
- [Documentation](#-documentation)
- [Testing & CI](#-testing--continuous-integration)
- [Citation](#-citation)
- [License](#-license)
- [Acknowledgements](#-acknowledgements)
- [Caveats](#-caveats)
## π Features
- β
Replicator dynamics for 2-strategy and N-player games
- β
Stochastic dynamics using the pairwise comparison rule
- β
Numerical simulation of evolutionary processes in finite populations
- β
Monte Carlo estimation of fixation probabilities and strategy distributions
- β
OpenMP parallelization for large-scale simulations (Linux/macOS)
- β
Modular game and strategy framework, extensible in both Python and C++
- β
Visual tools for plotting gradients, stationary distributions, and simplex diagrams
- β
Support for Boost, Eigen, and BLAS integration (configurable)
- β
Cross-platform wheels (Linux, macOS, Windows; x86_64 and ARM64)
## π¦ Installation
EGTTools is distributed via PyPI and includes prebuilt wheels for major platforms:
| Platform | Architectures | Python Versions | OpenMP Supported |
|-----------------|-----------------------|-----------------|------------------|
| Linux (x86_64) | x86_64 | 3.10 β 3.12 | β
Yes |
| macOS (x86/arm) | x86_64, arm64 (M1/M2) | 3.10 β 3.12 | β
Yes |
| Windows | x86_64, arm64 | 3.10 β 3.12 | β Not available |
### βΆοΈ Install with pip
```bash
pip install egttools
```
For a more reliable installation on macOS with conda-based environments:
conda install numpy scipy matplotlib networkx seaborn
pip install egttools --no-deps
---
## π₯οΈ Platform Notes
### π§ Linux
- OpenMP is fully supported and enabled by default.
- Wheels are built with optimized BLAS/LAPACK and Boost.
- Recommended for high-performance simulation runs.
### π macOS (Intel or Apple Silicon)
- Supported on both `x86_64` and `arm64`.
- OpenMP is enabled by default and linked via `libomp`.
- If using `conda`, prefer `miniforge` or `mambaforge` for ABI compatibility.
- To skip dependency resolution and control packages manually:
```bash
pip install egttools --no-deps
conda install numpy scipy matplotlib networkx seaborn
````
### πͺ Windows (x86_64 and ARM64)
- Windows wheels are available for both Intel and ARM architectures.
- OpenMP is currently not available on Windows.
- Simulations will fall back to single-threaded mode.
- BLAS/LAPACK can be enabled via conda or system libraries if building from source.
---
## βοΈ Advanced Configuration (BLAS, OpenMP, vcpkg)
The C++ backend of EGTTools supports several build-time options that can be toggled when building from source:
| Feature | CMake Option | Default | Description |
|---------------|----------------------------|------------------|-------------------------------------------------|
| OpenMP | `-DEGTTOOLS_USE_OPENMP=ON` | ON (Linux/macOS) | Enables parallel computation for simulations |
| BLAS/LAPACK | `-DEGTTOOLS_USE_BLAS=ON` | OFF | Enables matrix acceleration (e.g., OpenBLAS) |
| Use vcpkg | `-DEGTTOOLS_USE_VCPKG=ON` | ON | Automatically fetches Boost and Eigen |
| Disable vcpkg | `-DEGTTOOLS_USE_VCPKG=OFF` | | Allows using system-provided libraries manually |
### π§° When to disable vcpkg
You may want to disable `vcpkg` in CI environments or when using a distribution that provides all necessary dependencies
system-wide. To do this:
```bash
cmake -DEGTTOOLS_USE_VCPKG=OFF .
```
In this case, you are responsible for ensuring that compatible versions of Boost and Eigen are available in your system
paths.
---
## π§ Build from Source (with vcpkg)
To build EGTTools from source with all dependencies managed via `vcpkg`, run:
```bash
git clone --recurse-submodules https://github.com/Socrats/EGTTools.git
cd EGTTools
pip install .
```
To configure optional features manually, such as OpenMP or BLAS support:
```bash
cmake -DEGTTOOLS_USE_OPENMP=ON -DEGTTOOLS_USE_BLAS=ON -DEGTTOOLS_USE_VCPKG=OFF .
make
```
If using `conda`, make sure to activate your environment first and ensure that Python, NumPy, and compiler toolchains
are compatible.
---
## π§ͺ Usage Examples
### Calculate Gradient of Selection
```python
from egttools.analytical import PairwiseComparison
from egttools.games import Matrix2PlayerGameHolder
A = [[-0.5, 2], [0, 0]]
game = Matrix2PlayerGameHolder(2, A)
evolver = PairwiseComparison(100, game)
gradient = evolver.calculate_gradient_of_selection(beta=1.0, state=[10, 90])
```
---
### Estimate fixation probability numerically
```python
from egttools.numerical import PairwiseComparisonNumerical
from egttools.games import Matrix2PlayerGameHolder
A = [[-0.5, 2], [0, 0]]
game = Matrix2PlayerGameHolder(2, A)
numerical_evolver = PairwiseComparisonNumerical(game, population_size=100, cache=1_000_000)
fp = numerical_evolver.estimate_fixation_probability(
index_invading_strategy=1,
index_resident_strategy=0,
nb_runs=500,
nb_generations=5000,
beta=1.0
)
```
### More Examples of usage
The [Analytical example](docs/examples/hawk_dove_dynamics.ipynb) is a jupyter notebook which analyses analytically the
evolutionary dynamics in a (2-person, 2-actions, one-shot) Hawk-Dove game.
The [Numerical example](docs/examples/normal_form_game_mc_simulations.ipynb) is a jupyter notebook which analyses
through numerical simulations the evolutionary dynamics in a (2-person, 2-actions, one-shot) Hawk-Dove game.
The [Invasion example](docs/examples/plot_invasion_diagram.ipynb) is a jupyter notebook calculates the fixation
probabilities and stationary distribution of a Normal Form Game with 5 strategies and then plots an invasion diagram.
The [Plot 2 Simplex](docs/examples/plot_simplex.ipynb) is a jupyter notebook that shows how to use EGTtools to plot the
evolutionary dynamics in a 2 Simplex (a triangle), both for infinite and finite populations.
You can also check all these notebooks and a bit more on
this [tutorial repository](https://github.com/Socrats/egt-tutorial)
For example, assuming the following payoff matrix:

You can plot the gradient of selection in a finite population of \(Z=100\) individuals and assuming and intensity of
selection  in the following way:
```python
import numpy as np
from egttools.analytical import PairwiseComparison
from egttools.games import Matrix2PlayerGameHolder
beta = 1;
Z = 100;
nb_strategies = 2;
A = np.array([[-0.5, 2.], [0., 0.]])
pop_states = np.arange(0, Z + 1, 1)
game = Matrix2PlayerGameHolder(nb_strategies, payoff_matrix=A)
# Instantiate evolver and calculate gradient
evolver = PairwiseComparison(population_size=Z, game=game)
gradients = np.array([evolver.calculate_gradient_of_selection(beta, np.array([x, Z - x])) for x in range(Z + 1)])
```
Afterward, you can plot the results with:
```python
from egttools.plotting import plot_gradients
plot_gradients(gradients, figsize=(4, 4), fig_title="Hawk-Dove game stochastic dynamics",
marker_facecolor='white',
xlabel="frequency of hawks (k/Z)", marker="o", marker_size=20, marker_plot_freq=2)
```

And you can plot the stationary distribution for a mutation
rate  with:
```python
import matplotlib.pyplot as plt
from egttools.utils import calculate_stationary_distribution
transitions = evolver.calculate_transition_matrix(beta, mu=1e-3)
stationary_with_mu = calculate_stationary_distribution(transitions.transpose())
fig, ax = plt.subplots(figsize=(5, 4))
fig.patch.set_facecolor('white')
lines = ax.plot(np.arange(0, Z + 1) / Z, stationary_with_mu)
plt.setp(lines, linewidth=2.0)
ax.set_ylabel('stationary distribution', size=16)
ax.set_xlabel('$k/Z$', size=16)
ax.set_xlim(0, 1)
plt.show()
```

We can get the same results through numerical simulations. The error will depend on how many independent simulations
you perform and for how long you let the simulation run. While a future implementation will offer an adaptive method to
vary these parameters depending on the variations between the estimated distributions, for the moment it is important
that you let the simulation run for enough generations after it has achieved a steady state. Here is a comparison
between analytical and numerical results:
```python
from egttools.numerical import PairwiseComparisonNumerical
from egttools.games import NormalFormGame
# Instantiate the game
game = NormalFormGame(1, A)
numerical_evolver = PairwiseComparisonNumerical(Z, game, 1000000)
# We do this for different betas
betas = np.logspace(-4, 1, 50)
stationary_points = []
# numerical simulations
for i in range(len(betas)):
stationary_points.append(numerical_evolver.stationary_distribution(30, int(1e6), int(1e3),
betas[i], 1e-3))
stationary_points = np.asarray(stationary_points)
# Now we estimate the probability of Cooperation for each possible state
state_frequencies = np.arange(0, Z + 1) / Z
coop_level = np.dot(state_frequencies, stationary_points.T)
```
Lastly, we plot the results:
```python
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(1 - coop_level_analytical, coop_level)
# Finally, we plot and compare visually (and check how much error we get)
fig, ax = plt.subplots(figsize=(7, 5))
# ax.scatter(betas, coop_level, label="simulation")
ax.scatter(betas, coop_level_analytical, marker='x', label="analytical")
ax.scatter(betas, coop_level, marker='o', label="simulation")
ax.text(0.01, 0.535, 'MSE = {0:.3e}'.format(mse), style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
ax.legend()
ax.set_xlabel(r'$\beta$', fontsize=15)
ax.set_ylabel('Cooperation level', fontsize=15)
ax.set_xscale('log')
plt.show()
```

Finally, you may also visualize the result of independent simulations:
```python
init_states = np.random.randint(0, Z + 1, size=10, dtype=np.uint64)
output = []
for i in range(10):
output.append(evolver.run(int(1e6), 1, 1e-3,
[init_states[i], Z - init_states[i]]))
# Plot each year's time series in its own facet
fig, ax = plt.subplots(figsize=(5, 4))
for run in output:
ax.plot(run[:, 0] / Z, color='gray', linewidth=.1, alpha=0.6)
ax.set_ylabel('k/Z')
ax.set_xlabel('generation')
ax.set_xscale('log')
```

### Plotting the dynamics in a 2 Simplex
EGTtools can also be used to visualize the evolutionary dynamics in a 2 Simplex. In the example bellow, we use the
`egttools.plotting.plot_replicator_dynamics_in_simplex` which calculates the gradients on a simplex given an initial
payoff matrix and returns a `egttools.plotting.Simplex2D` object which can be used to plot the 2 Simplex.
```python
import numpy as np
import matplotlib.pyplot as plt
from egttools.plotting import plot_replicator_dynamics_in_simplex
payoffs = np.array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
type_labels = ['A', 'B', 'C']
fig, ax = plt.subplots(figsize=(10, 8))
simplex, gradient_function, roots, roots_xy, stability = plot_replicator_dynamics_in_simplex(payoffs, ax=ax)
plot = (simplex.add_axis(ax=ax)
.draw_triangle()
.draw_gradients(zorder=0)
.add_colorbar()
.add_vertex_labels(type_labels)
.draw_stationary_points(roots_xy, stability)
.draw_trajectory_from_roots(gradient_function,
roots,
stability,
trajectory_length=15,
linewidth=1,
step=0.01,
color='k', draw_arrow=True,
arrowdirection='right',
arrowsize=30, zorder=4, arrowstyle='fancy')
.draw_scatter_shadow(gradient_function, 300, color='gray', marker='.', s=0.1, zorder=0)
)
ax.axis('off')
ax.set_aspect('equal')
plt.xlim((-.05, 1.05))
plt.ylim((-.02, simplex.top_corner + 0.05))
plt.show()
```

The same can be done for finite populations, with the added possibility to plot the stationary distribution inside the
triangle (see [simplex plotting](docs/examples/plot_simplex.ipynb)
and [simplified simplex plotting](docs/examples/plot_simplex_simplified.ipynb)
for a more in-depth example).
---
## π Documentation
- π API Reference (ReadTheDocs): [https://egttools.readthedocs.io](https://egttools.readthedocs.io)
- π Live Tutorial & Examples: [https://efernandez.eu/EGTTools/](https://efernandez.eu/EGTTools/)
You can find a full description of available games, strategies, and simulation methods, along with Jupyter notebooks and
real-world use cases.
---
## π§ͺ Testing & Continuous Integration
EGTTools uses GitHub Actions for full CI/CD automation:
- π§± **`wheels.yml`** builds wheels for all platforms (Linux, macOS, Windows; x86_64 and arm64)
- π **`docs.yml`** builds documentation and deploys it to GitHub Pages and ReadTheDocs
- β
Unit tests run with `pytest` and are included in each CI matrix build
- π§ͺ Python stub files are auto-generated from `pybind11` bindings for better typing support
To run tests locally:
```bash
pytest tests
```
You can also build and validate docs locally with:
```bash
cd docs
make html
```
---
## π Citation
If you use EGTtools in your publications, please cite it in the following way with bibtex:
```latex
@article{Fernandez2023,
author = {FernΓ‘ndez Domingos, Elias and Santos, Francisco C. and Lenaerts, Tom},
title = {EGTtools: Evolutionary game dynamics in Python},
journal = {iScience},
volume = {26},
number = {4},
pages = {106419},
year = {2023},
issn = {2589-0042},
doi = {https://doi.org/10.1016/j.isci.2023.106419}
}
```
Or in text format:
```
FernΓ‘ndez Domingos, E., Santos, F. C. & Lenaerts, T. EGTtools: Evolutionary game dynamics in Python. iScience 26, 106419 (2023).
```
And to cite the current version of EGTtools you can use:
```latex
@misc{Fernandez2020,
author = {FernΓ‘ndez Domingos, Elias},
title = {EGTTools: Toolbox for Evolutionary Game Theory (0.1.12)},
year = {2022},
month = {Dec},
journal = {Zenodo},
doi = {10.5281/zenodo.7458631}
}
```
Moreover, you may find our article at [here](https://www.cell.com/iscience/pdf/S2589-0042(23)00496-0.pdf).
---
## π License
EGTTools is released under the [GPLv3 or later](LICENSE).
---
## π Acknowledgements
Developed and maintained by [Elias FernΓ‘ndez](https://efernandez.eu).
* Great parts of this project have been possible thanks to the help of
[Yannick Jadoul](https://github.com/YannickJadoul) author of
[Parselmouth](https://github.com/YannickJadoul/Parselmouth)
and [Eugenio Bargiacchi](https://github.com/Svalorzen) author of [AIToolBox](https://github.com/Svalorzen/AI-Toolbox).
They are both great programmers and scientists, so it is always a good idea to check out their work.
* EGTtools makes use of the amazing [pybind11](https://github.com/pybind/pybind11). library to provide a Python
interface for optimized monte-carlo simulations written in C++.
---
## β οΈ Caveats
- On **Windows**, OpenMP is currently not supported. All simulations will run single-threaded.
- On **macOS**, OpenMP is supported but performance may depend on the installed `libomp`. If using `conda`, make sure `llvm-openmp` is available.
- Wheels are only built for **Python 3.10 β 3.12**.
- Numerical simulations require large RAM allocations when using large population sizes or caching; ensure you configure the `cache` size accordingly.
- Advanced users building from source should ensure Boost, Eigen, and BLAS/LAPACK libraries are compatible with their compiler toolchain.
---
Raw data
{
"_id": null,
"home_page": "https://github.com/Socrats/EGTTools",
"name": "egttools",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "\"Elias F. Domingos\" <elias.fernandez.domingos@vub.be>",
"keywords": "evolutionary game theory, EGT, python, library, scientific computing",
"author": "Elias F. Domingos",
"author_email": "\"Elias F. Domingos\" <elias.fernandez.domingos@vub.be>",
"download_url": "https://files.pythonhosted.org/packages/e2/70/3fdb2ddc369eccfdd90156da85060d968b0b28d6f83b7ff1dc459615aa55/egttools-0.1.14.2.tar.gz",
"platform": null,
"description": "\n\n# EGTTools \u2013 Evolutionary Game Theory Toolbox\n\n[](https://pypi.org/project/egttools/)\n[](https://egttools.readthedocs.io/)\n[](https://efernandez.eu/EGTTools/)\n[](https://github.com/Socrats/EGTTools/actions/workflows/wheels.yml)\n[](https://gitter.im/EGTTools/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)\n[](https://mybinder.org/v2/gh/Socrats/EGTTools/HEAD?labpath=docs%2Fexamples)\n[](https://zenodo.org/badge/latestdoi/242180332)\n\nEGTTools is a modular toolbox for simulating and analyzing **evolutionary dynamics** in strategic environments. It\ncombines **analytical methods** (replicator dynamics, fixation probabilities) and **numerical simulations** (Monte Carlo\nwith parallel C++ backends) under a unified interface.\n\n---\n\n## \ud83d\udcd1 Table of Contents\n\nTesting & Continuous Integration\n\n- [Features](#-features)\n- [Installation](#-installation)\n- [Platform Notes](#-platform-notes)\n- [Advanced Configuration](#-advanced-configuration-blas-openmp-vcpkg)\n- [Build from Source](#-build-from-source-with-vcpkg)\n- [Usage Examples](#-usage-examples)\n- [Documentation](#-documentation)\n- [Testing & CI](#-testing--continuous-integration)\n- [Citation](#-citation)\n- [License](#-license)\n- [Acknowledgements](#-acknowledgements)\n- [Caveats](#-caveats)\n\n## \ud83d\ude80 Features\n\n- \u2705 Replicator dynamics for 2-strategy and N-player games\n- \u2705 Stochastic dynamics using the pairwise comparison rule\n- \u2705 Numerical simulation of evolutionary processes in finite populations\n- \u2705 Monte Carlo estimation of fixation probabilities and strategy distributions\n- \u2705 OpenMP parallelization for large-scale simulations (Linux/macOS)\n- \u2705 Modular game and strategy framework, extensible in both Python and C++\n- \u2705 Visual tools for plotting gradients, stationary distributions, and simplex diagrams\n- \u2705 Support for Boost, Eigen, and BLAS integration (configurable)\n- \u2705 Cross-platform wheels (Linux, macOS, Windows; x86_64 and ARM64)\n\n## \ud83d\udce6 Installation\n\nEGTTools is distributed via PyPI and includes prebuilt wheels for major platforms:\n\n| Platform | Architectures | Python Versions | OpenMP Supported |\n|-----------------|-----------------------|-----------------|------------------|\n| Linux (x86_64) | x86_64 | 3.10 \u2013 3.12 | \u2705 Yes |\n| macOS (x86/arm) | x86_64, arm64 (M1/M2) | 3.10 \u2013 3.12 | \u2705 Yes |\n| Windows | x86_64, arm64 | 3.10 \u2013 3.12 | \u274c Not available |\n\n### \u25b6\ufe0f Install with pip\n\n```bash\npip install egttools\n```\n\nFor a more reliable installation on macOS with conda-based environments:\n\nconda install numpy scipy matplotlib networkx seaborn\npip install egttools --no-deps\n\n---\n\n## \ud83d\udda5\ufe0f Platform Notes\n\n### \ud83d\udc27 Linux\n\n- OpenMP is fully supported and enabled by default.\n- Wheels are built with optimized BLAS/LAPACK and Boost.\n- Recommended for high-performance simulation runs.\n\n### \ud83c\udf4e macOS (Intel or Apple Silicon)\n\n- Supported on both `x86_64` and `arm64`.\n- OpenMP is enabled by default and linked via `libomp`.\n- If using `conda`, prefer `miniforge` or `mambaforge` for ABI compatibility.\n- To skip dependency resolution and control packages manually:\n\n```bash\npip install egttools --no-deps\nconda install numpy scipy matplotlib networkx seaborn\n````\n\n### \ud83e\ude9f Windows (x86_64 and ARM64)\n\n- Windows wheels are available for both Intel and ARM architectures.\n- OpenMP is currently not available on Windows.\n- Simulations will fall back to single-threaded mode.\n- BLAS/LAPACK can be enabled via conda or system libraries if building from source.\n\n---\n\n## \u2699\ufe0f Advanced Configuration (BLAS, OpenMP, vcpkg)\n\nThe C++ backend of EGTTools supports several build-time options that can be toggled when building from source:\n\n| Feature | CMake Option | Default | Description |\n|---------------|----------------------------|------------------|-------------------------------------------------|\n| OpenMP | `-DEGTTOOLS_USE_OPENMP=ON` | ON (Linux/macOS) | Enables parallel computation for simulations |\n| BLAS/LAPACK | `-DEGTTOOLS_USE_BLAS=ON` | OFF | Enables matrix acceleration (e.g., OpenBLAS) |\n| Use vcpkg | `-DEGTTOOLS_USE_VCPKG=ON` | ON | Automatically fetches Boost and Eigen |\n| Disable vcpkg | `-DEGTTOOLS_USE_VCPKG=OFF` | | Allows using system-provided libraries manually |\n\n### \ud83e\uddf0 When to disable vcpkg\n\nYou may want to disable `vcpkg` in CI environments or when using a distribution that provides all necessary dependencies\nsystem-wide. To do this:\n\n```bash\ncmake -DEGTTOOLS_USE_VCPKG=OFF .\n```\n\nIn this case, you are responsible for ensuring that compatible versions of Boost and Eigen are available in your system\npaths.\n\n---\n\n## \ud83d\udd27 Build from Source (with vcpkg)\n\nTo build EGTTools from source with all dependencies managed via `vcpkg`, run:\n\n```bash\ngit clone --recurse-submodules https://github.com/Socrats/EGTTools.git\ncd EGTTools\npip install .\n```\n\nTo configure optional features manually, such as OpenMP or BLAS support:\n\n```bash\ncmake -DEGTTOOLS_USE_OPENMP=ON -DEGTTOOLS_USE_BLAS=ON -DEGTTOOLS_USE_VCPKG=OFF .\nmake\n```\n\nIf using `conda`, make sure to activate your environment first and ensure that Python, NumPy, and compiler toolchains\nare compatible.\n\n---\n## \ud83e\uddea Usage Examples\n\n### Calculate Gradient of Selection\n\n```python\nfrom egttools.analytical import PairwiseComparison\nfrom egttools.games import Matrix2PlayerGameHolder\n\nA = [[-0.5, 2], [0, 0]]\ngame = Matrix2PlayerGameHolder(2, A)\nevolver = PairwiseComparison(100, game)\n\ngradient = evolver.calculate_gradient_of_selection(beta=1.0, state=[10, 90])\n```\n\n---\n\n### Estimate fixation probability numerically\n\n```python\nfrom egttools.numerical import PairwiseComparisonNumerical\nfrom egttools.games import Matrix2PlayerGameHolder\n\nA = [[-0.5, 2], [0, 0]]\ngame = Matrix2PlayerGameHolder(2, A)\nnumerical_evolver = PairwiseComparisonNumerical(game, population_size=100, cache=1_000_000)\nfp = numerical_evolver.estimate_fixation_probability(\n index_invading_strategy=1,\n index_resident_strategy=0,\n nb_runs=500,\n nb_generations=5000,\n beta=1.0\n)\n```\n\n\n### More Examples of usage\n\nThe [Analytical example](docs/examples/hawk_dove_dynamics.ipynb) is a jupyter notebook which analyses analytically the\nevolutionary dynamics in a (2-person, 2-actions, one-shot) Hawk-Dove game.\n\nThe [Numerical example](docs/examples/normal_form_game_mc_simulations.ipynb) is a jupyter notebook which analyses\nthrough numerical simulations the evolutionary dynamics in a (2-person, 2-actions, one-shot) Hawk-Dove game.\n\nThe [Invasion example](docs/examples/plot_invasion_diagram.ipynb) is a jupyter notebook calculates the fixation\nprobabilities and stationary distribution of a Normal Form Game with 5 strategies and then plots an invasion diagram.\n\nThe [Plot 2 Simplex](docs/examples/plot_simplex.ipynb) is a jupyter notebook that shows how to use EGTtools to plot the\nevolutionary dynamics in a 2 Simplex (a triangle), both for infinite and finite populations.\n\nYou can also check all these notebooks and a bit more on\nthis [tutorial repository](https://github.com/Socrats/egt-tutorial)\n\nFor example, assuming the following payoff matrix:\n\n\n\nYou can plot the gradient of selection in a finite population of \\(Z=100\\) individuals and assuming and intensity of\nselection  in the following way:\n\n```python\nimport numpy as np\nfrom egttools.analytical import PairwiseComparison\nfrom egttools.games import Matrix2PlayerGameHolder\n\nbeta = 1;\nZ = 100;\nnb_strategies = 2;\nA = np.array([[-0.5, 2.], [0., 0.]])\npop_states = np.arange(0, Z + 1, 1)\n\ngame = Matrix2PlayerGameHolder(nb_strategies, payoff_matrix=A)\n\n# Instantiate evolver and calculate gradient\nevolver = PairwiseComparison(population_size=Z, game=game)\ngradients = np.array([evolver.calculate_gradient_of_selection(beta, np.array([x, Z - x])) for x in range(Z + 1)])\n```\n\nAfterward, you can plot the results with:\n\n```python\nfrom egttools.plotting import plot_gradients\n\nplot_gradients(gradients, figsize=(4, 4), fig_title=\"Hawk-Dove game stochastic dynamics\",\n marker_facecolor='white',\n xlabel=\"frequency of hawks (k/Z)\", marker=\"o\", marker_size=20, marker_plot_freq=2)\n```\n\n\n\nAnd you can plot the stationary distribution for a mutation\nrate  with:\n\n```python\nimport matplotlib.pyplot as plt\nfrom egttools.utils import calculate_stationary_distribution\n\ntransitions = evolver.calculate_transition_matrix(beta, mu=1e-3)\nstationary_with_mu = calculate_stationary_distribution(transitions.transpose())\nfig, ax = plt.subplots(figsize=(5, 4))\nfig.patch.set_facecolor('white')\nlines = ax.plot(np.arange(0, Z + 1) / Z, stationary_with_mu)\nplt.setp(lines, linewidth=2.0)\nax.set_ylabel('stationary distribution', size=16)\nax.set_xlabel('$k/Z$', size=16)\nax.set_xlim(0, 1)\nplt.show()\n```\n\n\n\nWe can get the same results through numerical simulations. The error will depend on how many independent simulations\nyou perform and for how long you let the simulation run. While a future implementation will offer an adaptive method to\nvary these parameters depending on the variations between the estimated distributions, for the moment it is important\nthat you let the simulation run for enough generations after it has achieved a steady state. Here is a comparison\nbetween analytical and numerical results:\n\n```python\nfrom egttools.numerical import PairwiseComparisonNumerical\nfrom egttools.games import NormalFormGame\n\n# Instantiate the game\ngame = NormalFormGame(1, A)\nnumerical_evolver = PairwiseComparisonNumerical(Z, game, 1000000)\n\n# We do this for different betas\nbetas = np.logspace(-4, 1, 50)\nstationary_points = []\n# numerical simulations\nfor i in range(len(betas)):\n stationary_points.append(numerical_evolver.stationary_distribution(30, int(1e6), int(1e3),\n betas[i], 1e-3))\nstationary_points = np.asarray(stationary_points)\n# Now we estimate the probability of Cooperation for each possible state\nstate_frequencies = np.arange(0, Z + 1) / Z\ncoop_level = np.dot(state_frequencies, stationary_points.T)\n```\n\nLastly, we plot the results:\n\n```python\nfrom sklearn.metrics import mean_squared_error\n\nmse = mean_squared_error(1 - coop_level_analytical, coop_level)\n\n# Finally, we plot and compare visually (and check how much error we get)\nfig, ax = plt.subplots(figsize=(7, 5))\n# ax.scatter(betas, coop_level, label=\"simulation\")\nax.scatter(betas, coop_level_analytical, marker='x', label=\"analytical\")\nax.scatter(betas, coop_level, marker='o', label=\"simulation\")\nax.text(0.01, 0.535, 'MSE = {0:.3e}'.format(mse), style='italic',\n bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})\nax.legend()\nax.set_xlabel(r'$\\beta$', fontsize=15)\nax.set_ylabel('Cooperation level', fontsize=15)\nax.set_xscale('log')\nplt.show()\n```\n\n\n\nFinally, you may also visualize the result of independent simulations:\n\n```python\ninit_states = np.random.randint(0, Z + 1, size=10, dtype=np.uint64)\noutput = []\nfor i in range(10):\n output.append(evolver.run(int(1e6), 1, 1e-3,\n [init_states[i], Z - init_states[i]]))\n# Plot each year's time series in its own facet\nfig, ax = plt.subplots(figsize=(5, 4))\n\nfor run in output:\n ax.plot(run[:, 0] / Z, color='gray', linewidth=.1, alpha=0.6)\nax.set_ylabel('k/Z')\nax.set_xlabel('generation')\nax.set_xscale('log')\n```\n\n\n\n### Plotting the dynamics in a 2 Simplex\n\nEGTtools can also be used to visualize the evolutionary dynamics in a 2 Simplex. In the example bellow, we use the\n`egttools.plotting.plot_replicator_dynamics_in_simplex` which calculates the gradients on a simplex given an initial\npayoff matrix and returns a `egttools.plotting.Simplex2D` object which can be used to plot the 2 Simplex.\n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom egttools.plotting import plot_replicator_dynamics_in_simplex\n\npayoffs = np.array([[1, 0, 0],\n [0, 2, 0],\n [0, 0, 3]])\ntype_labels = ['A', 'B', 'C']\n\nfig, ax = plt.subplots(figsize=(10, 8))\n\nsimplex, gradient_function, roots, roots_xy, stability = plot_replicator_dynamics_in_simplex(payoffs, ax=ax)\n\nplot = (simplex.add_axis(ax=ax)\n .draw_triangle()\n .draw_gradients(zorder=0)\n .add_colorbar()\n .add_vertex_labels(type_labels)\n .draw_stationary_points(roots_xy, stability)\n .draw_trajectory_from_roots(gradient_function,\n roots,\n stability,\n trajectory_length=15,\n linewidth=1,\n step=0.01,\n color='k', draw_arrow=True,\n arrowdirection='right',\n arrowsize=30, zorder=4, arrowstyle='fancy')\n .draw_scatter_shadow(gradient_function, 300, color='gray', marker='.', s=0.1, zorder=0)\n )\n\nax.axis('off')\nax.set_aspect('equal')\n\nplt.xlim((-.05, 1.05))\nplt.ylim((-.02, simplex.top_corner + 0.05))\nplt.show()\n```\n\n\n\nThe same can be done for finite populations, with the added possibility to plot the stationary distribution inside the\ntriangle (see [simplex plotting](docs/examples/plot_simplex.ipynb)\nand [simplified simplex plotting](docs/examples/plot_simplex_simplified.ipynb)\nfor a more in-depth example).\n\n---\n\n## \ud83d\udcda Documentation\n\n- \ud83d\udcd8 API Reference (ReadTheDocs): [https://egttools.readthedocs.io](https://egttools.readthedocs.io)\n- \ud83c\udf0d Live Tutorial & Examples: [https://efernandez.eu/EGTTools/](https://efernandez.eu/EGTTools/)\n\nYou can find a full description of available games, strategies, and simulation methods, along with Jupyter notebooks and\nreal-world use cases.\n\n---\n\n## \ud83e\uddea Testing & Continuous Integration\n\nEGTTools uses GitHub Actions for full CI/CD automation:\n\n- \ud83e\uddf1 **`wheels.yml`** builds wheels for all platforms (Linux, macOS, Windows; x86_64 and arm64)\n- \ud83d\udcd8 **`docs.yml`** builds documentation and deploys it to GitHub Pages and ReadTheDocs\n- \u2705 Unit tests run with `pytest` and are included in each CI matrix build\n- \ud83e\uddea Python stub files are auto-generated from `pybind11` bindings for better typing support\n\nTo run tests locally:\n\n```bash\npytest tests\n```\n\nYou can also build and validate docs locally with:\n\n```bash\ncd docs\nmake html\n```\n\n---\n\n## \ud83d\udcd6 Citation\n\nIf you use EGTtools in your publications, please cite it in the following way with bibtex:\n\n```latex\n@article{Fernandez2023,\n author = {Fern\u00e1ndez Domingos, Elias and Santos, Francisco C. and Lenaerts, Tom},\n title = {EGTtools: Evolutionary game dynamics in Python},\n journal = {iScience},\n volume = {26},\n number = {4},\n pages = {106419},\n year = {2023},\n issn = {2589-0042},\n doi = {https://doi.org/10.1016/j.isci.2023.106419}\n}\n```\n\nOr in text format:\n\n```\nFern\u00e1ndez Domingos, E., Santos, F. C. & Lenaerts, T. EGTtools: Evolutionary game dynamics in Python. iScience 26, 106419 (2023).\n```\n\nAnd to cite the current version of EGTtools you can use:\n\n```latex\n@misc{Fernandez2020,\n author = {Fern\u00e1ndez Domingos, Elias},\n title = {EGTTools: Toolbox for Evolutionary Game Theory (0.1.12)},\n year = {2022},\n month = {Dec},\n journal = {Zenodo},\n doi = {10.5281/zenodo.7458631}\n}\n```\n\nMoreover, you may find our article at [here](https://www.cell.com/iscience/pdf/S2589-0042(23)00496-0.pdf).\n\n---\n\n## \ud83d\udcc4 License\n\nEGTTools is released under the [GPLv3 or later](LICENSE).\n\n---\n\n## \ud83d\ude4f Acknowledgements\n\nDeveloped and maintained by [Elias Fern\u00e1ndez](https://efernandez.eu).\n\n* Great parts of this project have been possible thanks to the help of\n [Yannick Jadoul](https://github.com/YannickJadoul) author of\n [Parselmouth](https://github.com/YannickJadoul/Parselmouth)\n and [Eugenio Bargiacchi](https://github.com/Svalorzen) author of [AIToolBox](https://github.com/Svalorzen/AI-Toolbox).\n They are both great programmers and scientists, so it is always a good idea to check out their work.\n* EGTtools makes use of the amazing [pybind11](https://github.com/pybind/pybind11). library to provide a Python\n interface for optimized monte-carlo simulations written in C++.\n\n---\n\n## \u26a0\ufe0f Caveats\n\n- On **Windows**, OpenMP is currently not supported. All simulations will run single-threaded.\n- On **macOS**, OpenMP is supported but performance may depend on the installed `libomp`. If using `conda`, make sure `llvm-openmp` is available.\n- Wheels are only built for **Python 3.10 \u2013 3.12**.\n- Numerical simulations require large RAM allocations when using large population sizes or caching; ensure you configure the `cache` size accordingly.\n- Advanced users building from source should ensure Boost, Eigen, and BLAS/LAPACK libraries are compatible with their compiler toolchain.\n\n---\n",
"bugtrack_url": null,
"license": null,
"summary": "Efficient Python library for Evolutionary Game Theory (EGT)",
"version": "0.1.14.2",
"project_urls": {
"Bug Tracker": "https://github.com/Socrats/EGTTools/issues",
"Documentation": "https://egttools.readthedocs.io/en/latest/",
"Homepage": "https://github.com/Socrats/EGTTools"
},
"split_keywords": [
"evolutionary game theory",
" egt",
" python",
" library",
" scientific computing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "72deba85f7e1d057b1a725b4e27289d4cb41a607245fe5a3591af49c67334dba",
"md5": "048fa62f3f40cbe07e46682d1063c346",
"sha256": "cbd9bf8d5ecc546588e8ca87dd94be366557df2a340cd050aaf86989e0703b84"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp310-cp310-macosx_13_0_x86_64.whl",
"has_sig": false,
"md5_digest": "048fa62f3f40cbe07e46682d1063c346",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.10",
"size": 5191645,
"upload_time": "2025-07-20T21:13:23",
"upload_time_iso_8601": "2025-07-20T21:13:23.387565Z",
"url": "https://files.pythonhosted.org/packages/72/de/ba85f7e1d057b1a725b4e27289d4cb41a607245fe5a3591af49c67334dba/egttools-0.1.14.2-cp310-cp310-macosx_13_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "cfc462fb9a35c3d70ced24c362b9e1752ff6983c029f76f5939db830d6e7ef38",
"md5": "6755b9494b34a170a70155e090a51f00",
"sha256": "4cea474bdc709ed73d35d5f4aab15f5c0e5aed98739e3d713effbb9f7fceb972"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp310-cp310-macosx_14_0_arm64.whl",
"has_sig": false,
"md5_digest": "6755b9494b34a170a70155e090a51f00",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.10",
"size": 5001037,
"upload_time": "2025-07-20T21:13:26",
"upload_time_iso_8601": "2025-07-20T21:13:26.156321Z",
"url": "https://files.pythonhosted.org/packages/cf/c4/62fb9a35c3d70ced24c362b9e1752ff6983c029f76f5939db830d6e7ef38/egttools-0.1.14.2-cp310-cp310-macosx_14_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1cf6bb5131b50e35cf3235f79bf58e90f713c6513bb0a6cb4fc0196d83088b64",
"md5": "357d70825cd262fe81fc27f03e3e5b41",
"sha256": "7c8affc22dc3ef332121eb538b1b6a18eba2b6f3e1408be3508b2c44e56707a9"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"has_sig": false,
"md5_digest": "357d70825cd262fe81fc27f03e3e5b41",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.10",
"size": 15773820,
"upload_time": "2025-07-20T21:13:28",
"upload_time_iso_8601": "2025-07-20T21:13:28.050250Z",
"url": "https://files.pythonhosted.org/packages/1c/f6/bb5131b50e35cf3235f79bf58e90f713c6513bb0a6cb4fc0196d83088b64/egttools-0.1.14.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "9b164c8eb3bf0e197747bbcd36b2e70914f0f383ad56840862659d56838fd3d2",
"md5": "4f00e72b161907c0352e4faffa3bd739",
"sha256": "a37ee60784f04c991ba49bb421c2b2cc98fe456c369f8e806a3bbc6c77fb979e"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp310-cp310-win_amd64.whl",
"has_sig": false,
"md5_digest": "4f00e72b161907c0352e4faffa3bd739",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.10",
"size": 5904065,
"upload_time": "2025-07-20T21:13:30",
"upload_time_iso_8601": "2025-07-20T21:13:30.158560Z",
"url": "https://files.pythonhosted.org/packages/9b/16/4c8eb3bf0e197747bbcd36b2e70914f0f383ad56840862659d56838fd3d2/egttools-0.1.14.2-cp310-cp310-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "67e622c3b6b67eaca4f3e65389174a93a3581302e7b3ab8a64b05c20d7f363cb",
"md5": "f182d8629863f7cf5f478470ff440bb3",
"sha256": "c11155a8ba9c8576248216281b7c1ba57b3690b25b9a8782aa633edaf33a687f"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp310-cp310-win_arm64.whl",
"has_sig": false,
"md5_digest": "f182d8629863f7cf5f478470ff440bb3",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.10",
"size": 6581904,
"upload_time": "2025-07-20T21:13:32",
"upload_time_iso_8601": "2025-07-20T21:13:32.075995Z",
"url": "https://files.pythonhosted.org/packages/67/e6/22c3b6b67eaca4f3e65389174a93a3581302e7b3ab8a64b05c20d7f363cb/egttools-0.1.14.2-cp310-cp310-win_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1789ce8dd84548b1cbd93a5b62465c4c175503a6a0c4b43c0ecbe4a4334ecefc",
"md5": "46ade5aecb172ee6eba7733f7a95a577",
"sha256": "f8b39a20a9a248272882104ab616a2e36656f054f8a759e2e3f48f01d67c6c08"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp311-cp311-macosx_13_0_x86_64.whl",
"has_sig": false,
"md5_digest": "46ade5aecb172ee6eba7733f7a95a577",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.10",
"size": 5194420,
"upload_time": "2025-07-20T21:13:33",
"upload_time_iso_8601": "2025-07-20T21:13:33.501808Z",
"url": "https://files.pythonhosted.org/packages/17/89/ce8dd84548b1cbd93a5b62465c4c175503a6a0c4b43c0ecbe4a4334ecefc/egttools-0.1.14.2-cp311-cp311-macosx_13_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a7ddbb6cd70603870c7edfe65d22cf00e36fe367ea9981414c73cd04c12028d9",
"md5": "3ec5fedc8529a85b028094c62fb9b61b",
"sha256": "fd7fc6f893a31c92e3c3a9e0a40e647e1707a281bf891c5990f4832536fe0e6b"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp311-cp311-macosx_14_0_arm64.whl",
"has_sig": false,
"md5_digest": "3ec5fedc8529a85b028094c62fb9b61b",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.10",
"size": 5003051,
"upload_time": "2025-07-20T21:13:35",
"upload_time_iso_8601": "2025-07-20T21:13:35.010254Z",
"url": "https://files.pythonhosted.org/packages/a7/dd/bb6cd70603870c7edfe65d22cf00e36fe367ea9981414c73cd04c12028d9/egttools-0.1.14.2-cp311-cp311-macosx_14_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c6b26203872745dfc2519218a0f019e7c941ebd973553f7de27e1bb2b0c435e1",
"md5": "f71d4d747dacea82e42369a041edfb05",
"sha256": "e1f0ae13c0dbdff739018302e5c72bf6b8864fe1cd32be95dd7d1660e5004abd"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"has_sig": false,
"md5_digest": "f71d4d747dacea82e42369a041edfb05",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.10",
"size": 15775646,
"upload_time": "2025-07-20T21:13:37",
"upload_time_iso_8601": "2025-07-20T21:13:37.110862Z",
"url": "https://files.pythonhosted.org/packages/c6/b2/6203872745dfc2519218a0f019e7c941ebd973553f7de27e1bb2b0c435e1/egttools-0.1.14.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "124d351f932887783448b334f48a9b1e51d02d833c6a04fce4edf8d427be9979",
"md5": "369f0f1dba11c38e83954e245db25c23",
"sha256": "7d8e9385da6b6b311816378d4195e839723f75df7e37804be2ddf0dfe6472256"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp311-cp311-win_amd64.whl",
"has_sig": false,
"md5_digest": "369f0f1dba11c38e83954e245db25c23",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.10",
"size": 5906673,
"upload_time": "2025-07-20T21:13:40",
"upload_time_iso_8601": "2025-07-20T21:13:40.346501Z",
"url": "https://files.pythonhosted.org/packages/12/4d/351f932887783448b334f48a9b1e51d02d833c6a04fce4edf8d427be9979/egttools-0.1.14.2-cp311-cp311-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2baf11705eaeb758ce3a385ef7d8bad87ef59c6afba8b31c09866fb2040ffe66",
"md5": "a90a270f253edc88633f7eb3b8213b65",
"sha256": "50a29f4c2f75461f85c665ee3a2aafba5cd14b352b50122b85f6ea0cdb3b728d"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp311-cp311-win_arm64.whl",
"has_sig": false,
"md5_digest": "a90a270f253edc88633f7eb3b8213b65",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.10",
"size": 6582602,
"upload_time": "2025-07-20T21:13:42",
"upload_time_iso_8601": "2025-07-20T21:13:42.156186Z",
"url": "https://files.pythonhosted.org/packages/2b/af/11705eaeb758ce3a385ef7d8bad87ef59c6afba8b31c09866fb2040ffe66/egttools-0.1.14.2-cp311-cp311-win_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "18747b17ef476b08c561592d484578a2be498924517b4ea6c68a5180c210aba3",
"md5": "9524c26f0712dbffa2ba26232ee7f893",
"sha256": "8c64568c95937adb77b75164efb7eb215409c534073f900ba586cac405b62fbc"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp312-cp312-macosx_13_0_x86_64.whl",
"has_sig": false,
"md5_digest": "9524c26f0712dbffa2ba26232ee7f893",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.10",
"size": 5203614,
"upload_time": "2025-07-20T21:13:43",
"upload_time_iso_8601": "2025-07-20T21:13:43.888817Z",
"url": "https://files.pythonhosted.org/packages/18/74/7b17ef476b08c561592d484578a2be498924517b4ea6c68a5180c210aba3/egttools-0.1.14.2-cp312-cp312-macosx_13_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4add0068a0c9be16bc1dd0e1d753bb05b632aa4f8123eff8d3abe1f97be84570",
"md5": "ebadfea9e44087beb6e8ee85e5a1ffc8",
"sha256": "38d4eb75308f6f809b2cdb5c917bfbcd5c4da7002f7507f1da6e8fab9375547c"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp312-cp312-macosx_14_0_arm64.whl",
"has_sig": false,
"md5_digest": "ebadfea9e44087beb6e8ee85e5a1ffc8",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.10",
"size": 5009353,
"upload_time": "2025-07-20T21:13:45",
"upload_time_iso_8601": "2025-07-20T21:13:45.269619Z",
"url": "https://files.pythonhosted.org/packages/4a/dd/0068a0c9be16bc1dd0e1d753bb05b632aa4f8123eff8d3abe1f97be84570/egttools-0.1.14.2-cp312-cp312-macosx_14_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8d3638d101cd85cab73b89db8e42de0755d7d54099e8fd7d7a2d28e0e8871c76",
"md5": "8832481fdf081556fd4052fa31c2475f",
"sha256": "f6533ebac5575c8387e7ea7ee17ce7fa135c4ce16d5e699878dbbdfe39b9d824"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"has_sig": false,
"md5_digest": "8832481fdf081556fd4052fa31c2475f",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.10",
"size": 15760461,
"upload_time": "2025-07-20T21:13:46",
"upload_time_iso_8601": "2025-07-20T21:13:46.944603Z",
"url": "https://files.pythonhosted.org/packages/8d/36/38d101cd85cab73b89db8e42de0755d7d54099e8fd7d7a2d28e0e8871c76/egttools-0.1.14.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2d734f3856c991f2c76431193d6b1e6c17daeec9380af44cb09199e0c89539d8",
"md5": "1d6419e83b84216cf9d5a26eaab8a950",
"sha256": "feae3675855f4eb19e266027f4b0ca8381a3f2dd2301949911a83f0af02a891b"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp312-cp312-win_amd64.whl",
"has_sig": false,
"md5_digest": "1d6419e83b84216cf9d5a26eaab8a950",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.10",
"size": 5903438,
"upload_time": "2025-07-20T21:13:49",
"upload_time_iso_8601": "2025-07-20T21:13:49.266888Z",
"url": "https://files.pythonhosted.org/packages/2d/73/4f3856c991f2c76431193d6b1e6c17daeec9380af44cb09199e0c89539d8/egttools-0.1.14.2-cp312-cp312-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a59347c858c868778fd103fd9163e6e9b5a8d0c48dbb8a24d04a0d1421dcbef6",
"md5": "e6c8286486594d94f0453f018b876ad8",
"sha256": "77a37839ab9447e31cb9714686cee16f1c10845fae6fb2e12dd3612688a77fba"
},
"downloads": -1,
"filename": "egttools-0.1.14.2-cp312-cp312-win_arm64.whl",
"has_sig": false,
"md5_digest": "e6c8286486594d94f0453f018b876ad8",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.10",
"size": 6585318,
"upload_time": "2025-07-20T21:13:50",
"upload_time_iso_8601": "2025-07-20T21:13:50.647001Z",
"url": "https://files.pythonhosted.org/packages/a5/93/47c858c868778fd103fd9163e6e9b5a8d0c48dbb8a24d04a0d1421dcbef6/egttools-0.1.14.2-cp312-cp312-win_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e2703fdb2ddc369eccfdd90156da85060d968b0b28d6f83b7ff1dc459615aa55",
"md5": "1b98122dc2c1f110c08087a0929ce7ca",
"sha256": "55abc057b1f0897351205f25940b19b9998bc982ef3a921f4fbf84012dbcdb9f"
},
"downloads": -1,
"filename": "egttools-0.1.14.2.tar.gz",
"has_sig": false,
"md5_digest": "1b98122dc2c1f110c08087a0929ce7ca",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 3402304,
"upload_time": "2025-07-20T21:13:51",
"upload_time_iso_8601": "2025-07-20T21:13:51.942940Z",
"url": "https://files.pythonhosted.org/packages/e2/70/3fdb2ddc369eccfdd90156da85060d968b0b28d6f83b7ff1dc459615aa55/egttools-0.1.14.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-20 21:13:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Socrats",
"github_project": "EGTTools",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "numpy",
"specs": [
[
">=",
"1.26.3"
]
]
},
{
"name": "scipy",
"specs": [
[
">=",
"1.12.0"
]
]
},
{
"name": "matplotlib",
"specs": [
[
">=",
"3.8.2"
]
]
},
{
"name": "seaborn",
"specs": [
[
">=",
"0.13.2"
]
]
},
{
"name": "networkx",
"specs": [
[
">=",
"3.2.1"
]
]
}
],
"lcname": "egttools"
}