start pythonifying data
This commit is contained in:
parent
55cb9ddd3d
commit
2c1775e8f2
0
posts/permutations/2/graph_data/__init__.py
Normal file
0
posts/permutations/2/graph_data/__init__.py
Normal file
135
posts/permutations/2/graph_data/base.py
Normal file
135
posts/permutations/2/graph_data/base.py
Normal file
@ -0,0 +1,135 @@
|
||||
from dataclasses import dataclass
|
||||
import sympy
|
||||
from sympy.abc import x
|
||||
|
||||
|
||||
def display_integral_root(
|
||||
root: int, multiplicity: int, pad_to: int | None = None
|
||||
) -> str:
|
||||
return (
|
||||
"("
|
||||
# denote sign
|
||||
+ ("\\pm" if root != 0 else "")
|
||||
+ str(root)
|
||||
+ ")^{"
|
||||
+ str(multiplicity)
|
||||
# pad multiplicity
|
||||
+ ("\\phantom{" + ("0" * pad_to) + "}" if pad_to is not None else "")
|
||||
+ "}"
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class SymmetricSpectrum:
|
||||
"""
|
||||
Dataclass for symmetric spectra -- those for which, if a spectrum contains a root,
|
||||
it also contains its negative.
|
||||
|
||||
If a root polynomial is not symmetric, then its symmetric counterpart will *not* be specified.
|
||||
"""
|
||||
|
||||
# Either the integral root or a polynomial with the root, and the multiplicity
|
||||
roots: list[tuple[sympy.Expr | int, int]]
|
||||
not_shown_count: int = 0
|
||||
|
||||
def to_markdown(self) -> str:
|
||||
"""
|
||||
Display a spectrum as a markdown string
|
||||
"""
|
||||
integer_roots = [
|
||||
(root, multiplicity)
|
||||
for root, multiplicity in self.roots
|
||||
if isinstance(root, int)
|
||||
]
|
||||
# symmetrify polynomials
|
||||
polynomial_roots = [
|
||||
(root, multiplicity)
|
||||
for base_root, multiplicity in self.roots
|
||||
if isinstance(base_root, sympy.Expr)
|
||||
for root in set(
|
||||
[base_root, (-1) ** (sympy.degree(base_root)) * base_root.subs(x, -x)]
|
||||
)
|
||||
]
|
||||
|
||||
shown_roots = len(polynomial_roots) > 0 or len(integer_roots) > 0
|
||||
not_shown_string = (
|
||||
(
|
||||
f"Not shown: {self.not_shown_count} other roots"
|
||||
if shown_roots
|
||||
else f"Not shown: all {self.not_shown_count} roots"
|
||||
)
|
||||
if self.not_shown_count > 0
|
||||
else ""
|
||||
)
|
||||
|
||||
# strictly integral spectra
|
||||
if len(polynomial_roots) == 0 and len(integer_roots) != 0:
|
||||
longest_integer = max(
|
||||
len(str(multiplicity)) for _, multiplicity in integer_roots
|
||||
)
|
||||
return (
|
||||
(
|
||||
"$$\\begin{gather*}"
|
||||
+ " \\\\ ".join(
|
||||
display_integral_root(*rm, pad_to=longest_integer)
|
||||
for rm in integer_roots
|
||||
)
|
||||
+ "\\end{gather*}$$"
|
||||
)
|
||||
if shown_roots
|
||||
else ""
|
||||
) + not_shown_string
|
||||
|
||||
# conditionally split integral roots onto multiple lines
|
||||
integral_roots_lines = (
|
||||
" ".join(display_integral_root(*rm) for rm in integer_roots)
|
||||
if len(integer_roots) < 5
|
||||
else (
|
||||
" ".join(
|
||||
display_integral_root(*rm)
|
||||
for rm in integer_roots[: len(integer_roots) // 2]
|
||||
)
|
||||
+ "\\\\"
|
||||
+ " ".join(
|
||||
display_integral_root(*rm)
|
||||
for rm in integer_roots[len(integer_roots) // 2 :]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return ((
|
||||
"$$\\begin{gather*}"
|
||||
+ integral_roots_lines
|
||||
+ " \\\\ "
|
||||
+ " \\\\ ".join(
|
||||
sympy.latex(root**multiplicity)
|
||||
for root, multiplicity in polynomial_roots
|
||||
)
|
||||
+ "\\end{gather*}$$"
|
||||
)
|
||||
if shown_roots
|
||||
else ""
|
||||
) + not_shown_string
|
||||
|
||||
|
||||
def count_roots_spectrum(spectrum: SymmetricSpectrum) -> int:
|
||||
return (
|
||||
sum(
|
||||
[
|
||||
(
|
||||
(multiplicity * 2 if root != 0 else multiplicity)
|
||||
if isinstance(root, int)
|
||||
else (int(sympy.degree(root, x)) * multiplicity)
|
||||
)
|
||||
for root, multiplicity in spectrum.roots
|
||||
]
|
||||
)
|
||||
+ spectrum.not_shown_count
|
||||
)
|
||||
|
||||
@dataclass
|
||||
class GraphData:
|
||||
vertex_count: int
|
||||
edge_count: int
|
||||
distance_classes: list[int]
|
||||
spectrum: SymmetricSpectrum
|
||||
50
posts/permutations/2/graph_data/complete.py
Normal file
50
posts/permutations/2/graph_data/complete.py
Normal file
@ -0,0 +1,50 @@
|
||||
from .base import SymmetricSpectrum
|
||||
|
||||
# TODO: other non-spectral data
|
||||
complete_spectra = {
|
||||
3: SymmetricSpectrum([(0, 4), (3, 1)]),
|
||||
4: SymmetricSpectrum([(0, 4), (2, 9), (6, 1)]),
|
||||
5: SymmetricSpectrum(
|
||||
[
|
||||
(0, 36),
|
||||
(2, 25),
|
||||
(5, 16),
|
||||
(10, 1),
|
||||
]
|
||||
),
|
||||
6: SymmetricSpectrum(
|
||||
[
|
||||
(0, 256),
|
||||
(3, 125),
|
||||
(5, 81),
|
||||
(9, 25),
|
||||
(15, 1),
|
||||
]
|
||||
),
|
||||
7: SymmetricSpectrum(
|
||||
[
|
||||
(0, 400),
|
||||
(1, 441),
|
||||
(3, 1225),
|
||||
(6, 196),
|
||||
(7, 225),
|
||||
(9, 196),
|
||||
(14, 36),
|
||||
(21, 1),
|
||||
]
|
||||
),
|
||||
# TODO: missing a root (and its negative) of multiplicity 400
|
||||
8: SymmetricSpectrum(
|
||||
[
|
||||
(0, 9864),
|
||||
(2, 3136),
|
||||
(4, 6125),
|
||||
(7, 4096),
|
||||
(8, 196),
|
||||
(10, 784),
|
||||
(12, 441),
|
||||
(20, 49),
|
||||
(28, 1),
|
||||
]
|
||||
),
|
||||
}
|
||||
50
posts/permutations/2/graph_data/path.py
Normal file
50
posts/permutations/2/graph_data/path.py
Normal file
@ -0,0 +1,50 @@
|
||||
from .base import SymmetricSpectrum, x
|
||||
|
||||
path_spectra = {
|
||||
3: SymmetricSpectrum(
|
||||
[(1, 2), (2, 1)]
|
||||
),
|
||||
4: SymmetricSpectrum(
|
||||
[
|
||||
(1, 3),
|
||||
(3, 1),
|
||||
(x**2 - 3, 2),
|
||||
(x**2 - 2 * x - 1, 3),
|
||||
(x**2 + 2 * x - 1, 3),
|
||||
]
|
||||
),
|
||||
5: SymmetricSpectrum(
|
||||
[
|
||||
(0, 12),
|
||||
(1, 6),
|
||||
(4, 1),
|
||||
(x**2 - 5, 6),
|
||||
(x**2 + 5 * x + 5, 4),
|
||||
(x**2 + 3 * x + 1, 4),
|
||||
(x**2 + 2 * x - 1, 5),
|
||||
(x**3 + 2 * x**2 - 5 * x - 4, 5),
|
||||
]
|
||||
),
|
||||
6: SymmetricSpectrum(
|
||||
[
|
||||
(0, 20),
|
||||
(1, 25),
|
||||
(2, 15),
|
||||
(3, 5),
|
||||
(4, 5),
|
||||
(5, 1),
|
||||
(x**2 - 3, 20),
|
||||
],
|
||||
not_shown_count=558,
|
||||
),
|
||||
7: SymmetricSpectrum(
|
||||
[
|
||||
(0, 35),
|
||||
(1, 20),
|
||||
(2, 45),
|
||||
(6, 1),
|
||||
],
|
||||
not_shown_count=4873,
|
||||
),
|
||||
8: SymmetricSpectrum([], not_shown_count=40320),
|
||||
}
|
||||
55
posts/permutations/2/graph_data/star.py
Normal file
55
posts/permutations/2/graph_data/star.py
Normal file
@ -0,0 +1,55 @@
|
||||
from .base import SymmetricSpectrum
|
||||
|
||||
star_spectra = {
|
||||
3: SymmetricSpectrum([(1, 2), (2, 1)]),
|
||||
4: SymmetricSpectrum(
|
||||
[
|
||||
(0, 4),
|
||||
(1, 3),
|
||||
(2, 6),
|
||||
(3, 1),
|
||||
]
|
||||
),
|
||||
5: SymmetricSpectrum(
|
||||
[
|
||||
(0, 30),
|
||||
(1, 4),
|
||||
(2, 28),
|
||||
(3, 12),
|
||||
(4, 1),
|
||||
]
|
||||
),
|
||||
6: SymmetricSpectrum(
|
||||
[
|
||||
(0, 168),
|
||||
(1, 30),
|
||||
(2, 120),
|
||||
(3, 105),
|
||||
(4, 20),
|
||||
(5, 1),
|
||||
]
|
||||
),
|
||||
7: SymmetricSpectrum(
|
||||
[
|
||||
(0, 840),
|
||||
(1, 468),
|
||||
(2, 495),
|
||||
(3, 830),
|
||||
(4, 276),
|
||||
(5, 30),
|
||||
(6, 1),
|
||||
]
|
||||
),
|
||||
8: SymmetricSpectrum(
|
||||
[
|
||||
(0, 3960),
|
||||
(1, 5691),
|
||||
(2, 2198),
|
||||
(3, 6321),
|
||||
(4, 3332),
|
||||
(5, 595),
|
||||
(6, 42),
|
||||
(7, 1),
|
||||
]
|
||||
),
|
||||
}
|
||||
@ -19,6 +19,8 @@ categories:
|
||||
|
||||
from IPython.display import Markdown
|
||||
from tabulate import tabulate
|
||||
|
||||
from graph_data import complete, path, star
|
||||
```
|
||||
|
||||
|
||||
@ -234,51 +236,44 @@ In the case of these graphs, they are a partition of the factorial numbers.
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
mahonian = [
|
||||
[1, 2, 2, 1],
|
||||
[1, 3, 5, 6, 5, 3, 1],
|
||||
[1, 4, 9, 15, 20, 22, 20, 15, 9, 4, 1],
|
||||
[1, 5, 14, 29, 49, 71, 90, 101, 101, 90, 71, 49, 29, 14, 5, 1],
|
||||
[1, 6, 20, 49, 98, 169, 259, 359, 455, 531, 573, 573, 531, 455, 359, 259, 169, 98, 49, 20, 6, 1],
|
||||
]
|
||||
|
||||
whitney_second_kind = [
|
||||
[1, 2, 2, 1],
|
||||
[1, 3, 6, 9, 5],
|
||||
[1, 4, 12, 30, 44, 26, 3],
|
||||
[1, 5, 20, 70, 170, 250, 169, 35],
|
||||
[1, 6, 30, 135, 460, 1110, 1689, 1254, 340, 15],
|
||||
]
|
||||
|
||||
stirling_second_kind = [
|
||||
[1, 3, 2],
|
||||
[1, 6, 11, 6],
|
||||
[1, 10, 35, 50, 24],
|
||||
[1, 15, 85, 225, 274, 120],
|
||||
[1, 21, 175, 735, 1624, 1764, 720],
|
||||
]
|
||||
|
||||
half_break = lambda x: str(x[:len(x) // 2])[:-1] + "<br>" + str(x[len(x) // 2:])[1:]
|
||||
|
||||
Markdown(tabulate(
|
||||
[
|
||||
[
|
||||
3,
|
||||
"[1, 2, 2, 1]",
|
||||
"[1, 2, 2, 1]",
|
||||
"[1, 3, 2]"
|
||||
],
|
||||
[
|
||||
4,
|
||||
"[1, 3, 5, 6, 5, 3, 1]",
|
||||
"[1, 2, 2, 1]",
|
||||
"[1, 6, 11, 6]"
|
||||
],
|
||||
[
|
||||
5,
|
||||
"[1, 4, 9, 15, 20, 22, 20, 15, 9, 4, 1]",
|
||||
"[1, 4, 12, 30, 44, 26, 3]",
|
||||
"[1, 10, 35, 50, 24]"
|
||||
],
|
||||
[
|
||||
6,
|
||||
"[1, 5, 14, 29, 49, 71, 90, 101,<br>101, 90, 71, 49, 29, 14, 5, 1]",
|
||||
"[1, 5, 20, 70, 170, 250, 169, 35]",
|
||||
"[1, 15, 85, 225, 274, 120]"
|
||||
],
|
||||
[
|
||||
7,
|
||||
"[1, 6, 20, 49, 98, 169, 259, 359, 455, 531, 573,<br>573, 531, 455, 359, 259, 169, 98, 49, 20, 6, 1]",
|
||||
"[1, 6, 30, 135, 460, 1110, 1689, 1254, 340, 15]",
|
||||
"[1, 21, 175, 735, 1624, 1764, 720]"
|
||||
],
|
||||
[
|
||||
"Rule",
|
||||
"Mahonian numbers [OEIS A008302](http://oeis.org/A008302)",
|
||||
"Whitney numbers of the second kind (star poset) [OEIS A007799](http://oeis.org/A007799)",
|
||||
"Stirling numbers of the first kind [OEIS A132393](http://oeis.org/A132393)"
|
||||
],
|
||||
[i, j if i <= 5 else half_break(j), k, l]
|
||||
for i, j, k, l in zip(range(3,8), mahonian, whitney_second_kind, stirling_second_kind)
|
||||
],
|
||||
headers=[
|
||||
"*n*",
|
||||
r"$dists(\exp( P_n ))$",
|
||||
r"$dists(\exp( \bigstar_n ))$",
|
||||
r"$dists(\exp( K_n ))$"
|
||||
r"$\text{dists}(\exp( P_n ))$",
|
||||
r"$\text{dists}(\exp( \bigstar_n ))$",
|
||||
r"$\text{dists}(\exp( K_n ))$"
|
||||
]
|
||||
))
|
||||
```
|
||||
@ -297,130 +292,20 @@ Unfortunately, eigenvalues are not necessarily integers, and therefore not easil
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
|
||||
# TODO: less raw latex, more data converted to latex
|
||||
|
||||
f = lambda x: x.replace("\n", "")
|
||||
#| classes: plain
|
||||
|
||||
Markdown(tabulate(
|
||||
[
|
||||
[3, r"$(\pm 1)^2 (\pm 2)$", r"$(\pm 1)^2 (\pm 2)$", r"$(0)^4 (\pm 3)$"],
|
||||
[4, f(r"""$$
|
||||
\begin{gather*}
|
||||
(\pm 1)^3 (\pm 3) \\
|
||||
(x^2 -\ 3)^2 \\
|
||||
(x^2 -\ 2x -\ 1)^3
|
||||
(x^2 + 2x -\ 1)^3
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^4 \\
|
||||
(\pm 1)^3 \\
|
||||
(\pm 2)^6 \\
|
||||
(\pm 3)^{\phantom{0}}
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^4 \\
|
||||
(\pm 2)^9 \\
|
||||
(\pm 6)^{\phantom{0}}
|
||||
\end{gather*}$$""")],
|
||||
[5, f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{12} (\pm 1)^6 (\pm 4) \\
|
||||
(x^2 -\ 5)^6 \\
|
||||
(x^2 -\ 5x + 5)^4
|
||||
(x^2 + 5x + 5)^4 \\
|
||||
(x^2 -\ 3x + 1)^4
|
||||
(x^2 + 3x + 1)^4 \\
|
||||
(x^2 -\ 2x -\ 1)^5
|
||||
(x^2 + 2x -\ 1)^5 \\
|
||||
(x^3 -\ 2x^2 -\ 5x + 4)^5 \\
|
||||
(x^3 + 2x^2 -\ 5x -\ 4)^5
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{30} \\
|
||||
(\pm 1)^{4\phantom{0}} \\
|
||||
(\pm 2)^{28} \\
|
||||
(\pm 3)^{12} \\
|
||||
(\pm 4)^{\phantom{00}}
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{36} \\
|
||||
(\pm 2)^{25} \\
|
||||
(\pm 5)^{16} \\
|
||||
(\pm 10)^{\phantom{00}}
|
||||
\end{gather*}$$""")],
|
||||
[6, f(r"""$$\begin{gather*}
|
||||
(0)^{20} (\pm 1)^{25} (\pm 2)^{15} \\
|
||||
(\pm 3)^5 (\pm 4)^5 (\pm 5) \\
|
||||
(x^2 -\ 3)^{20} \\
|
||||
\end{gather*}
|
||||
$$ <br> *Not shown: 558 other roots*"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{168} \\
|
||||
(\pm 1)^{30\phantom{0}} \\
|
||||
(\pm 2)^{120} \\
|
||||
(\pm 3)^{105} \\
|
||||
(\pm 4)^{20\phantom{0}} \\
|
||||
(\pm 5)^{\phantom{000}}
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{256} \\
|
||||
(\pm 3)^{125} \\
|
||||
(\pm 5)^{81\phantom{0}} \\
|
||||
(\pm 9)^{25\phantom{0}} \\
|
||||
(\pm 15)^{\phantom{000}}
|
||||
\end{gather*}$$""")],
|
||||
[7, f(r"""
|
||||
$(0)^{35} (\pm 1)^{20} (\pm 2)^{45} (6)$ <br>
|
||||
*Not shown: 4873 other roots*
|
||||
"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{840} \\
|
||||
(\pm 1)^{468} \\
|
||||
(\pm 2)^{495} \\
|
||||
(\pm 3)^{830} \\
|
||||
(\pm 4)^{276} \\
|
||||
(\pm 5)^{30\phantom{0}} \\
|
||||
(\pm 6)^{\phantom{000}}
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{400\phantom{0}} \\
|
||||
(\pm 1)^{441\phantom{0}} \\
|
||||
(\pm 3)^{1225} \\
|
||||
(\pm 6)^{196\phantom{0}} \\
|
||||
(\pm 7)^{225\phantom{0}} \\
|
||||
(\pm 9)^{196\phantom{0}} \\
|
||||
(\pm 14)^{36\phantom{00}} \\
|
||||
(\pm 21)^{\phantom{0000}}
|
||||
\end{gather*}$$""")],
|
||||
[8, f(r"""*Not shown: all 40320 roots*"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{3960} \\
|
||||
(\pm 1)^{5691} \\
|
||||
(\pm 2)^{2198} \\
|
||||
(\pm 3)^{6321} \\
|
||||
(\pm 4)^{3332} \\
|
||||
(\pm 5)^{595\phantom{0}} \\
|
||||
(\pm 6)^{42\phantom{00}} \\
|
||||
(\pm 7)^{\phantom{0000}}
|
||||
\end{gather*}$$"""), f(r"""$$
|
||||
\begin{gather*}
|
||||
(0)^{9864} \\
|
||||
(\pm 2)^{3136} \\
|
||||
(\pm 4)^{6125} \\
|
||||
(\pm 7)^{4096} \\
|
||||
(\pm 8)^{196\phantom{0}} \\
|
||||
(\pm 10)^{784\phantom{0}} \\
|
||||
(\pm 12)^{441\phantom{0}} \\
|
||||
(\pm 20)^{49\phantom{00}} \\
|
||||
(\pm 28)^{\phantom{0000}}
|
||||
\end{gather*}$$""")
|
||||
],
|
||||
[i, pathG.to_markdown(), starG.to_markdown(), completeG.to_markdown()]
|
||||
for i in range(3, 9)
|
||||
for pathG, starG, completeG in (
|
||||
[path.path_spectra[i], star.star_spectra[i], complete.complete_spectra[i]],
|
||||
)
|
||||
],
|
||||
headers=[
|
||||
"*n*",
|
||||
r"$\text{Spec}(\exp( P_n ))$",
|
||||
r"$\text{Spec}(\exp( \bigstar_n)$",
|
||||
r"$\text{Spec}(\exp( \bigstar_n )$",
|
||||
r"$\text{Spec}(\exp( K_n ))$"
|
||||
]
|
||||
))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user