Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
Brouwer, Alexander, and the invariance of homology under subdivision (1911-1915)#
Is homology a property of the space or of the chosen triangulation? Brouwer’s simplicial approximation (1911) answers it. Any continuous map is close to a simplicial one after subdividing finely enough. Alexander (1915) used this to prove that homology is a topological invariant. Barycentric subdivision replaces every simplex by the chains of its faces. The simplex counts grow about sixfold per round for surfaces, while the Betti numbers do not change.
import matplotlib.pyplot as plt
from mathematicskit.topology import barycentric_subdivision, betti_numbers, projective_plane, simplex, torus
from mathematicskit.topology.visualizers import plot_complex
for name, K in (("torus", torus(3, 3)), ("projective plane", projective_plane())):
for level in range(3):
print(f"{name:>16}, sd^{level}: f = {K.f_vector!s:>18} chi = {K.euler_characteristic} Betti = {betti_numbers(K)} mod 2: {betti_numbers(K, field=2)}")
if level < 2:
K = barycentric_subdivision(K)
torus, sd^0: f = (9, 27, 18) chi = 0 Betti = (1, 2, 1) mod 2: (1, 2, 1)
torus, sd^1: f = (54, 162, 108) chi = 0 Betti = (1, 2, 1) mod 2: (1, 2, 1)
torus, sd^2: f = (324, 972, 648) chi = 0 Betti = (1, 2, 1) mod 2: (1, 2, 1)
projective plane, sd^0: f = (6, 15, 10) chi = 1 Betti = (1, 0, 0) mod 2: (1, 1, 1)
projective plane, sd^1: f = (31, 90, 60) chi = 1 Betti = (1, 0, 0) mod 2: (1, 1, 1)
projective plane, sd^2: f = (181, 540, 360) chi = 1 Betti = (1, 0, 0) mod 2: (1, 1, 1)
Subdividing a triangle#
triangle = simplex(2)
triangle.coordinates = [[0.0, 0.0], [1.0, 0.0], [0.5, 0.866]]
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
K = triangle
for level, ax in enumerate(axes):
plot_complex(K, ax=ax, face_values=list(range(len(K.simplices(2)))), cmap="tab20", alpha=0.6, vertex_size=6)
ax.set_title(f"sd^{level}: f = {K.f_vector}, χ = {K.euler_characteristic}")
ax.axis("off")
K = barycentric_subdivision(K)
fig.suptitle("Barycentric subdivision changes the triangulation, not the space")

Text(0.5, 0.98, 'Barycentric subdivision changes the triangulation, not the space')
Total running time of the script: (0 minutes 0.622 seconds)