12 lines
31 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"hash": "df9fef54ee2049cdaf90a0487a97b59e",
"result": {
"engine": "jupyter",
"markdown": "---\ntitle: \"Exploring Finite Fields, Part 3: Roll a d20\"\ndescription: |\n When we extend fields with matrices, what other structures do we encounter?\nformat:\n html:\n html-math-method: katex\ndate: \"2024-02-03\"\ndate-modified: \"2025-08-04\"\ncategories:\n - algebra\n - finite field\n - haskell\n---\n\n<style>\n.narrow {\n max-width: 512px;\n}\n</style>\n\n\n\nIn the [previous post](../2), we focused on constructing finite fields using *n*×*n* matrices.\nThese matrices came from from primitive polynomials of degree *n* over GF(*p*),\n and could be used to do explicit arithmetic over GF(*p*^*n*^).\nIn this post, we'll look at a way to apply this in describing certain groups.\n\n\nWeakening the Field\n-------------------\n\nRecall the way we defined GF(4) in the first post.\nWe took the irreducible polynomial *p*(*x*) = *x*^2^ + *x* + 1, called its root *α*,\n and created addition and multiplication tables spanning the four elements.\nAfter the second post, we can do this more cleverly by mapping *α*\n to the companion matrix *C*~*p*~ over GF(2).\n\n$$\n\\begin{gather*}\n f : \\mathbb{F_4} \\longrightarrow \\mathbb{F}_2 {}^{2 \\times 2}\n \\\\[10pt]\n 0 \\mapsto \\left(\\begin{matrix}\n 0 & 0 \\\\\n 0 & 0\n \\end{matrix}\\right)\n ~~\n 1 \\mapsto \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right) = I\n ~~\n \\alpha \\mapsto \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix}\\right) = C_p\n \\\\ \\\\\n \\textcolor{red}{\\alpha} + \\textcolor{blue}{1} = \\alpha^2 \\mapsto\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right) =\n \\textcolor{red} {\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix}\\right)\n }\n + \\textcolor{blue}{\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right)\n }\\mod 2\n\\end{gather*}\n$$\n\nIn the images of *f*, the zero matrix has determinant 0 and all other elements have determinant 1.\nTherefore, the product of any two nonzero matrices always has determinant 1,\n and a nonzero determinant means the matrix is invertible.\nPer the definition of the field, the non-zero elements form a group with respect to multiplication.\nHere, they form a cyclic group of order 3, since *C*~*p*~^3^ = *I* mod 2.\nThis is also true using symbols, since *α*^3^ = 1.\n\n\n### Other Matrices\n\nHowever, there are more 2×2 matrices over GF(2) than just these.\nThere are two possible values in four locations, so there are 24 = 16 matrices,\n or 12 more than we've identified.\n\n$$\n\\begin{array}{c|c}\n \\#\\{a_{ij} = 1\\} & \\det = 0 & \\det = 1\n \\\\ \\hline\n 1 &\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 0 & 0\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 0\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 0 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 0 & 0 \\\\\n 1 & 0\n \\end{matrix}\\right)\n \\\\\n 2 &\n \\scriptsize\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 0 & 0\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 0 & 0 \\\\\n 1 & 1\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 0 & 1\n \\end{matrix}\\right)\n ~~\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 0 & 0\n \\end{matrix}\\right)\n &\n \\scriptsize\n \\textcolor{red}{\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right)\n }\n \\\\\n 3 & &\n \\scriptsize\n \\textcolor{red}{\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 0 & 1\n \\end{matrix}\\right)\n }\n ~~\n \\textcolor{red}{\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 1 & 1\n \\end{matrix}\\right)\n }\n \\\\\n 4 &\n \\scriptsize\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 1\n \\end{matrix}\\right)\n\\end{array}\n$$\n\nThe matrices in the right column (in red) have determinant 1, which means they can *also* multiply\n with our field-like elements without producing a singular matrix.\nThis forms a larger group, of which our field's multiplication group is a subgroup.\nHowever, it is *not* commutative, since matrix multiplication is not commutative in general.\n\nThe group of all six matrices with nonzero determinant is called the\n [*general linear group*](https://en.wikipedia.org/wiki/General_linear_group)\n of degree 2 over GF(2), written[^1] GL(2, 2).\nWe can sort the elements into classes by their order, or the number of times we have\n to multiply them before getting to the identity matrix (mod 2):\n\n[^1]: Unfortunately, it's rather easy to confuse \"GF\" with \"GL\".\n Remember that \"F\" is for \"field\", with the former standing for \"Galois field\".\n\n$$\n\\begin{array}{}\n \\text{Order 1} & \\text{Order 2} & \\text{Order 3}\n \\\\ \\hline\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right)\n &\n \\begin{align*}\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 0 & 1\n \\end{matrix}\\right)\n \\\\\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 1 & 1\n \\end{matrix}\\right)\n \\\\\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right)\n \\end{align*}\n &\n \\begin{align*}\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix}\\right)\n \\\\\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right)\n \\end{align*}\n\\end{array}\n$$\n\nIf you've studied enough group theory, you know that there are two groups of order 6:\n the cyclic group of order 6, *C*~6~, and the symmetric group on three elements, *S*~3~.\nSince the former group has order-6 elements, but none of these matrices are of order 6,\n the matrix group must be isomorphic to the latter.\nSince the group is small, it's not too difficult to construct an isomorphism between the two.\nWriting the elements of *S*~3~ in [cycle notation](/posts/math/permutations/1/), we have:\n\n$$\n\\begin{gather*}\n e \\mapsto \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right)\n \\\\ \\\\\n (1 ~ 2) \\mapsto \\left(\\begin{matrix}\n 1 & 1 \\\\\n 0 & 1\n \\end{matrix}\\right)\n \\qquad\n (1 ~ 3) \\mapsto \\left(\\begin{matrix}\n 1 & 0 \\\\\n 1 & 1\n \\end{matrix}\\right)\n \\qquad\n (2 ~ 3) \\mapsto \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right)\n \\\\ \\\\\n (1 ~ 2 ~ 3) \\mapsto \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix}\\right)\n \\qquad\n (3 ~ 2 ~ 1) \\mapsto \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 0\n \\end{matrix}\\right)\n\\end{gather*}\n$$\n\n\nBigger Linear Groups\n--------------------\n\nOf course, there is nothing special about GF(2) in this definition.\nFor any field *K*, the general linear group GL(*n*, *K*) is composed of invertible\n *n*×*n* matrices under matrix multiplication.\n\nFor fields other than GF(2), a matrix can have a determinant other than 1.\nSince the determinant is multiplicative, the product of two determinant 1 matrices also has determinant 1.\nTherefore, the general linear group has a subgroup,\n the [*special linear group*](https://en.wikipedia.org/wiki/Special_linear_group)\n SL(*n*, *K*), consisting of these matrices.\n\n\n<details>\n<summary>\nHaskell implementation of GL and SL for prime fields\n</summary>\nThis implementation will be based on the `Matrix` type from the first post.\nAssume we have already defined matrix multiplication and addition.\n\n::: {#d70bf3ee .cell execution_count=3}\n``` {.haskell .cell-code}\nimport Data.Array (listArray, bounds, elems)\nimport Data.List (unfoldr)\n\n-- Partition a list into lists of length n\nreshape :: Int -> [a] -> [[a]]\nreshape n = unfoldr (reshape' n) where\n reshape' n x = if null x then Nothing else Just $ splitAt n x\n\n-- Convert list of lists to Matrix\n-- Abuses listArray working across rows, then columns\ntoMatrix :: [[a]] -> Matrix a\ntoMatrix l = Mat $ listArray ((0,0),(n-1,m-1)) $ concat l where\n m = length $ head l\n n = length l\n\n-- Convert Matrix to list of lists\nfromMatrix :: Matrix a -> [[a]]\nfromMatrix (Mat m) = let (_,(_,n)) = bounds m in reshape (n+1) $ elems m\n```\n:::\n\n\nWith helper functions out of the way, we can move on to generating all matrices (mod *n*).\nThen, we filter for matrices with nonzero determinant (in the case of GL) and determinant 1\n (in the case of SL).\n\n::: {#6249f6f4 .cell execution_count=4}\n``` {.haskell .cell-code}\nimport Control.Monad (replicateM)\n\n-- All m x m matrices (mod n)\nallMatrices :: Int -> Int -> [Matrix Int]\nallMatrices m n = map toMatrix $ replicateM m vectors where\n -- Construct all vectors mod n using base-n expansions and padding\n vectors = [pad $ coeffs $ asPoly n l | l <- [1..n^m-1]]\n -- Pad xs to length m with zero\n pad xs = xs ++ replicate (m - length xs) 0\n\n-- All matrices, but paired with their determinants\nmatsWithDets :: Int -> Int -> [(Matrix Int, Int)]\nmatsWithDets m n = map (\\x -> (x, determinant x `mod` n)) $ allMatrices m n\n\n-- Nonzero determinants\nmGL m n = map fst $ filter (\\(x,d) -> d /= 0) $ matsWithDets m n\n-- Determinant is 1\nmSL m n = map fst $ filter (\\(x,d) -> d == 1) $ matsWithDets m n\n```\n:::\n\n\n</details>\n\n\n### Projectivity\n\nAnother important matrix group is the\n [*projective general linear group*](https://en.wikipedia.org/wiki/Projective_linear_group),\n PGL(*n*, *K*).\nIn this group, two matrices are considered equal if one is a scalar multiple of the other[^2].\nBoth this and the determinant 1 constraint can apply at the same time,\n forming the *projective special linear group*, PSL(*n*, *K*).\n\n[^2]: Equivalently, the elements *are* these equivalence classes.\n The product of two classes is the set of all possible products between the two classes,\n which is another class.\n\nFor GF(2), all of these groups are the same, since the only nonzero determinant and scalar multiple is 1.\nTherefore, it's beneficial to contrast SL and PGL with another example.\n\nLet's arbitrarily examine GL(2, 5).\nSince 4 squares to 1 (mod 5) and we're working with 2×2 matrices, the determinant is unchanged\n when a matrix is scalar-multiplied by 4.\nThese multiples are identified in PSL.\nOn the other hand, in PGL, there are classes of matrices with determinant 2 and 3, which do not square to 1.\nThese classes are exactly the ones which are \"left out\" of PSL.\n\n$$\n\\begin{matrix}\n \\boxed{ \\begin{gather*}\n \\large \\text{GL}(2, 5)\n \\\\\n \\underset{\\det = 4}{\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix} \\right) },\n \\textcolor{red}{ \\underset{\\det = 1}{\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 2 \\\\\n 2 & 2\n \\end{matrix} \\right)\n }},\n \\underset{\\det = 2}{\n \\scriptsize\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 2\n \\end{matrix} \\right)\n },\n \\underset{\\det = 3}{\n \\scriptsize\n \\left(\\begin{matrix}\n 2 & 0 \\\\\n 0 & 4\n \\end{matrix} \\right)\n },\n ...\n \\end{gather*} }\n & \\twoheadrightarrow &\n \\boxed{ \\begin{gather*}\n \\large \\text{PGL}(2,5)\n \\\\\n \\underset{\\det = 1, ~4}{\n \\scriptsize\n \\textcolor{red}{\\left\\{\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix} \\right),\n \\left(\\begin{matrix}\n 0 & 2 \\\\\n 2 & 2\n \\end{matrix} \\right),\n ...\n \\right\\}\n }}\n \\\\\n \\underset{\\det = 2, ~ 3}{\n \\scriptsize\n \\left\\{ \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 2\n \\end{matrix} \\right),\n \\left(\\begin{matrix}\n 2 & 0 \\\\\n 0 & 4\n \\end{matrix} \\right),\n ...\n \\right\\}\n }\n \\\\\n ...\n \\end{gather*}\n }\n \\\\ \\\\\n \\boxed{ \\begin{gather*}\n \\large \\text{SL}(2,5)\n \\\\\n \\textcolor{red}{\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 2 \\\\\n 2 & 2\n \\end{matrix} \\right)\n },\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 3 \\\\\n 3 & 3\n \\end{matrix} \\right),\n ...\n \\end{gather*} }\n & \\twoheadrightarrow &\n \\boxed{ \\begin{gather*}\n \\large \\text{PSL}(2,5)\n \\\\\n \\textcolor{red}{ \\left\\{\n \\scriptsize\n \\left(\\begin{matrix}\n 0 & 2 \\\\\n 2 & 2\n \\end{matrix} \\right),\n \\left(\\begin{matrix}\n 0 & 3 \\\\\n 3 & 3\n \\end{matrix} \\right),\n ...\n \\right\\} }\n ...\n \\end{gather*} }\n\\end{matrix}\n$$\n\n::: {#7533e591 .cell execution_count=5}\n``` {.haskell .cell-code code-fold=\"true\" code-summary=\"Haskell implementation of PGL and PSL for prime fields\"}\nimport Data.List (nubBy)\n\n-- PGL and PSL require special equality.\n-- It's certainly possible to write a definition which makes the classes explicit, as its own new type.\n-- We could then define equality on this type through `Eq`.\n-- This is rather inefficient, though, so I'll choose to work with the representatives instead.\n\n-- Scalar-multiply a matrix (mod p)\nscalarTimes :: Int -> Int -> Matrix Int -> Matrix Int\nscalarTimes n k = fmap ((`mod` n) . (*k))\n\n-- Construct all scalar multiples mod n, then check if ys is any of them.\n-- This is ludicrously inefficient, and only works for fields.\nprojEq :: Int -> Matrix Int -> Matrix Int -> Bool\nprojEq n xs ys = ys `elem` [scalarTimes n k xs | k <- [1..n-1]]\n\n-- Strip out duplicates in GL and SL with projective equality\nmPGL m n = nubBy (projEq n) $ mGL m n\nmPSL m n = nubBy (projEq n) $ mSL m n\n```\n:::\n\n\n### Exceptional Isomorphisms\n\nWhen *K* is a finite field, the smaller PSLs turn out specify some interesting groups.\nWe've studied the case of PSL(2, 2) being isomorphic to *S*~3~ already, but it is also the case that:\n\n$$\n\\begin{align*}\n &\\text{PSL}(2,3) \\cong A_4 & & \\text{(order 24)}\n \\\\ \\\\\n &\\text{PSL}(2,4) \\cong \\text{PSL}(2,5) \\cong A_5 & & \\text{(order 60)}\n \\\\ \\\\\n &\\text{PSL}(2,7) \\cong \\text{PSL}(3,2) & & \\text{(order 168)}\n\\end{align*}\n$$\n\nThese relationships can be proven abstractly (and frequently are!).\nHowever, I always found myself wanting.\nFor PSL(2, 3) and *A*~4~, it's trivial to assign elements to one another by hand.\nBut *A*~5~ is getting untenable, to say nothing of PSL(2, 7).\nIn these circumstances, it's a good idea to leverage the computer.\n\n\nWarming Up: *A*~5~ and PSL(2, 5)\n--------------------------------\n\n*A*~5~, the alternating group on 5 elements, is composed of the\n [even](https://en.wikipedia.org/wiki/Parity_of_a_permutation) permutations of 5 elements.\nIt also happens to describe the rotations of an icosahedron.\nWithin the group, there are three kinds of elements:\n\n- The product of two 2-cycles, such as *a* = (1 2)(3 4)\n - On an icosahedron, this corresponds to a 180 degree rotation\n (or more precisely, 1/2 of a turn) about an edge\n- 5-cycles, such as *b* = (1 2 3 4 5)\n - This corresponds to a 72 degree rotation (1/5 of a turn)\n around a vertex\n- 3-cycles, such as *ab* = (2 4 5)\n - This corresponds to a 120 degree rotation (1/3 of a turn)\n around the center of a face\n\nIt happens to be the case that all elements of the group can be expressed\n as a product between *a* and *b* -- they generate the group.\n\n\n### Mapping to Matrices\n\nTo create a correspondence with PSL(2, 5), we need to identify permutations with matrices.\nObviously, the identity permutation goes to the identity matrix.\nThen, since *a* and *b* generate the group, we can search for two matrices which\n obey the same relations (under projective equality, since we're working in PSL).\n\nFortunately, we have a computer, so we can search for candidates rather quickly.\nFirst, let's note a matrix *B* which is cyclic of order 5 to correspond with *b*:\n\n::: {#66d77e13 .cell execution_count=6}\n``` {.haskell .cell-code code-fold=\"true\" code-summary=\"Haskell implementation of finding candidates for B\"}\n-- Repeatedly apply f to p, until the predicate z\n-- (usually equality to some quantity) becomes True.\n-- Get the length of the resulting list\norderWith :: Eq a => (a -> a -> a) -> (a -> Bool) -> a -> Int\norderWith f z p = (+1) $ length $ takeWhile (not . z) $ iterate (f p) p\n\n-- Order with respect to PSL(2, 5): using matrix multiplication (mod 5)\n-- and projective equality to the identity matrix\norderPSL25 = orderWith (\\x -> fmap (`mod` 5) . (x |*|)) (projEq 5 $ eye 2)\n\n-- Only order 5 elements of PSL(2, 5)\npsl25_order5 = filter ((==5) . orderPSL25) $ mPSL 2 5\n\nmarkdown $ (\"$$B = \" ++) $ (++ \"... $$\") $ intercalate \" ~,~ \" $\n take 5 $ map texifyMatrix psl25_order5\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown}\n$$B = \\left( \\begin{matrix}2 & 0 \\\\ 1 & 2\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}2 & 0 \\\\ 2 & 2\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}2 & 0 \\\\ 3 & 2\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}2 & 0 \\\\ 4 & 2\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}0 & 1 \\\\ 1 & 1\\end{matrix} \\right)... $$\n:::\n:::\n\n\nArbitrarily, let's pick the last entry on this list.\nNow, we can search for order-2 elements in PSL(2, 5) whose product with *B* has order 3.\nThis matrix (*A*) matches exactly with *a* in *A*~5~.\n\n::: {#0ed9f298 .cell execution_count=7}\n``` {.haskell .cell-code code-fold=\"true\" code-summary=\"Haskell implementation using B as a generator to find candidates for A\"}\n-- Start with B as a generator\npsl25_gen_B = toMatrix [[0,2],[2,2]]\n\n-- Only order 2 elements of PSL(2, 5)\npsl25_order2 = filter ((==2) . orderPSL25) $ mPSL 2 5\n\n-- Find an order 2 element whose product with `psl25_gen_B` has order 3\npsl25_gen_A_candidates = filter ((==3) . orderPSL25 . (psl25_gen_B |*|))\n psl25_order2\n\nmarkdown $ (\"$$A = \" ++) $ (++ \"$$\") $ intercalate \" ~,~ \" $\n map texifyMatrix psl25_gen_A_candidates\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown}\n$$A = \\left( \\begin{matrix}1 & 0 \\\\ 0 & 4\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}1 & 0 \\\\ 2 & 4\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}2 & 1 \\\\ 2 & 3\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}1 & 2 \\\\ 0 & 4\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}2 & 2 \\\\ 1 & 3\\end{matrix} \\right)$$\n:::\n:::\n\n\nAgain, arbitrarily, we'll pick the last entry from this list.\nLet's also peek at what the matrix *AB* looks like.\n\n::: {#4645affa .cell execution_count=8}\n``` {.haskell .cell-code code-fold=\"true\"}\npsl25_gen_AB = (`mod` 5) <$> (psl25_gen_A_candidates !! 4) |*| psl25_gen_B\n\nmarkdown $ (\"$$\" ++) $ (++ \"$$\") $ intercalate \" \\\\quad \" [\n \"(AB) = \" ++ texifyMatrix psl25_gen_AB,\n \"(AB)^3 = \" ++ texifyMatrix ((`mod` 5) <$> (psl25_gen_AB^3))\n ]\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown}\n$$(AB) = \\left( \\begin{matrix}4 & 3 \\\\ 1 & 3\\end{matrix} \\right) \\quad (AB)^3 = \\left( \\begin{matrix}2 & 0 \\\\ 0 & 2\\end{matrix} \\right)$$\n:::\n:::\n\n\nWe now have a correspondence between three elements of *A*~5~ and PSL(2, 5).\nWe can \"run\" both sets of the generators until we associate all elements to one another.\nThis is most visually appealing to see as a Cayley graph[^3]:\n\n[\n ![\n Cayley graph showing an isomorphism between A5 and PSL(2, 5). <br>\n Order-2 elements are red, order-3 elements are green, and order-5 elements are blue.\n Purple arrows are order-5 generators, orange arrows are order-2 generators.\n ](./a5_psl25_cayley.png){.narrow}\n](./a5_psl24_cayley.png)\n\n[^3]: Different generators appear to be used for *A* and *B* due to some\n self-imposed turbulence when writing the original post.\n Under projective equality, both are the same as our choices of *A* and *B*.\n\n\nPSL(2, 4)\n---------\n\nWe could do the same for PSL(2, 4), but we can't just work modulo 4\n -- remember, the elements of GF(4) are 0, 1, *α*, and *α*^2^.\nIt follows that GL(2, 4) is composed of (invertible) matrices of those elements,\n and SL(2, 4) is composed of matrices with determinant 1.\n\n$$\n\\begin{matrix}\n \\boxed{ \\begin{gather*}\n \\large \\text{GL}(2, 4)\n \\\\\n \\textcolor{red}{ \\underset{\\det = 1}{\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix} \\right)\n }},\n \\underset{\\det = \\alpha + 1}{\n \\left(\\begin{matrix}\n 0 & \\alpha \\\\\n \\alpha & \\alpha\n \\end{matrix} \\right)\n },\n \\underset{\\det = \\alpha}{\n \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & \\alpha\n \\end{matrix} \\right)\n },\n \\textcolor{red}{\n \\underset{\\det = 1}{\n \\left(\\begin{matrix}\n \\alpha & 0 \\\\\n 0 & \\alpha^2\n \\end{matrix} \\right)\n }},\n ...\n \\end{gather*} }\n \\\\ \\\\\n \\boxed{ \\begin{gather*}\n \\large \\text{SL}(2,4)\n \\\\\n \\textcolor{red}{\n \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix} \\right)\n },\n \\textcolor{red}{\n \\left(\\begin{matrix}\n \\alpha & 0 \\\\\n 0 & \\alpha^2\n \\end{matrix} \\right)\n },\n ...\n \\end{gather*} }\n\\end{matrix}\n$$\n\nScalar multiplication by *α* multiplies the determinant by *α*^2^;\n by *α*^2^ multiplies the determinant by *α*^4^ = *α*.\nThus, SL(2, 4) is also PSL(2, 4), since a scalar multiple has determinant 1.\n\nLet's start by looking at an order-5 matrix over PSL(2, 4).\nWe'll call this matrix *B*' to correspond with our order-5 generator in PSL(2, 5).\n\n$$\n\\begin{gather*}\n B' = \\left(\\begin{matrix}\n 0 & \\alpha \\\\\n \\alpha^2 & \\alpha^2\n \\end{matrix} \\right)\n \\qquad\n (B')^2 = \\left(\\begin{matrix}\n 1 & 1 \\\\\n \\alpha & \\alpha^2\n \\end{matrix}\\right)\n \\qquad\n (B')^3 = \\left(\\begin{matrix}\n \\alpha^2 & 1 \\\\\n \\alpha & 1\n \\end{matrix}\\right)\n \\\\\n (B')^4 = \\left(\\begin{matrix}\n \\alpha^2 & \\alpha \\\\\n \\alpha^2 & 0\n \\end{matrix}\\right)\n \\qquad\n (B')^5 = \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix}\\right)\n \\\\ \\\\\n \\det B' = 0\\alpha^2 - \\alpha^3 = 1\n\\end{gather*}\n$$\n\n\nWe need to be able to do three things over GL(2, 4) on a computer:\n\n- multiply matrices over GF(4),\n- compute their determinant,\n- visually distinguish between each of them, and\n- be able to systematically write down all of them\n\nIt would then follow for us to repeat what we did with with SL(2, 5).\nBut as I've said, working symbolically is hard for computers, and the methods described for prime fields\n do not work in general with prime power fields.\nFortunately, we're amply prepared to find a solution.\n\n\n### Bootstrapping Matrices\n\nRecall that the elements of GF(4) can also be written as the zero matrix, the identity matrix,\n *C*~*p*~, and *C*~*p*~^2^ (where *C*~*p*~ is the companion matrix of *p*(x)\n and again, *p*(x) = *x*^2^ + *x* + 1).\nThis means we can also write elements of GL(2, 4) as matrices *of matrices*.\nArithmetic works exactly the same as it does symbolically\n -- we just replace all instances of *α* in *B*' with *C*~*p*~.\n\n$$\n\\begin{gather*}\n f^* : \\mathbb{F}_4 {}^{2 \\times 2} \\rightarrow (\\mathbb{F}_2 {}^{2 \\times 2})^{2 \\times 2}\n \\\\ \\\\\n \\begin{align*}\n \\bar {B'} = f^*(B') &= \\left(\\begin{matrix}\n f(0) & f(\\alpha) \\\\\n f(\\alpha^2) & f(\\alpha^2)\n \\end{matrix} \\right) = \\left(\\begin{matrix}\n {\\bf 0} & C_p \\\\\n C_p {}^2 & C_p {}^2\n \\end{matrix} \\right) \\\\\n &= \\left(\\begin{matrix}\n \\left(\\begin{matrix} 0 & 0 \\\\ 0 & 0 \\end{matrix} \\right) &\n \\left(\\begin{matrix} 0 & 1 \\\\ 1 & 1 \\end{matrix} \\right) \\\\\n \\left(\\begin{matrix} 1 & 1 \\\\ 1 & 0 \\end{matrix} \\right) &\n \\left(\\begin{matrix} 1 & 1 \\\\ 1 & 0 \\end{matrix} \\right)\n \\end{matrix} \\right)\n \\\\ ~ \\\\\n (f^*(\\bar B'))^2 &= \\left(\\begin{matrix}\n ({\\bf 0})({\\bf 0}) + C_p {}^3 & ({\\bf 0})C_p +C_p {}^3 \\\\\n ({\\bf 0})C_p {}^2 + C_p {}^4 & C_p {}^3 + C_p {}^4\n \\end{matrix} \\right) \\\\\n &= \\left(\\begin{matrix}\n I & I \\\\\n C_p {} & C_p {}^2\n \\end{matrix} \\right) = \\left(\\begin{matrix}\n f(1) & f(1) \\\\\n f(\\alpha) & f(\\alpha^2)\n \\end{matrix} \\right) =\n f^*((B')^2)\n \\end{align*}\n\\end{gather*}\n$$\n\nMake no mistake, this is *not* a [block matrix](https://en.wikipedia.org/wiki/Block_matrix),\n at least not a typical one.\nNamely, the layering means that the determinant (which signifies its membership in SL) is another matrix:\n\n$$\n\\begin{align*}\n \\det( f^*(B') ) &= {\\bf 0} (C_p {}^2) - (C_p)(C_p {}^2)\n \\\\\n &= \\left(\\begin{matrix}\n 0 & 0 \\\\\n 0 & 0\n \\end{matrix} \\right)\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 0\n \\end{matrix} \\right)\n - \\left(\\begin{matrix}\n 0 & 1 \\\\\n 1 & 1\n \\end{matrix} \\right)\n \\left(\\begin{matrix}\n 1 & 1 \\\\\n 1 & 0 \\end{matrix}\n \\right)\n \\\\\n &= \\left(\\begin{matrix}\n 1 & 0 \\\\\n 0 & 1\n \\end{matrix} \\right) \\mod 2\n \\\\\n &= I = f(\\det(B'))\n\\end{align*}\n$$\n\nSince *B*' is in SL(2, 4), the determinant is unsurprisingly *f*(1) = I.\nThe (matrix) determinants of *f*\\* applied to other elements of GL(2, 4)\n could just as well be *f*(*α*) = *C*~*p*~ or *f*(*α*^2^) = *C*~*p*~^2^.\n\n\n### Implementation\n\nUsing this method, we can implement PSL(2, 4) directly.\nAll we need to do is find all possible 4-tuples of **0**, *I*, *C*~*p*~, and *C*~*p*~^2^,\n then arrange each into a 2x2 matrix.\nMultiplication follows from the typical definition and the multiplicative identity is just *f*\\*(*I*).\n\n::: {#55360e06 .cell execution_count=9}\n``` {.haskell .cell-code code-fold=\"true\" code-summary=\"Haskell implementation of PSL(2, 4)\"}\nimport Data.List (elemIndex)\n\n-- Matrices which obey the same relations as the elements of GF(4)\nzero_f4 = zero 2\none_f4 = eye 2\nalpha_f4 = toMatrix [[0,1],[1,1]]\nalpha2_f4 = toMatrix [[1,1],[1,0]]\n\n-- Gathered into a list\nfield4 = [zero_f4, one_f4, alpha_f4, alpha2_f4]\n\n-- Convenient show function for these matrices\nshowF4 x = case elemIndex x field4 of\n Just 0 -> \"0\"\n Just 1 -> \"1\"\n Just 2 -> \"α\"\n Just 3 -> \"α^2\"\n Nothing -> \"N/A\"\n\n-- Identity matrix over GF(4)\npsl_24_identity = toMatrix [[one_f4, zero_f4], [zero_f4, one_f4]]\n\n-- All possible matrices over GF(4)\n-- Create a list of 4-lists of elements from GF(4), then\n-- Shape them into 2x2 matrices\nf4_matrices = map (toMatrix . reshape 2) $ replicateM 4 field4\n\n-- Sieve out those which have a determinant of 1 in the field\nmPSL24 = filter ((==one_f4) . fmap (`mod` 2) . laplaceDet) f4_matrices\n```\n:::\n\n\nNow that we can generate the group, we can finally repeat what we did with PSL(2, 5).\nAll we have to do is filter out order-2 elements, then further filter\n for those which have an order-3 product with *B*'.\n\n::: {#891047c6 .cell execution_count=10}\n``` {.haskell .cell-code code-fold=\"true\" code-summary=\"Haskell implementation using *B*' as a generator to find candidates for *A*'\"}\n-- Order with respect to PSL(2, 4): using matrix multiplication (mod 2)\n-- and projective equality to the identity matrix\norderPSL24 = orderWith (\\x -> fmap (fmap (`mod` 2)) . (x*)) (== psl_24_identity)\n\n-- Only order 2 elements of PSL(2, 4)\npsl24_order2 = filter ((==2) . orderPSL24) mPSL24\n\n-- Start with B as a generator\npsl24_gen_B = toMatrix [[zero_f4, alpha_f4], [alpha2_f4, alpha2_f4]]\n\n-- Find an order 2 element whose product with `psl24_gen_B` has order 3\npsl24_gen_A_candidates = filter ((==3) . orderPSL24 . (psl24_gen_B |*|))\n psl24_order2\n\nmarkdown $ (\"$$ A' = \" ++) $ (++ \"$$\") $ intercalate \" ~,~ \" $\n map (texifyMatrix' showF4) psl24_gen_A_candidates\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown}\n$$ A' = \\left( \\begin{matrix}0 & 1 \\\\ 1 & 0\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}0 & α^2 \\\\ α & 0\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}1 & 0 \\\\ 1 & 1\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}1 & α^2 \\\\ 0 & 1\\end{matrix} \\right) ~,~ \\left( \\begin{matrix}α & 1 \\\\ α & α\\end{matrix} \\right)$$\n:::\n:::\n\n\nWe'll pick the second entry as our choice of *A*'.\nWe note that the product *A'B'*, does indeed have order 3.\n\n::: {#8ad49800 .cell execution_count=11}\n``` {.haskell .cell-code code-fold=\"true\"}\npsl24_gen_AB = fmap (`mod` 2) <$> (psl24_gen_A_candidates !! 1) |*| psl24_gen_B\n\nmarkdown $ (\"$$\" ++) $ (++ \"$$\") $ intercalate \" \\\\quad \" [\n \"(A'B') = \" ++ texifyMatrix' showF4 psl24_gen_AB,\n \"(A'B')^3 = \" ++ texifyMatrix' showF4 (fmap (`mod` 2) <$> (psl24_gen_AB^3))\n ]\n```\n\n::: {.cell-output .cell-output-display .cell-output-markdown}\n$$(A'B') = \\left( \\begin{matrix}α & α \\\\ 0 & α^2\\end{matrix} \\right) \\quad (A'B')^3 = \\left( \\begin{matrix}1 & 0 \\\\ 0 & 1\\end{matrix} \\right)$$\n:::\n:::\n\n\nFinally, we can arrange these matrices on a Cayley graph in the same way as PSL(2, 5):\n\n[\n ![\n Cayley graph showing an isomorphism between *A*~5~ and PSL(2, 4). <br>\n Colors indicate the same thing as in the previous diagram.\n ](./a5_psl24_cayley.png){.narrow}\n](./a5_psl24_cayley.png)\n\n\nClosing\n-------\n\nThis post addresses my original goal in implementing finite fields,\n namely computationally finding an explicit map between *A*~5~ and PSL(2, 4).\nI believe the results are a little more satisfying than attempting to wrap your head\n around group-theoretic proofs.\nThat's not to discount the power and incredible logic that goes into the latter method.\nIt does tend to leave things rather opaque, however.\n\nIf you'd prefer a more interactive diagram showing the above isomorphisms,\n I've gone to the liberty of creating a hoverable SVG:\n\n[\n ![\n Click to open interactive version\n ](./a5_psl24_psl25_isomorphism.svg){.narrow}\n](./a5_psl24_psl25_isomorphism.svg)\n\nThis post slightly diverts our course from the previous one's focus on fields.\nThe [next one](../4) will focus on more results regarding the treatment of layered matrices.\nThe algebraic consequences of this structure are notable in and of themselves,\n and are entirely obfuscated by the usual interpretation of block matrices.\n\nDiagrams created with Geogebra and Inkscape.\n\n",
"supporting": [
"index_files/figure-html"
],
"filters": [],
"includes": {}
}
}