refactor pentagons.3
This commit is contained in:
parent
6caf4640ac
commit
bbf141785e
@ -33,8 +33,6 @@ import matplotlib.pyplot as plt
|
||||
from tabulate import tabulate
|
||||
|
||||
from goldberg.common import (
|
||||
GoldbergData,
|
||||
GoldbergOperator,
|
||||
hexagons_to_polyhedron,
|
||||
group_dict,
|
||||
link_polyhedronisme,
|
||||
|
||||
1
posts/pentagons/3/goldberg
Symbolic link
1
posts/pentagons/3/goldberg
Symbolic link
@ -0,0 +1 @@
|
||||
../1/goldberg
|
||||
@ -12,27 +12,11 @@ categories:
|
||||
- geometry
|
||||
- combinatorics
|
||||
- symmetry
|
||||
# Get rid of the figure label
|
||||
crossref:
|
||||
fig-title: ""
|
||||
fig-labels: " "
|
||||
tbl-title: ""
|
||||
tbl-labels: " "
|
||||
title-delim: ""
|
||||
custom:
|
||||
- key: fig
|
||||
kind: float
|
||||
reference-prefix: Figure
|
||||
space-before-numbering: false
|
||||
- key: tbl
|
||||
kind: float
|
||||
reference-prefix: Table
|
||||
space-before-numbering: false
|
||||
---
|
||||
|
||||
<style>
|
||||
.image-wide {
|
||||
width: 384px;
|
||||
width: 192px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@ -43,8 +27,7 @@ crossref:
|
||||
</style>
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, asdict
|
||||
import itertools
|
||||
from typing import Callable, TypeAlias
|
||||
|
||||
@ -52,28 +35,91 @@ from IPython.display import Markdown
|
||||
import sympy
|
||||
from tabulate import tabulate
|
||||
|
||||
@dataclass
|
||||
class PolyData:
|
||||
hexagon_count: int
|
||||
vertex_count: int
|
||||
edge_count: int
|
||||
from goldberg.common import (
|
||||
hexagons_to_polyhedron,
|
||||
group_dict,
|
||||
link_polyhedronisme,
|
||||
)
|
||||
from goldberg.operators import (
|
||||
t_param,
|
||||
GoldbergOperator,
|
||||
goldberg_operators,
|
||||
goldberg_operators_to_parameters,
|
||||
loeschian_numbers,
|
||||
loeschian_norm,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_hexagons(cls, hexagon_count: int):
|
||||
return cls(
|
||||
hexagon_count=hexagon_count,
|
||||
vertex_count=2*hexagon_count + 20,
|
||||
edge_count=3*hexagon_count + 30,
|
||||
n_param, aux_t_param, temp_param = sympy.symbols("n T' x")
|
||||
from_base_case = lambda x: (t_param * (x + 10) - 10)
|
||||
|
||||
@dataclass
|
||||
class MiniConwayTable:
|
||||
conway: str
|
||||
hexagon_count: str
|
||||
vertex_count: str
|
||||
edge_count: str
|
||||
|
||||
as_maybe_tex = lambda x: x if isinstance(x, int) or not x.has_free(t_param) else f"${sympy.latex(x)}$"
|
||||
as_maybe_recipe_link = lambda x, recipe: x if recipe is None else link_polyhedronisme(x, recipe)
|
||||
|
||||
def display_mini_conway_table(
|
||||
base_case_hexagons: int,
|
||||
base_case_name: str,
|
||||
recipes: dict[str, str] = {},
|
||||
) -> Markdown:
|
||||
headers = MiniConwayTable(
|
||||
"Conway",
|
||||
"$F_6$",
|
||||
"V",
|
||||
"E",
|
||||
)
|
||||
|
||||
rows = [
|
||||
MiniConwayTable(
|
||||
conway=recipe,
|
||||
hexagon_count=str(as_maybe_tex(polyhedron.face_count - 12)),
|
||||
vertex_count=str(as_maybe_tex(polyhedron.vertex_count)),
|
||||
edge_count=str(as_maybe_tex(polyhedron.edge_count)),
|
||||
)
|
||||
# base row list
|
||||
for operator in ["", "dk", "c", "w", "tk", "g_T"]
|
||||
# try lookup (a, b) tuple in parameter dict
|
||||
for maybe_parameter in (goldberg_operators_to_parameters.get(operator),)
|
||||
# combinatorially construct polyhedron from the base case and (maybe) the parameter
|
||||
for polyhedron in (
|
||||
(
|
||||
hexagons_to_polyhedron(base_case_hexagons)
|
||||
if operator == ""
|
||||
else hexagons_to_polyhedron(
|
||||
from_base_case(base_case_hexagons).expand().subs(
|
||||
# if the lookup failed, leave the T parameter free
|
||||
t_param,
|
||||
loeschian_norm(*maybe_parameter)
|
||||
if maybe_parameter is not None
|
||||
else t_param
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
# pull the recipe from the `recipes` dict
|
||||
for recipe in (
|
||||
as_maybe_recipe_link(
|
||||
f"${operator + base_case_name.split(' ')[-1]}$"
|
||||
if operator == ""
|
||||
else f"${base_case_name}$",
|
||||
recipes.get(operator),
|
||||
),
|
||||
)
|
||||
]
|
||||
|
||||
@dataclass
|
||||
class GoldbergData:
|
||||
parameter: tuple[int, int]
|
||||
conway: str
|
||||
|
||||
parameter_link: str | None = None
|
||||
conway_recipe: str | None = None
|
||||
return Markdown(tabulate(
|
||||
{
|
||||
field: [name] + [getattr(item, field) for item in rows]
|
||||
for field, name in asdict(headers).items()
|
||||
},
|
||||
headers="firstrow",
|
||||
numalign="left",
|
||||
))
|
||||
```
|
||||
|
||||
|
||||
@ -91,59 +137,79 @@ Yet more unconventional solutions are presented below.
|
||||
Combinatorics of Goldberg-Coxeter Operators
|
||||
-------------------------------------------
|
||||
|
||||
In the first post, we established that a solution figure *S* has feature counts
|
||||
which are parametrized entirely by $F_6$:
|
||||
|
||||
$$
|
||||
S = \begin{pmatrix} v \\ e \\ f \end{pmatrix}
|
||||
= \begin{pmatrix}
|
||||
2F_6 + 20 \\
|
||||
3F_6 + 30 \\
|
||||
F_6 + 12
|
||||
\end{pmatrix}
|
||||
= \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
|
||||
+ \begin{pmatrix} 20 \\ 30 \\ 12 \end{pmatrix}
|
||||
$$
|
||||
|
||||
In the last post, it was discovered that certain solutions cannot be created easily from seed polyhedra
|
||||
in a polyhedron viewer.
|
||||
This prompts the question of how to calculate the vertex, edge, and face counts
|
||||
without acquiring them from the output of such a program.
|
||||
|
||||
Each of the simple GC operators (*c*, *dk*, and *w*) has a combinatoric matrix form
|
||||
which can be applied to a vector of the vertex, edge, and face counts of a figure *S*.
|
||||
Fortunatelly, each of the simple GC operators (*dk*, *c*, and *w*) has a combinatoric matrix form[^1].
|
||||
|
||||
$$
|
||||
\begin{gather*}
|
||||
S = \begin{pmatrix} v \\ e \\ f \end{pmatrix}
|
||||
= \begin{pmatrix}
|
||||
2F_6 + 20 \\
|
||||
3F_6 + 30 \\
|
||||
F_6 + 12
|
||||
\end{pmatrix}
|
||||
= \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
|
||||
+ \begin{pmatrix} 20 \\ 30 \\ 12 \end{pmatrix} \\
|
||||
\underset{
|
||||
\text{Class I}
|
||||
}{
|
||||
c = \begin{pmatrix}
|
||||
1 & 2 & 0 \\
|
||||
0 & 4 & 0 \\
|
||||
0 & 1 & 1
|
||||
\end{pmatrix}
|
||||
} \quad
|
||||
\underset{
|
||||
\text{Class II}
|
||||
}{
|
||||
dk = \begin{pmatrix}
|
||||
0 & 2 & 0 \\
|
||||
0 & 3 & 0 \\
|
||||
1 & 0 & 1
|
||||
\end{pmatrix}
|
||||
} \quad
|
||||
\underset{
|
||||
\text{Class III}
|
||||
}{
|
||||
w = \begin{pmatrix}
|
||||
1 & 4 & 0 \\
|
||||
0 & 7 & 0 \\
|
||||
0 & 2 & 1
|
||||
\end{pmatrix}
|
||||
}
|
||||
\end{gather*}
|
||||
\underset{
|
||||
\text{Class I}
|
||||
}{
|
||||
c = \begin{pmatrix}
|
||||
1 & 2 & 0 \\
|
||||
0 & 4 & 0 \\
|
||||
0 & 1 & 1
|
||||
\end{pmatrix}
|
||||
} \quad
|
||||
\underset{
|
||||
\text{Class II}
|
||||
}{
|
||||
dk = \begin{pmatrix}
|
||||
0 & 2 & 0 \\
|
||||
0 & 3 & 0 \\
|
||||
1 & 0 & 1
|
||||
\end{pmatrix}
|
||||
} \quad
|
||||
\underset{
|
||||
\text{Class III}
|
||||
}{
|
||||
w = \begin{pmatrix}
|
||||
1 & 4 & 0 \\
|
||||
0 & 7 & 0 \\
|
||||
0 & 2 & 1
|
||||
\end{pmatrix}
|
||||
}
|
||||
$$
|
||||
|
||||
[^1]:
|
||||
These matrices can be derived by closely observing the vertex, edge, and face counts of a figure before
|
||||
and after applying the operator.
|
||||
Gather the feature counts of the tetrahedron, dodecahedron, and icosahedron into a matrix.
|
||||
|
||||
$$
|
||||
\begin{gather*}
|
||||
f \begin{pmatrix} | & | & | \\ T & D & I \\ | & | & | \end{pmatrix}
|
||||
= f \begin{pmatrix} 4 & 20 & 12 \\ 6 & 30 & 30 \\ 4 & 12 & 20 \end{pmatrix}
|
||||
= \begin{pmatrix} | & | & | \\ fT & fD & fI \\ | & | & | \end{pmatrix} \\
|
||||
f = \begin{pmatrix} | & | & | \\ fT & fD & fI \\ | & | & | \end{pmatrix}
|
||||
\begin{pmatrix} 4 & 20 & 12 \\ 6 & 30 & 30 \\ 4 & 12 & 20 \end{pmatrix}^{-1}
|
||||
\end{gather*}
|
||||
$$
|
||||
|
||||
This matrix is invertible, and the feature counts for *fT*, *fD*, and *fI* can be acquired from a viewer
|
||||
implementing the operator *f*.
|
||||
|
||||
These operators are labelled with the classes of Goldberg polyhedra they construct
|
||||
when applied to the dodecahedron.
|
||||
|
||||
- *cD* = GC(2, 0)
|
||||
- *dkD* = *tI* = GC(1, 1)
|
||||
- *cD* = GC(2, 0)
|
||||
- *wD* = GC(2, 1)
|
||||
|
||||
It's worth noting again that *dk* alternates between producing Class I and Class II solutions.
|
||||
@ -156,83 +222,41 @@ Unlike it, it preserves solution class.
|
||||
Powers of a matrix are more readily expressed when the matrix is diagonalized.
|
||||
Diagonalizing each of these operators shows that they have something in common.
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
c &= \begin{pmatrix}
|
||||
1 & 2 & 0 \\
|
||||
0 & 4 & 0 \\
|
||||
0 & 1 & 1
|
||||
\end{pmatrix}
|
||||
= \textcolor{red}{
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
}
|
||||
\begin{pmatrix}
|
||||
1 & 0 & 0 \\
|
||||
0 & 1 & 0 \\
|
||||
0 & 0 & 4
|
||||
\end{pmatrix}
|
||||
\textcolor{blue}{
|
||||
\begin{pmatrix}
|
||||
1 & -2/3 & 0 \\
|
||||
1 & -1 & 1 \\
|
||||
0 & 1/3 & 0
|
||||
\end{pmatrix}
|
||||
} \\
|
||||
dk &= \begin{pmatrix}
|
||||
0 & 2 & 0 \\
|
||||
0 & 3 & 0 \\
|
||||
1 & 0 & 1
|
||||
\end{pmatrix}
|
||||
= \textcolor{red}{
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
}
|
||||
\begin{pmatrix}
|
||||
0 & 0 & 0 \\
|
||||
0 & 1 & 0 \\
|
||||
0 & 0 & 3
|
||||
\end{pmatrix}
|
||||
\textcolor{blue}{
|
||||
\begin{pmatrix}
|
||||
1 & -2/3 & 0 \\
|
||||
1 & -1 & 1 \\
|
||||
0 & 1/3 & 0
|
||||
\end{pmatrix}
|
||||
}
|
||||
\\
|
||||
w &= \begin{pmatrix}
|
||||
1 & 4 & 0 \\
|
||||
0 & 7 & 0 \\
|
||||
0 & 2 & 1
|
||||
\end{pmatrix}
|
||||
= \textcolor{red}{
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
}
|
||||
\begin{pmatrix}
|
||||
1 & 0 & 0 \\
|
||||
0 & 1 & 0 \\
|
||||
0 & 0 & 7
|
||||
\end{pmatrix}
|
||||
\textcolor{blue}{
|
||||
\begin{pmatrix}
|
||||
1 & -2/3 & 0 \\
|
||||
1 & -1 & 1 \\
|
||||
0 & 1/3 & 0
|
||||
\end{pmatrix}
|
||||
}
|
||||
\end{align*}
|
||||
$$
|
||||
```{python}
|
||||
# diagonalizing dk gives an eigenspace which shows the 3V = 2E condition
|
||||
# and Euler characteristic more clearly
|
||||
eigenspace, _ = goldberg_operators["dk"].diagonalize()
|
||||
|
||||
def show_diagonalized(operator: GoldbergOperator):
|
||||
assert operator != "g_T"
|
||||
matrix = goldberg_operators[operator]
|
||||
diag = eigenspace.inv() @ matrix @ eigenspace
|
||||
|
||||
return f"""{
|
||||
sympy.latex(matrix)
|
||||
} = \\textcolor{{red}}{{{
|
||||
sympy.latex(eigenspace)
|
||||
}}}{
|
||||
sympy.latex(diag)
|
||||
}\\textcolor{{blue}}{{{
|
||||
sympy.latex(eigenspace.inv(), fold_short_frac=True)
|
||||
}}}"""
|
||||
|
||||
Markdown(f"""
|
||||
$$
|
||||
\\begin{{align*}}
|
||||
dk &= {show_diagonalized("dk")} \\\\
|
||||
c &= {show_diagonalized("c")} \\\\
|
||||
w &= {show_diagonalized("w")}
|
||||
\\end{{align*}}
|
||||
$$
|
||||
""".replace(
|
||||
"\\left[\\begin{matrix}", "\\begin{pmatrix}"
|
||||
).replace(
|
||||
"\\end{matrix}\\right]", "\\end{pmatrix}"
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
All of these operators share the same eigenvectors, which can be seen
|
||||
in the columns of the left outer matrix and rows of the right outer one.
|
||||
@ -243,7 +267,7 @@ Some of these eigenvectors have special interpretations:
|
||||
|
||||
- The left eigenvector (1, -1, 1) (right matrix, middle row) always has eigenvalue 1.
|
||||
- This means that the operation does not change the Euler characteristic.
|
||||
- The left eigenvector (3, -2, 0) (right matrix, top row), when applied to general polyhedra
|
||||
- The left eigenvector (3, -2, 0) (right matrix, top row), when applied to general polyhedra,
|
||||
corresponds to the edges and vertices added by the operation:
|
||||
- In *dk*, this vector has eigenvalue 0, forcing $3V = 2E$, i.e., all vertices to have degree 3.
|
||||
- In *c* and *w*, this vector has eigenvalue 1. These operators only add degree-3 vertices.
|
||||
@ -265,10 +289,10 @@ $$
|
||||
Call this number $T = \|a + bu\| = a^2 + ab + b^2$.
|
||||
We know that integers of this form are never congruent to 2 (mod 3).
|
||||
Conveniently, this matches with the upper-left eigenvalue.
|
||||
|
||||
Assuming for the sake of argument that this is true, it implies something interesting:
|
||||
**the GC operators produced from *T* are (combinatorially) closed under composition**.
|
||||
This captures all powers of a given *T*, as well as products between it and other possible *T*s.
|
||||
|
||||
However, this combinatorial view misses some of the picture, since some feature counts
|
||||
can be shared between two different classes at once.
|
||||
This comes down to the existence of chiral pairs.
|
||||
@ -282,53 +306,21 @@ This doesn't affect hexagon counts, so it means we can characterize the possible
|
||||
|
||||
$$
|
||||
\begin{align*}
|
||||
g_T S &= \begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
x & 0 & 0 \\
|
||||
0 & 1 & 0 \\
|
||||
0 & 0 & T
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
1 & -{2 \over 3} & 0 \\
|
||||
1 & -1 & 1 \\
|
||||
0 & {1 \over 3} & 0
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix} v \\ e \\ f \end{pmatrix} \\[8pt]
|
||||
&=
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
x & 0 & 0 \\
|
||||
0 & 1 & 0 \\
|
||||
0 & 0 & T
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
v - {2 \over 3} e = 0 \\
|
||||
v - e + f = 2 \\
|
||||
{1 \over 3} e = F_6 + 10
|
||||
\end{pmatrix} \\[8pt]
|
||||
&=
|
||||
\begin{pmatrix}
|
||||
-1 & 0 & 2 \\
|
||||
0 & 0 & 3 \\
|
||||
1 & 1 & 1
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix} 0 \\ 2 \\ T (F_6 + 10) \end{pmatrix} \\
|
||||
&=
|
||||
\begin{pmatrix} T(2F_6 + 20) \\ T(3F_6 + 30) \\ T(F_6 + 10) + 2 \end{pmatrix} \\[8pt]
|
||||
g_T S &= g_T \left(
|
||||
\begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
|
||||
+ \begin{pmatrix} 20 \\ 30 \\ 10 \end{pmatrix}
|
||||
+ \begin{pmatrix} 0 \\ 0 \\ 2 \end{pmatrix}
|
||||
\right) \\
|
||||
&= T \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
|
||||
+ T \begin{pmatrix} 20 \\ 30 \\ 10 \end{pmatrix}
|
||||
+ \begin{pmatrix} 0 \\ 0 \\ 2 \end{pmatrix} \\
|
||||
&= \begin{pmatrix} T(2F_6 + 20) \\ T(3F_6 + 30) \\ T(F_6 + 10) + 2 \end{pmatrix} \\[8pt]
|
||||
F'_6 &= T(F_6 + 10) - 10
|
||||
\end{align*}
|
||||
$$
|
||||
|
||||
This demonstrates two things: the initial $F_6$ count from the choice of seed polygon *S* matters,
|
||||
and the possible values of *T* can be used to grow this sequence
|
||||
and we can use valid values of *T* to produce a sequence of solutions.
|
||||
|
||||
|
||||
Searching for Other Seeds
|
||||
@ -399,72 +391,13 @@ It inherits the dihedral symmetry of degree 3 from the vertices of the dodecahed
|
||||
](./truncated gyroelongated bipyramid pole.png)
|
||||
:::
|
||||
|
||||
::: {.column}
|
||||
```{python}
|
||||
#| echo: false
|
||||
|
||||
t_param = sympy.symbols("T")
|
||||
norm = lambda a, b: a**2 + a*b + b**2
|
||||
|
||||
@dataclass
|
||||
class GCOperator:
|
||||
name: str
|
||||
parameter: int | sympy.Symbol
|
||||
|
||||
gc_operators = [
|
||||
GCOperator("dk", norm(1, 1)),
|
||||
GCOperator("c", norm(2, 0)),
|
||||
GCOperator("w", norm(2, 1)),
|
||||
GCOperator("tk", norm(3, 0)),
|
||||
GCOperator("g_T", t_param),
|
||||
]
|
||||
|
||||
def polyhedronisme(recipe: str) -> str:
|
||||
return f"https://levskaya.github.io/polyhedronisme/?recipe={recipe}"
|
||||
|
||||
as_maybe_tex = lambda x: x if isinstance(x, int) or not x.has_free(t_param) else f"${sympy.latex(x)}$"
|
||||
as_maybe_recipe_link = lambda x, recipe: f"[{x}]({polyhedronisme(recipe)})" if recipe is not None else x
|
||||
|
||||
def mini_conway_table(
|
||||
base_case_hexagons: int,
|
||||
base_case_name: str,
|
||||
recipes: dict[str, str] = {},
|
||||
) -> list[tuple[str, PolyData]]:
|
||||
return [
|
||||
(
|
||||
as_maybe_recipe_link(f"${base_case_name}$", recipes.get("")),
|
||||
PolyData.from_hexagons(base_case_hexagons),
|
||||
)
|
||||
] + [
|
||||
(
|
||||
as_maybe_recipe_link(
|
||||
f"${operator.name + base_case_name.split(' ')[-1]}$",
|
||||
recipes.get(operator.name),
|
||||
),
|
||||
PolyData.from_hexagons((
|
||||
t_param * (base_case_hexagons + 10) - 10
|
||||
).expand().subs(t_param, operator.parameter)),
|
||||
)
|
||||
for operator in gc_operators
|
||||
]
|
||||
|
||||
def display_mini_conway_table(
|
||||
base_case_hexagons: int,
|
||||
base_case_name: str,
|
||||
recipes: dict[str, str] = {},
|
||||
) -> Markdown:
|
||||
return Markdown(tabulate(
|
||||
[[
|
||||
conway,
|
||||
as_maybe_tex(polyhedron.hexagon_count),
|
||||
as_maybe_tex(polyhedron.vertex_count),
|
||||
as_maybe_tex(polyhedron.edge_count),
|
||||
] for conway, polyhedron in mini_conway_table(base_case_hexagons, base_case_name, recipes)],
|
||||
headers=["Conway", "$F_6$", "V", "E"],
|
||||
numalign="left",
|
||||
))
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(6, "F")
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
|
||||
@ -497,7 +430,7 @@ The pentagons gather in groups of 4 and are separated by three bands of hexagons
|
||||
The symmetry inherited by this figure is also dihedral of degree 3, but centered about a hexagon,
|
||||
rather than (a complex of) pentagons.
|
||||
|
||||
:::: {layout-ncol="2" layout-valign="center"}
|
||||
::: {layout-ncol="2" layout-valign="center"}
|
||||
[
|
||||
{target="_blank_"}
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(8, "F")
|
||||
```
|
||||
::::
|
||||
:::
|
||||
|
||||
|
||||
#### Others
|
||||
@ -567,18 +500,18 @@ This is a symmetry beyond that of the icosahedron, but exists due to the symmetr
|
||||
](./polyhedronisme-K300t6dA6.png)
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(
|
||||
2,
|
||||
"t_6dA_6 = T_6",
|
||||
recipes = {
|
||||
"": "K300t6dA6",
|
||||
"dk": "dkK300t6dA6",
|
||||
"c": "K300cK30t6dA6",
|
||||
"w": "K300wK30t6dA6",
|
||||
"tk": "K300tkK30t6dA6"
|
||||
}
|
||||
2,
|
||||
"t_6dA_6 = T_6",
|
||||
recipes = {
|
||||
"": "K300t6dA6",
|
||||
"dk": "dkK300t6dA6",
|
||||
"c": "K300cK30t6dA6",
|
||||
"w": "K300wK30t6dA6",
|
||||
"tk": "K300tkK30t6dA6",
|
||||
},
|
||||
)
|
||||
```
|
||||
::::
|
||||
@ -608,11 +541,13 @@ The resultant figure has dihedral symmetry of degree 5.
|
||||
](./petrial expanded dodecahedron.png)
|
||||
:::
|
||||
|
||||
::: {.column}
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(5, "D_\\pi")
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
Interestingly, this is also the first solution polyhedron with an odd number of faces.
|
||||
@ -632,43 +567,47 @@ Solution polyhedra can be found by examining the pentagonal ($t_5 g Y_5$) and he
|
||||
The former has dihedral symmetry of degree 5 and the latter has that of degree 6.
|
||||
|
||||
:::: {layout-ncol="2" layout-valign="center"}
|
||||
::: {.column .slim-column}
|
||||
{.column .slim-column}
|
||||
:::
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(
|
||||
10,
|
||||
"t_5gY_5 = G_5",
|
||||
recipes = {
|
||||
"": "K300t5K30gY5",
|
||||
"dk": "dkK300t5K30gY5",
|
||||
"c": "K300dudt5K30gY5",
|
||||
"w": "K300wK30t5K30gY5",
|
||||
"tk": "tkK300t5K30gY5",
|
||||
},
|
||||
10,
|
||||
"t_5gY_5 = G_5",
|
||||
recipes = {
|
||||
"": "K300t5K30gY5",
|
||||
"dk": "dkK300t5K30gY5",
|
||||
"c": "K300dudt5K30gY5",
|
||||
"w": "K300wK30t5K30gY5",
|
||||
"tk": "tkK300t5K30gY5",
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
::: {.column .slim-column}
|
||||
{.column .slim-column}
|
||||
](./polyhedronisme-K300t6K30gY6.png)
|
||||
:::
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(
|
||||
14,
|
||||
"t_6gY_6 = G_6",
|
||||
recipes = {
|
||||
"": "K300t6K30gY6",
|
||||
"dk": "dkK300t6K30gY6",
|
||||
"c": "K300dudK40t6gY6",
|
||||
"w": "K300wK30t6K30gY6",
|
||||
"tk": "tkK300t6K30gY6",
|
||||
},
|
||||
14,
|
||||
"t_6gY_6 = G_6",
|
||||
recipes = {
|
||||
"": "K300t6K30gY6",
|
||||
"dk": "dkK300t6K30gY6",
|
||||
"c": "K300dudK40t6gY6",
|
||||
"w": "K300wK30t6K30gY6",
|
||||
"tk": "tkK300t6K30gY6",
|
||||
},
|
||||
)
|
||||
```
|
||||
::::
|
||||
@ -718,9 +657,13 @@ In fact, the graph of the whirl operation on the surface of a cube
|
||||
|
||||
:::: {#fig-tatami-polyhedron}
|
||||
::: {layout="[[-1,2,-1,2,-1]]"}
|
||||
<a title="Tomruen, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Conway_wC.png"><img width="384" alt="Conway wC" src="https://upload.wikimedia.org/wikipedia/commons/f/f4/Conway_wC.png"></a>
|
||||
<a title="Tomruen, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Conway_wC.png">
|
||||
<img width="384" alt="Conway wC" src="https://upload.wikimedia.org/wikipedia/commons/f/f4/Conway_wC.png">
|
||||
</a>
|
||||
|
||||
<a title="See page for author, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Tearoom_layout.svg"><img style="background-color: white !important; padding: 5px" width="384" alt="Tearoom layout" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Tearoom_layout.svg/256px-Tearoom_layout.svg.png"></a>
|
||||
<a title="See page for author, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Tearoom_layout.svg">
|
||||
<img style="background-color: white !important; padding: 5px" width="384" alt="Tearoom layout" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Tearoom_layout.svg/256px-Tearoom_layout.svg.png">
|
||||
</a>
|
||||
:::
|
||||
|
||||
Images were retrieved from Wikimedia and belong to their respective owners.
|
||||
@ -739,14 +682,14 @@ Next to it is an equivalent graph with a regular hexagon as an outer face.
|
||||
As a 3D figure, it has only three hexagons and degree-3 dihedral symmetry, another odd number.
|
||||
|
||||
:::: {layout-ncol="2" layout-valign="center"}
|
||||
::: {.column .slim-column}
|
||||
::: {.column .slim-column .text-center}
|
||||
{.image-wide}
|
||||
|
||||
{.image-wide}
|
||||
:::
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
|
||||
display_mini_conway_table(3, "M")
|
||||
```
|
||||
@ -791,10 +734,11 @@ Final Tabulation
|
||||
The solutions examined have been collected in the table below.
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
#| classes: plain
|
||||
#| tbl-cap: "T, T' are members of the sequence 1, 3, 4, 7, 9, 12, 13, 16, 19, 21... ([OEIS A003136](http://oeis.org/A003136))\
|
||||
#| <br>\\\\*: This is the result of a GC operator applied to $2T - 14$, which requires *T* > 7"
|
||||
|
||||
TFilter: TypeAlias = Callable[[int], bool] | None
|
||||
n_param, t_param, aux_t_param, temp_param = sympy.symbols("n T T' x")
|
||||
|
||||
@dataclass
|
||||
class TotalHexagonRow:
|
||||
@ -803,8 +747,6 @@ class TotalHexagonRow:
|
||||
f6_expression: sympy.Expr
|
||||
t_filter: TFilter = None
|
||||
|
||||
from_base_case = lambda x: (t_param * (x + 10) - 10)
|
||||
|
||||
antitruncation = TotalHexagonRow(
|
||||
symmetry_group="Tetrahedral",
|
||||
class_name="Tetrahedral Goldberg Antitruncations",
|
||||
@ -880,18 +822,10 @@ full_tabulation_rows = [
|
||||
),
|
||||
]
|
||||
|
||||
def loeschian():
|
||||
"""
|
||||
Loeschian numbers -- those of the form a^2 + ab + b^2
|
||||
See https://oeis.org/A003136
|
||||
"""
|
||||
for a in itertools.count(1):
|
||||
for b in range(a + 1):
|
||||
yield a*a + a*b + b*b
|
||||
|
||||
|
||||
def get_example_counts(expr: sympy.Expr, amount: int, t_filter: TFilter = None):
|
||||
t_params = list(itertools.islice(loeschian(), 2*amount))
|
||||
"""Build values from the expression in terms of the number of hexagons"""
|
||||
t_params = list(itertools.islice(loeschian_numbers(), 2*amount))
|
||||
|
||||
return [
|
||||
count
|
||||
@ -931,18 +865,20 @@ Markdown(tabulate(
|
||||
))
|
||||
```
|
||||
|
||||
T, T' are members of the sequence 1, 3, 4, 7, 9, 12, 13, 16, 19, 21... ([OEIS A003136](http://oeis.org/A003136))
|
||||
|
||||
\*: This is the result of a GC operator applied to $2T - 14$, which requires *T* > 7
|
||||
|
||||
Sorting the entries in this table, we get the following possible hexagon counts:
|
||||
Here are a few hexagon counts from the table, sorted in ascending order:
|
||||
|
||||
```{python}
|
||||
#| echo: false
|
||||
|
||||
Markdown(", ".join(list(map(str, sorted(itertools.chain(*[
|
||||
get_example_counts(row.f6_expression, 10, row.t_filter) for row in full_tabulation_rows
|
||||
]))))[:15]))
|
||||
Markdown(
|
||||
", ".join([
|
||||
str(i)
|
||||
for i in group_dict(
|
||||
itertools.chain(*[
|
||||
get_example_counts(row.f6_expression, 10, row.t_filter)
|
||||
for row in full_tabulation_rows
|
||||
])
|
||||
).keys()
|
||||
][:20]) + "..."
|
||||
)
|
||||
```
|
||||
|
||||
However, keep in mind that this list is *not* exhaustive.
|
||||
|
||||
25
posts/pentagons/_metadata.yml
Normal file
25
posts/pentagons/_metadata.yml
Normal file
@ -0,0 +1,25 @@
|
||||
# freeze computational output
|
||||
freeze: auto
|
||||
|
||||
# Enable banner style title blocks
|
||||
title-block-banner: true
|
||||
|
||||
execute:
|
||||
echo: false
|
||||
|
||||
# Get rid of the figure label
|
||||
crossref:
|
||||
fig-title: ""
|
||||
fig-labels: " "
|
||||
tbl-title: ""
|
||||
tbl-labels: " "
|
||||
title-delim: ""
|
||||
custom:
|
||||
- key: fig
|
||||
kind: float
|
||||
reference-prefix: Figure
|
||||
space-before-numbering: false
|
||||
- key: tbl
|
||||
kind: float
|
||||
reference-prefix: Table
|
||||
space-before-numbering: false
|
||||
Loading…
x
Reference in New Issue
Block a user