J. Simon Richard
Blog

A Graphical Explanation of the Todd-Coxeter Algorithm

Tags: mathalgorithms
2022-05-03

Using a group presentation is often the most compact and elegant way to define a group, and in some cases it is also the most natural1. However, it is in general quite difficult to analyze groups written in this form. In fact, it is impossible to create an algorithm that determines whether a group is finite, trivial, or abelian from its group presentation alone1.

We can, however, analyze the cosets within these groups. The Todd-Coxeter Algorithm, which was originally created by J. A. Todd and H. S. M. Coxeter in the 1930s2, is a clever and surprisingly simple algorithm that enumerates the cosets of a given subgroup using only the presentation of the parent group and the generators of the subgroup. In this post, I will endevour to explain the concepts behind this algorithm, the procedure itself, and the inner workings of an implementation of this algorithm.

Group Presentations

Before we continue, we need to nail down a working definition for group presentations. As taken from Derek Holt's lecture notes1, if XR\langle X \mid R \rangle is a presentation of the group GG, then GG is the "largest" group generated by the elements of XX for which the relations in RR hold in GG. For example, r,sr6=s2=(rs)2=e\langle r,s \mid r^6 = s^2 = (rs)^2 = e \rangle is a presentation for the dihedral group D6D_6. Note that presentations are not necessarily unique.

The set RR may alternatively be defined to be a set of words following the form g1g2...gng_1g_2...g_n with giXg_i \in X or gi1Xg_i^{-1} \in X such that g1g2...gn=eg_1g_2...g_n=e. For convenience's sake, we will use this definition from now on.

Group Actions

Group actions are also fundamental to the theory behind the Todd-Coxeter Algorithm.

Let SS be a set and let GG be a group. A (left) group action of GG on SS is a function α:G×SS\alpha: G \times S \rightarrow S that meets the following requirements.

α(e,s)=s\alpha(e, s) = s
α(g,α(h,s))=α(gh,s)g,hG\alpha(g, \alpha(h, s)) = \alpha(gh, s) \hspace{0.5cm} \forall g,h \in G

If a group action of GG on SS exists, GG is said to act on SS. If GG acts transitively on SS, then the following is also true.

s1,s2S,gGα(g,s1)=s2\forall s_1,s_2 \in S, \exists g \in G \ni \alpha(g, s_1) = s_2

In otherwords, SS only has one orbit.

When working with group actions, α(g,s)\alpha(g, s) is often simplified to gsg \cdot s or gsgs. We will do this from now on.

Schreier Graphs

Now that we've defined both group presentations and group actions, we can define the Schreier graph, the fundamental data structure that underpins the Todd-Coxeter algorithm.

Let G=XRG = \langle X \mid R \rangle and let GG act transitively on SS. The Schreier graph for SS is a directed and labeled graph Γ\Gamma with SS as its vertex set and with edges labeled gg from ss to gsgs sS\forall s \in S and gX\forall g \in X.

Some Observations

  • Since group actions act bijectively on SS for a fixed gg, each vertex has exactly one incomming and one outgoing edge for each label gXg \in X.
  • A starting point sSs \in S and a word g1g2...gkg_1g_2...g_k with giXg_i \in X or gi1Xg_i^{-1} \in X defines a path in Γ\Gamma
  • Every word in RR corresponds with a loop in Γ\Gamma

An Example

Let G=r,sr3,s2,(rs)2G = \langle r, s \mid r^3, s^2, (rs)^2 \rangle. That is, G=XRG = \langle X \mid R \rangle with X={r,s}X = \{r, s\} and R={rrr,ss,rsrs}R = \{rrr, ss, rsrs\}. Let SS be a set of arbitrary regular triangles represented by the ordered triplets (1,2,3)(1,2,3), (2,3,1)(2,3,1), (3,1,2)(3,1,2), (1,3,2)(1,3,2), (3,2,1)(3,2,1), and (2,1,3)(2,1,3). Finally, let GG act on SS with r(a,b,c)=(b,c,a)r \cdot (a,b,c) = (b,c,a) and s(a,b,c)=(a,c,b)s \cdot (a,b,c) = (a,c,b).

