codexcyclic-four-versus-klein-four.py
cyclic-four-versus-klein-four.py
"""Compare the addition tables of C4 and C2 x C2; write PNG to CWD."""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from matplotlib.patches import Rectangle
import numpy as np
def operation_tables():
elements = np.arange(4)
c4 = (elements[:, None] + elements[None, :]) % 4
# Binary labels 00, 01, 10, 11: XOR is componentwise addition modulo two.
v4 = np.bitwise_xor(elements[:, None], elements[None, :])
assert np.array_equal(c4, c4.T)
assert np.array_equal(v4, v4.T)
assert np.array_equal(np.diag(c4), [0, 2, 0, 2])
assert np.all(np.diag(v4) == 0)
return c4, v4
def main():
plt.rcParams.update({"font.size": 12, "figure.facecolor": "white"})
fig, axes = plt.subplots(1, 2, figsize=(10.2, 5.5), dpi=100)
cmap = ListedColormap(["#e6eef7", "#f7d9bb", "#d7eedf", "#eddcf4"])
c4, v4 = operation_tables()
panels = [
(c4, ["0", "1", "2", "3"], r"$C_4$: addition modulo four",
"1 and 3 have order 4\nA single step can visit all four states"),
(v4, ["00", "01", "10", "11"], r"$C_2 \times C_2$: add each bit modulo two",
"01, 10 and 11 each have order 2\nEvery state added to itself gives 00"),
]
for ax, (table, labels, title, note) in zip(axes, panels, strict=True):
ax.imshow(table, cmap=cmap, vmin=-0.5, vmax=3.5)
for row in range(4):
for column in range(4):
ax.text(column, row, labels[table[row, column]],
ha="center", va="center", fontsize=17, color="#172434")
ax.add_patch(Rectangle((row - 0.48, row - 0.48), 0.96, 0.96,
fill=False, linewidth=2, edgecolor="#45566b"))
ax.set_xticks(range(4), labels=labels)
ax.set_yticks(range(4), labels=labels)
ax.xaxis.tick_top()
ax.tick_params(axis="both", length=0, pad=9)
ax.set_xticks(np.arange(-0.5, 4, 1), minor=True)
ax.set_yticks(np.arange(-0.5, 4, 1), minor=True)
ax.grid(which="minor", color="white", linewidth=3)
ax.tick_params(which="minor", bottom=False, left=False, top=False)
for spine in ax.spines.values():
spine.set_visible(False)
ax.set_title(title, fontsize=13, weight="bold", pad=24)
ax.text(1.5, 4.15, note, ha="center", va="top",
fontsize=12, linespacing=1.5)
ax.set_ylim(3.5, -0.5)
fig.suptitle("Same size and commutativity; different repetition periods",
fontsize=16, weight="bold", y=0.965)
fig.subplots_adjust(left=0.07, right=0.95, top=0.78, bottom=0.22, wspace=0.32)
fig.savefig(Path.cwd() / Path(__file__).with_suffix(".png").name,
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()