mutation-game 0.1.0__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.
- mutation_game-0.1.0/.claude/settings.json +9 -0
- mutation_game-0.1.0/.gitignore +6 -0
- mutation_game-0.1.0/.python-version +1 -0
- mutation_game-0.1.0/LICENSE +21 -0
- mutation_game-0.1.0/PKG-INFO +119 -0
- mutation_game-0.1.0/README.md +95 -0
- mutation_game-0.1.0/docs/Makefile +12 -0
- mutation_game-0.1.0/docs/_static/a3_all.png +0 -0
- mutation_game-0.1.0/docs/_static/a3_positive.png +0 -0
- mutation_game-0.1.0/docs/_static/d4_positive.png +0 -0
- mutation_game-0.1.0/docs/_static/e6_positive.png +0 -0
- mutation_game-0.1.0/docs/api.rst +7 -0
- mutation_game-0.1.0/docs/background.rst +259 -0
- mutation_game-0.1.0/docs/conf.py +14 -0
- mutation_game-0.1.0/docs/generate_images.py +28 -0
- mutation_game-0.1.0/docs/getting_started.rst +283 -0
- mutation_game-0.1.0/docs/index.rst +14 -0
- mutation_game-0.1.0/main.py +26 -0
- mutation_game-0.1.0/mutation.py +471 -0
- mutation_game-0.1.0/pyproject.toml +48 -0
- mutation_game-0.1.0/roots.png +0 -0
- mutation_game-0.1.0/src/mutation_game/__init__.py +6 -0
- mutation_game-0.1.0/src/mutation_game/mutation.py +471 -0
- mutation_game-0.1.0/test_mutation.py +285 -0
- mutation_game-0.1.0/uv.lock +1237 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(ls /home/acortis/my_codes/mutation_game/*.py)",
|
|
5
|
+
"Bash(ls /home/acortis/my_codes/mutation_game/.venv/bin/python*)",
|
|
6
|
+
"Bash(/home/acortis/my_codes/mutation_game/.venv/bin/python -c \"import numpy; print\\('numpy ok'\\); import networkx; print\\('nx ok'\\); import matplotlib; print\\('mpl ok'\\)\")"
|
|
7
|
+
]
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andrea Cortis
|
|
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,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mutation-game
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Root system explorer via the combinatorial mutation game on graphs
|
|
5
|
+
Project-URL: Homepage, https://github.com/andreacortis/mutation_game
|
|
6
|
+
Project-URL: Repository, https://github.com/andreacortis/mutation_game
|
|
7
|
+
Author: Andrea Cortis
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: dynkin-diagrams,lie-algebras,mutation-game,root-systems,weyl-group
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: matplotlib>=3.7
|
|
21
|
+
Requires-Dist: networkx>=3.0
|
|
22
|
+
Requires-Dist: numpy>=1.24
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Mutation Game
|
|
26
|
+
|
|
27
|
+
A Python library for exploring root systems through the combinatorial mutation game on graphs.
|
|
28
|
+
|
|
29
|
+
Given a graph (or a Dynkin diagram name like `A3`, `D5`, `E8`), the library computes the full root system via iterated mutations and visualizes the mutation graph.
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone git@github.com:andreacortis/mutation_game.git
|
|
35
|
+
cd mutation_game
|
|
36
|
+
uv sync
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from mutation import MutationGame
|
|
41
|
+
|
|
42
|
+
game = MutationGame.from_dynkin("A3")
|
|
43
|
+
roots = game.calculate_roots()
|
|
44
|
+
print(f"A3 has {len(roots)} roots") # 12
|
|
45
|
+
|
|
46
|
+
fig = game.plot_root_orbits()
|
|
47
|
+
fig.savefig("a3_positive.png", bbox_inches="tight", dpi=150)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Dynkin diagram support** -- create games from `A_n`, `D_n`, `E_6`, `E_7`, `E_8` by name
|
|
55
|
+
- **Matrix-based mutations** -- each mutation is a precomputed matrix multiply (`v' = M_k @ v`)
|
|
56
|
+
- **Cartan matrix analysis** -- eigenvalues, eigenvectors, and automatic finite-type detection via positive definiteness
|
|
57
|
+
- **Root system computation** -- full BFS enumeration with verified root counts for all ADE types
|
|
58
|
+
- **Mutation path finding** -- shortest path between any two roots via BFS on the mutation graph
|
|
59
|
+
- **Path tables** -- all-pairs shortest mutation paths in a formatted table
|
|
60
|
+
- **Visualization** -- side-by-side Dynkin diagram and mutation graph with color-coded simple roots
|
|
61
|
+
|
|
62
|
+
## Finite-type detection
|
|
63
|
+
|
|
64
|
+
The library checks whether the Cartan matrix `C = 2I - A` is positive definite before attempting to enumerate roots. Infinite-type graphs are rejected early with a clear error:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
cycle = MutationGame([[0,1,1],[1,0,1],[1,1,0]])
|
|
68
|
+
cycle.is_finite_type() # False
|
|
69
|
+
cycle.calculate_roots() # RuntimeError: Cartan matrix is not positive definite
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Mutation path table
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
game = MutationGame.from_dynkin("A3")
|
|
76
|
+
game.print_mutation_path_table()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Source Target Mutations Len
|
|
81
|
+
-------------------------------------------
|
|
82
|
+
(0, 0, 1) (0, 1, 0) 1 -> 2 2
|
|
83
|
+
(0, 0, 1) (0, 1, 1) 1 1
|
|
84
|
+
(0, 0, 1) (1, 0, 0) 1 -> 2 -> 0 -> 1 4
|
|
85
|
+
(0, 0, 1) (1, 1, 0) 1 -> 2 -> 0 3
|
|
86
|
+
(0, 0, 1) (1, 1, 1) 1 -> 0 2
|
|
87
|
+
...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Each path is reversible: to go from B back to A, apply the same mutations in reverse order.
|
|
91
|
+
|
|
92
|
+
## Tests
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
uv run pytest test_mutation.py -v
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
43 tests covering Dynkin construction, mutation rule, root counts for all ADE types, Cartan matrix properties, mutation paths, and plotting.
|
|
99
|
+
|
|
100
|
+
## Documentation
|
|
101
|
+
|
|
102
|
+
Full Sphinx documentation with mathematical background:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd docs
|
|
106
|
+
uv run sphinx-build -b html . _build/html
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then open `docs/_build/html/index.html`.
|
|
110
|
+
|
|
111
|
+
## Dependencies
|
|
112
|
+
|
|
113
|
+
- `numpy` -- linear algebra and matrix operations
|
|
114
|
+
- `networkx` -- graph construction and layout
|
|
115
|
+
- `matplotlib` -- visualization
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Mutation Game
|
|
2
|
+
|
|
3
|
+
A Python library for exploring root systems through the combinatorial mutation game on graphs.
|
|
4
|
+
|
|
5
|
+
Given a graph (or a Dynkin diagram name like `A3`, `D5`, `E8`), the library computes the full root system via iterated mutations and visualizes the mutation graph.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone git@github.com:andreacortis/mutation_game.git
|
|
11
|
+
cd mutation_game
|
|
12
|
+
uv sync
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from mutation import MutationGame
|
|
17
|
+
|
|
18
|
+
game = MutationGame.from_dynkin("A3")
|
|
19
|
+
roots = game.calculate_roots()
|
|
20
|
+
print(f"A3 has {len(roots)} roots") # 12
|
|
21
|
+
|
|
22
|
+
fig = game.plot_root_orbits()
|
|
23
|
+
fig.savefig("a3_positive.png", bbox_inches="tight", dpi=150)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **Dynkin diagram support** -- create games from `A_n`, `D_n`, `E_6`, `E_7`, `E_8` by name
|
|
31
|
+
- **Matrix-based mutations** -- each mutation is a precomputed matrix multiply (`v' = M_k @ v`)
|
|
32
|
+
- **Cartan matrix analysis** -- eigenvalues, eigenvectors, and automatic finite-type detection via positive definiteness
|
|
33
|
+
- **Root system computation** -- full BFS enumeration with verified root counts for all ADE types
|
|
34
|
+
- **Mutation path finding** -- shortest path between any two roots via BFS on the mutation graph
|
|
35
|
+
- **Path tables** -- all-pairs shortest mutation paths in a formatted table
|
|
36
|
+
- **Visualization** -- side-by-side Dynkin diagram and mutation graph with color-coded simple roots
|
|
37
|
+
|
|
38
|
+
## Finite-type detection
|
|
39
|
+
|
|
40
|
+
The library checks whether the Cartan matrix `C = 2I - A` is positive definite before attempting to enumerate roots. Infinite-type graphs are rejected early with a clear error:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
cycle = MutationGame([[0,1,1],[1,0,1],[1,1,0]])
|
|
44
|
+
cycle.is_finite_type() # False
|
|
45
|
+
cycle.calculate_roots() # RuntimeError: Cartan matrix is not positive definite
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Mutation path table
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
game = MutationGame.from_dynkin("A3")
|
|
52
|
+
game.print_mutation_path_table()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Source Target Mutations Len
|
|
57
|
+
-------------------------------------------
|
|
58
|
+
(0, 0, 1) (0, 1, 0) 1 -> 2 2
|
|
59
|
+
(0, 0, 1) (0, 1, 1) 1 1
|
|
60
|
+
(0, 0, 1) (1, 0, 0) 1 -> 2 -> 0 -> 1 4
|
|
61
|
+
(0, 0, 1) (1, 1, 0) 1 -> 2 -> 0 3
|
|
62
|
+
(0, 0, 1) (1, 1, 1) 1 -> 0 2
|
|
63
|
+
...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Each path is reversible: to go from B back to A, apply the same mutations in reverse order.
|
|
67
|
+
|
|
68
|
+
## Tests
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv run pytest test_mutation.py -v
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
43 tests covering Dynkin construction, mutation rule, root counts for all ADE types, Cartan matrix properties, mutation paths, and plotting.
|
|
75
|
+
|
|
76
|
+
## Documentation
|
|
77
|
+
|
|
78
|
+
Full Sphinx documentation with mathematical background:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd docs
|
|
82
|
+
uv run sphinx-build -b html . _build/html
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Then open `docs/_build/html/index.html`.
|
|
86
|
+
|
|
87
|
+
## Dependencies
|
|
88
|
+
|
|
89
|
+
- `numpy` -- linear algebra and matrix operations
|
|
90
|
+
- `networkx` -- graph construction and layout
|
|
91
|
+
- `matplotlib` -- visualization
|
|
92
|
+
|
|
93
|
+
## License
|
|
94
|
+
|
|
95
|
+
See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
SPHINXOPTS =
|
|
2
|
+
SPHINXBUILD = sphinx-build
|
|
3
|
+
SOURCEDIR = .
|
|
4
|
+
BUILDDIR = _build
|
|
5
|
+
|
|
6
|
+
help:
|
|
7
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
|
|
8
|
+
|
|
9
|
+
.PHONY: help Makefile
|
|
10
|
+
|
|
11
|
+
%: Makefile
|
|
12
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Mathematical Background
|
|
2
|
+
=======================
|
|
3
|
+
|
|
4
|
+
The mutation game is a combinatorial process on graphs that naturally produces
|
|
5
|
+
the root systems of Lie algebras. It was introduced by N. J. Wildberger
|
|
6
|
+
[Wild2003]_ and later published in a generalized form in [Wild2020]_.
|
|
7
|
+
This section describes the mathematical setting.
|
|
8
|
+
|
|
9
|
+
The mutation game
|
|
10
|
+
-----------------
|
|
11
|
+
|
|
12
|
+
The game is set on a network of cities on Mars, as described by Wildberger
|
|
13
|
+
[Wild2003]_. Consider a simple undirected graph *G* with *n* nodes, described
|
|
14
|
+
by its adjacency matrix *A* (where :math:`A_{ij} = 1` if nodes *i* and *j* are
|
|
15
|
+
connected, and 0 otherwise).
|
|
16
|
+
|
|
17
|
+
A **state** of the game is an integer vector :math:`v \in \mathbb{Z}^n`, where
|
|
18
|
+
each component :math:`v_i` represents the population at node *i*. Populations
|
|
19
|
+
can be positive ("Martians") or negative ("Anti-Martians") -- Wildberger's
|
|
20
|
+
original terminology.
|
|
21
|
+
|
|
22
|
+
A **mutation at node** *k* transforms the state according to the rule:
|
|
23
|
+
|
|
24
|
+
.. math::
|
|
25
|
+
|
|
26
|
+
v_k' = -v_k + \sum_{j \sim k} v_j
|
|
27
|
+
|
|
28
|
+
where the sum runs over all neighbors *j* of *k*. All other components remain
|
|
29
|
+
unchanged: :math:`v_i' = v_i` for :math:`i \neq k`.
|
|
30
|
+
|
|
31
|
+
Equivalently, the mutation at node *k* is the linear map :math:`v \mapsto M_k v`
|
|
32
|
+
where :math:`M_k` is the identity matrix with row *k* replaced:
|
|
33
|
+
|
|
34
|
+
.. math::
|
|
35
|
+
|
|
36
|
+
(M_k)_{ij} = \begin{cases}
|
|
37
|
+
-1 & \text{if } i = k \text{ and } j = k \\
|
|
38
|
+
A_{kj} & \text{if } i = k \text{ and } j \neq k \\
|
|
39
|
+
\delta_{ij} & \text{if } i \neq k
|
|
40
|
+
\end{cases}
|
|
41
|
+
|
|
42
|
+
Each mutation is an **involution**: :math:`M_k^2 = I`. Applying the same
|
|
43
|
+
mutation twice returns the state to its original value.
|
|
44
|
+
|
|
45
|
+
Root systems
|
|
46
|
+
------------
|
|
47
|
+
|
|
48
|
+
The **simple roots** are the standard basis vectors :math:`e_1, \ldots, e_n`.
|
|
49
|
+
Starting from these seeds, the **root system** :math:`\Phi` is the set of all
|
|
50
|
+
distinct vectors reachable by applying any sequence of mutations:
|
|
51
|
+
|
|
52
|
+
.. math::
|
|
53
|
+
|
|
54
|
+
\Phi = \{ M_{k_m} \cdots M_{k_2} M_{k_1} \, e_i
|
|
55
|
+
\mid i \in \{1, \ldots, n\},\;
|
|
56
|
+
k_1, \ldots, k_m \in \{1, \ldots, n\},\;
|
|
57
|
+
m \geq 0 \}
|
|
58
|
+
|
|
59
|
+
The root system decomposes into **positive roots** (all components
|
|
60
|
+
:math:`\geq 0`) and **negative roots** (all components :math:`\leq 0`). Every
|
|
61
|
+
root is either positive or negative, and :math:`v \in \Phi` implies
|
|
62
|
+
:math:`-v \in \Phi`.
|
|
63
|
+
|
|
64
|
+
Roots vs. bases
|
|
65
|
+
^^^^^^^^^^^^^^^
|
|
66
|
+
|
|
67
|
+
The simple roots :math:`e_1, \ldots, e_n` form a **basis** of
|
|
68
|
+
:math:`\mathbb{R}^n` -- they are linearly independent and span the space. The
|
|
69
|
+
root system, however, is much larger than a basis. For example, the A3 root
|
|
70
|
+
system lives in :math:`\mathbb{R}^3` (which needs only 3 basis vectors) but
|
|
71
|
+
contains 12 roots.
|
|
72
|
+
|
|
73
|
+
Every root can be written as an integer linear combination of simple roots:
|
|
74
|
+
positive roots have all non-negative coefficients, negative roots all
|
|
75
|
+
non-positive. But the roots are far from independent -- the root system is a
|
|
76
|
+
highly structured, symmetric set of vectors that the Weyl group permutes.
|
|
77
|
+
|
|
78
|
+
The Weyl group as a group of symmetries
|
|
79
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
80
|
+
|
|
81
|
+
The mutation matrices :math:`M_1, \ldots, M_n` generate a **group** under
|
|
82
|
+
matrix multiplication: the **Weyl group** :math:`W`. This group is finite for
|
|
83
|
+
ADE-type graphs and acts on the root system.
|
|
84
|
+
|
|
85
|
+
The group axioms are satisfied as follows:
|
|
86
|
+
|
|
87
|
+
- **Closure**: the product of any two mutation matrices (or compositions
|
|
88
|
+
thereof) is another element of *W*. In particular, for any root
|
|
89
|
+
:math:`v \in \Phi` and any mutation :math:`M_k`, the image
|
|
90
|
+
:math:`M_k v` is again a root in :math:`\Phi`.
|
|
91
|
+
- **Identity**: the identity matrix *I* is the "do nothing" mutation (apply
|
|
92
|
+
zero mutations).
|
|
93
|
+
- **Inverses**: each mutation is its own inverse (:math:`M_k^2 = I`), so
|
|
94
|
+
every generator is an involution. Arbitrary products are inverted by
|
|
95
|
+
reversing the order:
|
|
96
|
+
:math:`(M_{k_1} M_{k_2} \cdots M_{k_m})^{-1} = M_{k_m} \cdots M_{k_2} M_{k_1}`.
|
|
97
|
+
- **Associativity**: inherited from matrix multiplication.
|
|
98
|
+
|
|
99
|
+
The root system :math:`\Phi` is then an **orbit** of the simple roots under
|
|
100
|
+
this group action: :math:`\Phi = W \cdot \{e_1, \ldots, e_n\}` (together with
|
|
101
|
+
their negatives). The root system itself is *not* a group (it is not closed
|
|
102
|
+
under addition), but it is the set on which the Weyl group acts faithfully.
|
|
103
|
+
|
|
104
|
+
Finite and infinite types
|
|
105
|
+
-------------------------
|
|
106
|
+
|
|
107
|
+
Whether the root system is finite depends on the graph:
|
|
108
|
+
|
|
109
|
+
- **Finite type** -- The graph is a simply-laced Dynkin diagram (types A, D, E).
|
|
110
|
+
The mutation game terminates with a finite root system whose size is
|
|
111
|
+
determined by the type:
|
|
112
|
+
|
|
113
|
+
.. list-table::
|
|
114
|
+
:header-rows: 1
|
|
115
|
+
|
|
116
|
+
* - Type
|
|
117
|
+
- Graph structure
|
|
118
|
+
- Positive roots
|
|
119
|
+
- Total roots
|
|
120
|
+
* - :math:`A_n`
|
|
121
|
+
- Path on *n* nodes
|
|
122
|
+
- :math:`\frac{n(n+1)}{2}`
|
|
123
|
+
- :math:`n(n+1)`
|
|
124
|
+
* - :math:`D_n` (:math:`n \geq 4`)
|
|
125
|
+
- Path with a fork at one end
|
|
126
|
+
- :math:`n(n-1)`
|
|
127
|
+
- :math:`2n(n-1)`
|
|
128
|
+
* - :math:`E_6`
|
|
129
|
+
- See below
|
|
130
|
+
- 36
|
|
131
|
+
- 72
|
|
132
|
+
* - :math:`E_7`
|
|
133
|
+
- See below
|
|
134
|
+
- 63
|
|
135
|
+
- 126
|
|
136
|
+
* - :math:`E_8`
|
|
137
|
+
- See below
|
|
138
|
+
- 120
|
|
139
|
+
- 240
|
|
140
|
+
|
|
141
|
+
- **Infinite type** -- For any other connected graph (e.g. a cycle, or a tree
|
|
142
|
+
not of ADE type), the mutation process generates infinitely many distinct
|
|
143
|
+
roots.
|
|
144
|
+
|
|
145
|
+
The Cartan matrix and finite-type classification
|
|
146
|
+
-------------------------------------------------
|
|
147
|
+
|
|
148
|
+
The **Cartan matrix** of the graph is:
|
|
149
|
+
|
|
150
|
+
.. math::
|
|
151
|
+
|
|
152
|
+
C = 2I - A
|
|
153
|
+
|
|
154
|
+
The type of the root system is determined entirely by the spectrum of *C*:
|
|
155
|
+
|
|
156
|
+
- **Positive definite** (all eigenvalues :math:`> 0`): the root system is
|
|
157
|
+
**finite**. This happens exactly for the ADE Dynkin diagrams.
|
|
158
|
+
- **Positive semi-definite** (smallest eigenvalue :math:`= 0`): the root system
|
|
159
|
+
is **affine** (infinite, but with controlled growth). Example: a cycle graph.
|
|
160
|
+
- **Indefinite** (a negative eigenvalue): the root system is **infinite** with
|
|
161
|
+
no finiteness structure.
|
|
162
|
+
|
|
163
|
+
The library uses this criterion directly: ``is_finite_type()`` checks whether
|
|
164
|
+
the Cartan matrix is positive definite. Methods that require the full root
|
|
165
|
+
system (``calculate_roots``, ``plot_root_orbits``, etc.) raise a
|
|
166
|
+
``RuntimeError`` early if the graph is not finite type, rather than running
|
|
167
|
+
an unbounded BFS.
|
|
168
|
+
|
|
169
|
+
.. code-block:: pycon
|
|
170
|
+
|
|
171
|
+
>>> from mutation import MutationGame
|
|
172
|
+
>>> game = MutationGame.from_dynkin("D4")
|
|
173
|
+
>>> game.is_finite_type()
|
|
174
|
+
True
|
|
175
|
+
>>> print(game.cartan_eigenvalues())
|
|
176
|
+
[0.58578644 2. 2. 3.41421356]
|
|
177
|
+
|
|
178
|
+
>>> cycle = MutationGame([[0,1,1],[1,0,1],[1,1,0]])
|
|
179
|
+
>>> cycle.is_finite_type()
|
|
180
|
+
False
|
|
181
|
+
>>> print(cycle.cartan_eigenvalues())
|
|
182
|
+
[0. 3. 3.]
|
|
183
|
+
|
|
184
|
+
Eigenvectors of the Cartan matrix
|
|
185
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
186
|
+
|
|
187
|
+
Since :math:`C = 2I - A`, the eigenvectors of *C* are exactly the eigenvectors
|
|
188
|
+
of the adjacency matrix *A* (only the eigenvalues shift: if
|
|
189
|
+
:math:`A v = \lambda v` then :math:`C v = (2 - \lambda) v`).
|
|
190
|
+
|
|
191
|
+
The bilinear form :math:`\langle v, w \rangle = v^T C \, w` is the natural
|
|
192
|
+
**inner product** on the root lattice. The Weyl group preserves this form --
|
|
193
|
+
every mutation matrix satisfies :math:`M_k^T C \, M_k = C`. For simple roots,
|
|
194
|
+
:math:`\langle e_i, e_j \rangle = C_{ij}`, so the Cartan matrix is literally
|
|
195
|
+
the **Gram matrix** of the simple roots under this inner product.
|
|
196
|
+
|
|
197
|
+
The **Perron--Frobenius eigenvector** (the eigenvector of *A* with the largest
|
|
198
|
+
eigenvalue, equivalently the eigenvector of *C* with the smallest eigenvalue)
|
|
199
|
+
has all positive entries and is closely related to the **highest root** -- the
|
|
200
|
+
positive root with the largest height in the system.
|
|
201
|
+
|
|
202
|
+
.. code-block:: pycon
|
|
203
|
+
|
|
204
|
+
>>> game = MutationGame.from_dynkin("A3")
|
|
205
|
+
>>> vals, vecs = game.cartan_eigenvectors()
|
|
206
|
+
>>> print("Eigenvalues:", vals)
|
|
207
|
+
Eigenvalues: [0.58578644 2. 3.41421356]
|
|
208
|
+
>>> print("Perron-Frobenius eigenvector:", vecs[:, 0])
|
|
209
|
+
Perron-Frobenius eigenvector: [ 0.5 0.70710678 0.5 ]
|
|
210
|
+
|
|
211
|
+
Connection to Lie theory
|
|
212
|
+
------------------------
|
|
213
|
+
|
|
214
|
+
The mutation game is a combinatorial realization of the **Weyl group** action
|
|
215
|
+
on a root system [Wild2003]_ [Wild2020]_. The mutation matrices :math:`M_k`
|
|
216
|
+
are the **simple reflections** :math:`s_k` of the Weyl group *W(G)*, and the
|
|
217
|
+
root system :math:`\Phi` produced by the game coincides with the root system of
|
|
218
|
+
the corresponding simply-laced Lie algebra. Wildberger showed that the graphs
|
|
219
|
+
for which the mutation game produces a finite root system are precisely the
|
|
220
|
+
Dynkin diagrams of finite-dimensional complex simple Lie algebras. A related
|
|
221
|
+
purely combinatorial construction of the Lie algebras themselves for
|
|
222
|
+
simply-laced diagrams is given in [Wild2003b]_.
|
|
223
|
+
|
|
224
|
+
The simple reflection at node *k* acts on the weight lattice as:
|
|
225
|
+
|
|
226
|
+
.. math::
|
|
227
|
+
|
|
228
|
+
s_k(v) = v - (C v)_k \, e_k = v - (2 v_k - \sum_{j \sim k} v_j) \, e_k
|
|
229
|
+
|
|
230
|
+
which is precisely the mutation rule:
|
|
231
|
+
:math:`v_k \mapsto -v_k + \sum_{j \sim k} v_j`.
|
|
232
|
+
|
|
233
|
+
The mutation graph
|
|
234
|
+
------------------
|
|
235
|
+
|
|
236
|
+
The **mutation graph** has the roots as vertices and an edge between two roots
|
|
237
|
+
whenever one can be obtained from the other by a single mutation. Each edge is
|
|
238
|
+
labeled with the index of the mutated node.
|
|
239
|
+
|
|
240
|
+
For finite-type graphs, the mutation graph is a finite connected graph whose
|
|
241
|
+
structure encodes the combinatorics of the Weyl group. The shortest path
|
|
242
|
+
between two roots in this graph gives the minimal sequence of mutations (simple
|
|
243
|
+
reflections) needed to transform one into the other.
|
|
244
|
+
|
|
245
|
+
References
|
|
246
|
+
----------
|
|
247
|
+
|
|
248
|
+
.. [Wild2003] N. J. Wildberger, "The Mutation Game, Coxeter Graphs, and
|
|
249
|
+
Partially Ordered Multisets," preprint, UNSW, 2003.
|
|
250
|
+
https://web.maths.unsw.edu.au/~norman/papers/MutationGameCoxeterGraphs.pdf
|
|
251
|
+
|
|
252
|
+
.. [Wild2020] N. J. Wildberger, "The Mutation Game, Coxeter--Dynkin Graphs,
|
|
253
|
+
and Generalized Root Systems," *Algebra Colloquium*, vol. 27, no. 1,
|
|
254
|
+
pp. 55--78, 2020.
|
|
255
|
+
|
|
256
|
+
.. [Wild2003b] N. J. Wildberger, "A Combinatorial Construction for
|
|
257
|
+
Simply-Laced Lie Algebras," *Advances in Applied Mathematics*, vol. 30,
|
|
258
|
+
no. 1--2, pp. 385--396, 2003.
|
|
259
|
+
doi:`10.1016/S0196-8858(02)00541-9 <https://doi.org/10.1016/S0196-8858(02)00541-9>`_
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
project = "Mutation Game"
|
|
2
|
+
copyright = "2026"
|
|
3
|
+
author = ""
|
|
4
|
+
|
|
5
|
+
extensions = [
|
|
6
|
+
"sphinx.ext.autodoc",
|
|
7
|
+
"sphinx.ext.napoleon",
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
html_theme = "sphinx_rtd_theme"
|
|
11
|
+
html_static_path = ["_static"]
|
|
12
|
+
|
|
13
|
+
import os, sys
|
|
14
|
+
sys.path.insert(0, os.path.abspath(os.path.join("..", "src")))
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Generate example images for the documentation."""
|
|
2
|
+
import sys, os
|
|
3
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
|
|
4
|
+
import matplotlib
|
|
5
|
+
matplotlib.use("Agg")
|
|
6
|
+
|
|
7
|
+
from mutation_game import MutationGame
|
|
8
|
+
|
|
9
|
+
# A3 positive roots
|
|
10
|
+
game = MutationGame.from_dynkin("A3")
|
|
11
|
+
fig = game.plot_root_orbits(positive_only=True)
|
|
12
|
+
fig.savefig("_static/a3_positive.png", bbox_inches="tight", dpi=150)
|
|
13
|
+
|
|
14
|
+
# A3 all roots
|
|
15
|
+
fig = game.plot_root_orbits(positive_only=False)
|
|
16
|
+
fig.savefig("_static/a3_all.png", bbox_inches="tight", dpi=150)
|
|
17
|
+
|
|
18
|
+
# D4 positive roots
|
|
19
|
+
game = MutationGame.from_dynkin("D4")
|
|
20
|
+
fig = game.plot_root_orbits(positive_only=True)
|
|
21
|
+
fig.savefig("_static/d4_positive.png", bbox_inches="tight", dpi=150)
|
|
22
|
+
|
|
23
|
+
# E6 positive roots
|
|
24
|
+
game = MutationGame.from_dynkin("E6")
|
|
25
|
+
fig = game.plot_root_orbits(positive_only=True)
|
|
26
|
+
fig.savefig("_static/e6_positive.png", bbox_inches="tight", dpi=150)
|
|
27
|
+
|
|
28
|
+
print("Images generated.")
|