A possible solution for the Schreier graph of SS is as follows.

499b30fe-91f1-40a3-8108-82372839ccb0

Notice that the observations we just made hold for this example.

The Todd-Coxeter Algorithm

The Todd-Coxeter Algorithm takes two inputs.

  • A presentation G=XRG = \langle X \mid R \rangle with finite sets XX and RR
  • A finite set YY that generates HH, a subgroup of GG

The output of the algorithm is the Schreier graph for the set of left cosets of HH in GG, G/HG/H, with the following group action.

α:G×G/HG/H\alpha: G \times G/H \rightarrow G/H
α(g1,g2H)=(g1g2)H\alpha(g_1, g_2H) = (g_1g_2)H

The Procedure

From a theoretical standpoint, we start with the Schreier graph for the free group generated by XX. It need not (and indeed cannot, since it is infinite) be entirely represented in memory. Then, we follow the steps below.

  1. Label the vertex corresponding to the coset HH with the label 11 (this is represented in memory).

  2. For each word hHh \in H, start at vertex 11 and follow the path defined by hh. Give the vertices along this path new labels and identify the vertex at the end with vertex 11.

To identify two vertices, remove the one with the higher label and then merge its edges with the edges of the other vertex. If there are two outgoing edges with the same label or two incoming edges with the same label, the vertecies at the other end of those edges must also be identified so that we are left with at most one outgoing edge and one incoming edge for each label.

  1. For each vertex that is labeled or that will be labeled (including the ones that will be labeled during this step), define a path starting at that vertex for each word in RR (so, if SS is the set of all vertices that will eventually be labeled, there should be SR|S|\cdot|R| paths in total). Then, for each path pp, label the vertices along pp and identify starting point of pp with the endpoint of pp.

If and when this final step terminates, we will be left with a Schreier graph for G/HG/H that is completely labeled.

Some Observations

  • If H is trivial then the Schreier graph represents GG since G/{e}GG/\{e\} \cong G
  • A spanning tree rooted at vertex 11 gives us a way to recover all of the cosets of HH (or the elements of GG if HH is trivial) using only the generators in XX

An Interactive Example

Let G=D6=r,sr6,s2,(rs)2G = D_6 = \langle r,s \mid r^6, s^2, (rs)^2 \rangle and let H=r3H=\langle r^3 \rangle. So, the inputs for the Todd-Coxeter Algorithm are as follows.

X={r,s}X = \{r,s\}
R={rrrrrr,ss,rsrs}R = \{rrrrrr, ss, rsrs\}
Y={rrr}Y = \{rrr\}
Step 1: Label vertex 1 (frame 1.1)
51da1183-f4a8-44a4-92ee-3a981dfb51a2

Note: Some steps are skipped since they don't permanently affect the tree

Implementation

An implementation of this algorithm written in python can be found on GitHub here or downloaded here. Most of its core logic was taken from Kyle Miller's implementation3, but it was rewritten using classes. This, in my opinion, makes it a lot easier to read. It was also written as a terminal application in order to increase its ease of use.

To use this program, download it and then run the following command to get more usage information.

python3 todd-coxeter.py -h

To run this program for the example above, use the following command.

python3 todd-coxeter.py --ngens 2 --rels 1,1,1,1,1,1 2,2 1,2,1,2 --hgens 1,1,1

In this command, --ngens 2 is used to specify that there are two generators (they will be labeled 11 and 22, corresponding to rr and ss respectively, and their inverses will be labeled 1-1 and 2-2). After the --rels flag, the relations in RR are specified using the following format: each generator is separated with a comma, and each word in RR is separated by a space. After the --hgens flag, the generators for HH are specified using the same format.

The rest of this section will outline the general structure of this implementation. If you are interested in the exact syntax used, I would encourage you to look directly at the source code.

Data Structures and Classes

