Note
Go to the end to download the full example code.
Cayley’s abstract group and its multiplication table#
Cayley’s 1854 definition treats a group purely as symbols with a
binary operation. Here the group of his title, generated by
\(\theta\) with \(\theta^n = 1\), is written as an abstract
FiniteGroup whose
elements are just the strings "1", "θ", "θ²", .... Its Cayley table
is identical to that of \(\mathbb{Z}_6\), while the non-abelian
\(S_3\) of the same order gives a visibly different, non-symmetric
table.
import matplotlib.pyplot as plt
import numpy as np
from mathematicskit.abstract_algebra import CyclicGroup, FiniteGroup, PermutationGroup
A group defined only by the symbolic equation theta^n = 1#
class ThetaGroup(FiniteGroup):
"""Cayley's group 1, θ, θ², ..., θ^(n-1) with θ^n = 1, as bare symbols."""
def __init__(self, n):
self.n = n
self._symbols = ["1", "θ"] + [f"θ^{k}" for k in range(2, n)]
@property
def elements(self):
return self._symbols
def identity(self):
return "1"
def operate(self, a, b):
return self._symbols[(self._symbols.index(a) + self._symbols.index(b)) % self.n]
def inverse(self, a):
return self._symbols[-self._symbols.index(a) % self.n]
theta6 = ThetaGroup(6)
z6 = CyclicGroup(6)
s3 = PermutationGroup(3)
print(f"theta-group order {theta6.order}, abelian: {theta6.is_abelian()}")
print(f"theta^6 = 1: {theta6.element_order('θ') == 6}")
print(f"same Cayley table as Z_6: {np.array_equal(theta6.cayley_table(), z6.cayley_table())}")
print(f"S_3 table symmetric: {np.array_equal(s3.cayley_table(), s3.cayley_table().T)}")
theta-group order 6, abelian: True
theta^6 = 1: True
same Cayley table as Z_6: True
S_3 table symmetric: False
Cayley tables, labelled with the element names#
def labelled_table(ax, group, labels, title):
table = group.cayley_table()
ax.imshow(table, cmap="tab10", vmin=0, vmax=9)
for i in range(group.order):
for j in range(group.order):
ax.text(j, i, labels[table[i, j]], ha="center", va="center", fontsize=8)
ax.set_xticks(range(group.order), labels, fontsize=8, rotation=45)
ax.set_yticks(range(group.order), labels, fontsize=8)
ax.xaxis.tick_top()
ax.set_title(title, pad=28)
fig, axes = plt.subplots(1, 3, figsize=(14, 5))
theta_labels = ["1", r"$\theta$"] + [rf"$\theta^{k}$" for k in range(2, 6)]
labelled_table(axes[0], theta6, theta_labels, r"Cayley's $\theta^6 = 1$")
labelled_table(axes[1], z6, [str(k) for k in z6.elements], r"$\mathbb{Z}_6$ (same pattern)")
s3_labels = ["".join(map(str, p)) for p in s3.elements]
labelled_table(axes[2], s3, s3_labels, r"$S_3$ (not symmetric: non-abelian)")
fig.tight_layout()

Total running time of the script: (0 minutes 0.107 seconds)