There are two main data structures used within this implementation: a disjoint-set (or union-find) data structure implemented by the UnionFind class and a graph represented by an adjecency list (implemented with a list of dictionaries). These two data structures are combined to create the PartialSchreierGraph class, which represents the Schreier graph before the Todd-Coxeter Algorithm terminates.

The SchreierGraph class inherites from PartialSchreierGraph and contains the logic for the Todd-Coxeter Algorithm. This algorithm is executed within the constructor of SchreierGraph (i.e. it must terminate for an instance of SchreierGraph to finish being constructed) so that all instances are guaranteed to represent a valid Schreier graph for G/HG/H. This class, in conjuction with the Permutation class, also provides a way to interpret the graph without displaying it in its entirety. Instead, for each generator, it displays a product of cycles that corresponds with how that generator permutes the cosets of HH.

A Closer Look at UnionFind and its Role in PartialSchreierGraph

The disjoint-set (or union-find) data structure represents a set of disjoint sets using disjoint trees. This forest is represented by a single list parent with the following constraint.

parent[index/label of child] = index/label of parent

When using disjoint-sets, we have access to two operations.

  • Find: For any given label, find the root of the tree that contains that label
  • Union: For any two labels, if those labels are a part of different trees, combine those two trees. In our implementation, the root with the lower label is used as the root of the new tree.

More information about this data structure can be found here.

Within the PartialSchreierGraph class, the disjoint-set data structure is used to keep track of vertex labels. We could just use a single label for each vertex, but if a label is removed (and this happens quite a lot during identification) then all references to that label must be updated or removed. That would require looping through all of the edges of the graph, which is inefficient. With the disjoint-set keeping track of labels, we don't need to worry about this. Instead, whenever we want to run an operation on a vertex label, we first run the find operation on that label to get the actual (that is, the lowest) label for that vertex. And, whenever we identify two nodes, we run the union operation on their labels.

Supporting Inverses

It is not technically necessary to keep track of inverses within the adjacency list for our Schreier graph since every incoming edge is an outgoing edge for some other vertex. However, we would like to be able to include inverses in the words in RR and YY, and therefore we need to be able to calculate g1sg^{-1}s quickly. For this reason, we do include inverses in our adjacency list.

To keep the inverse edges pointing in the right direction, we add a trivial relation gg1gg^{-1} to RR for each gXg \in X. This ensures that, after the completion of the algorithm, we are left with a valid Schreier graph. No other changes are necessary.

Conclusion

Although this post is not quite mathematically complete, I hope that it has provided some valuable insight into the Todd-Coxeter Algorithm from a mathematical perspective and from the perspective of computer science.

In addition to being a fun project, this post was also an assignment for a class taken at Cleveland State University in cooperation with the Jack, Joseph and Morton Mandel Honors College. Special thanks to Dr. Galetto for his guidence during this project.

If you have any questions or find any errata, feel free to email me at [email protected] or create a GitHub issue here (if that's your kind of thing). Also, keep in mind that this entire website is open source, so if you want to learn how to make a website like this or a interactive graph like the one I have above, feel free to check out its source code here.

Resources

  1. Holt, Derek. (2013). Presentation of Groups. https://warwick.ac.uk/fac/sci/maths/people/staff/fbouyer/presentation_of_group.pdf

  2. Todd, J., & Coxeter, H. (1936). A practical method for enumerating cosets of a finite abstract group. Proceedings of the Edinburgh Mathematical Society, 5(1), 26-34. doi:10.1017/S0013091500008221 (pdf: https://www.cambridge.org/core/services/aop-cambridge-core/content/view/S0013091500008221)

  3. Miller, Kyle. (2016). The Todd-Coxeter algorithm. https://math.berkeley.edu/~kmill/notes/todd_coxeter.html

  4. vis.js: https://visjs.org/. Used to display the interactive graphs

  5. react-graph-vis: https://github.com/crubier/react-graph-vis. A vis.js wrapper for ReactJS

HomeAboutEducationWork ExperiencesSkillsInterests

Social

GitHubLinkedInInstagram

Contact Me

[email protected]

Source Code

GitHub
Copywrite © 2024 J. Simon Richard