haskellify finite-field.3
This commit is contained in:
parent
8d14c5b414
commit
91cfd2397a
1
posts/finite-field/3/Previous.hs
Symbolic link
1
posts/finite-field/3/Previous.hs
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../2/Previous.hs
|
||||||
@ -5,9 +5,8 @@ description: |
|
|||||||
format:
|
format:
|
||||||
html:
|
html:
|
||||||
html-math-method: katex
|
html-math-method: katex
|
||||||
jupyter: python3
|
|
||||||
date: "2024-02-03"
|
date: "2024-02-03"
|
||||||
date-modified: "2025-07-16"
|
date-modified: "2025-08-04"
|
||||||
categories:
|
categories:
|
||||||
- algebra
|
- algebra
|
||||||
- finite field
|
- finite field
|
||||||
@ -15,26 +14,64 @@ categories:
|
|||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.red {
|
.narrow {
|
||||||
color: red;
|
max-width: 512px;
|
||||||
}
|
|
||||||
.orange {
|
|
||||||
color: orange;
|
|
||||||
}
|
|
||||||
.yellow {
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
.green {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
.blue {
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
.purple {
|
|
||||||
color: purple;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
--| echo: false
|
||||||
|
|
||||||
|
:l Previous.hs
|
||||||
|
|
||||||
|
import Data.Array (ixmap, bounds, (!))
|
||||||
|
import Data.List (intercalate)
|
||||||
|
import IHaskell.Display (markdown)
|
||||||
|
|
||||||
|
import Previous (
|
||||||
|
Matrix(Mat, unMat), Polynomial(Poly, coeffs),
|
||||||
|
asPoly, evalPoly, synthDiv,
|
||||||
|
companion, zero, eye, determinant
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Explicit Matrix operations
|
||||||
|
(|+|) :: Num a => Matrix a -> Matrix a -> Matrix a
|
||||||
|
(|+|) = (+)
|
||||||
|
|
||||||
|
(|*|) :: Num a => Matrix a -> Matrix a -> Matrix a
|
||||||
|
(|*|) = (*)
|
||||||
|
|
||||||
|
-- Original determinant implementation, instead of the imported one based on Faddeev-Leverrier
|
||||||
|
laplaceDet :: (Num a, Eq a) => Matrix a -> a
|
||||||
|
laplaceDet (Mat xs) = determinant' xs where
|
||||||
|
-- Evaluate (-1)^i without repeated multiplication
|
||||||
|
parity i = if even i then 1 else -1
|
||||||
|
-- Map old array addresses to new ones when eliminating row 0, column i
|
||||||
|
rowMap i (x,y) = (x+1, if y >= i then y+1 else y)
|
||||||
|
-- Recursive determinant Array
|
||||||
|
determinant' xs
|
||||||
|
-- Base case: 1x1 matrix
|
||||||
|
| n == 0 = xs!(0,0)
|
||||||
|
-- Sum of cofactor expansions
|
||||||
|
| otherwise = sum $ map cofactor [0..n] where
|
||||||
|
-- Produce the cofactor of row 0, column i
|
||||||
|
cofactor i
|
||||||
|
| xs!(0,i) == 0 = 0
|
||||||
|
| otherwise = (parity i) * xs!(0,i) * determinant' (minor i)
|
||||||
|
-- Furthest extent of the bounds, i.e., the size of the matrix
|
||||||
|
(_,(n,_)) = bounds xs
|
||||||
|
-- Build a new Array by eliminating row 0 and column i
|
||||||
|
minor i = ixmap ((0,0),(n-1,n-1)) (rowMap i) xs
|
||||||
|
|
||||||
|
-- Convert matrix to LaTeX string
|
||||||
|
texifyMatrix' f mat = surround mat' where
|
||||||
|
mat' = intercalate " \\\\ " $ map (intercalate " & " . map f) $
|
||||||
|
fromMatrix mat
|
||||||
|
surround = ("\\left( \\begin{matrix}" ++) . (++ "\\end{matrix} \\right)")
|
||||||
|
|
||||||
|
texifyMatrix = texifyMatrix' show
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
In the [previous post](../2), we focused on constructing finite fields using *n*×*n* matrices.
|
In the [previous post](../2), we focused on constructing finite fields using *n*×*n* matrices.
|
||||||
These matrices came from from primitive polynomials of degree *n* over GF(*p*),
|
These matrices came from from primitive polynomials of degree *n* over GF(*p*),
|
||||||
@ -59,12 +96,12 @@ $$
|
|||||||
0 & 0 \\
|
0 & 0 \\
|
||||||
0 & 0
|
0 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
1 \mapsto \left(\begin{matrix}
|
1 \mapsto \left(\begin{matrix}
|
||||||
1 & 0 \\
|
1 & 0 \\
|
||||||
0 & 1
|
0 & 1
|
||||||
\end{matrix}\right) = I
|
\end{matrix}\right) = I
|
||||||
\quad
|
~~
|
||||||
\alpha \mapsto \left(\begin{matrix}
|
\alpha \mapsto \left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
1 & 1
|
1 & 1
|
||||||
@ -93,9 +130,9 @@ $$
|
|||||||
In the images of *f*, the zero matrix has determinant 0 and all other elements have determinant 1.
|
In the images of *f*, the zero matrix has determinant 0 and all other elements have determinant 1.
|
||||||
Therefore, the product of any two nonzero matrices always has determinant 1,
|
Therefore, the product of any two nonzero matrices always has determinant 1,
|
||||||
and a nonzero determinant means the matrix is invertible.
|
and a nonzero determinant means the matrix is invertible.
|
||||||
This means that the non-zero elements of the field form their own group with respect to multiplication.
|
Per the definition of the field, the non-zero elements form a group with respect to multiplication.
|
||||||
Here, they form a cyclic group of order 3, since *C*~*p*~^3^ = *I* mod 2.
|
Here, they form a cyclic group of order 3, since *C*~*p*~^3^ = *I* mod 2.
|
||||||
This is also true using symbols, and we've already agreed that *α*^3^ = 1.
|
This is also true using symbols, since *α*^3^ = 1.
|
||||||
|
|
||||||
|
|
||||||
### Other Matrices
|
### Other Matrices
|
||||||
@ -109,47 +146,51 @@ $$
|
|||||||
\#\{a_{ij} = 1\} & \det = 0 & \det = 1
|
\#\{a_{ij} = 1\} & \det = 0 & \det = 1
|
||||||
\\ \hline
|
\\ \hline
|
||||||
1 &
|
1 &
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
0 & 0
|
0 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 0 \\
|
1 & 0 \\
|
||||||
0 & 0
|
0 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 0 \\
|
0 & 0 \\
|
||||||
0 & 1
|
0 & 1
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 0 \\
|
0 & 0 \\
|
||||||
1 & 0
|
1 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\\
|
\\
|
||||||
2 &
|
2 &
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 1 \\
|
1 & 1 \\
|
||||||
0 & 0
|
0 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 0 \\
|
0 & 0 \\
|
||||||
1 & 1
|
1 & 1
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
0 & 1
|
0 & 1
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
\quad
|
~~
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 1 \\
|
1 & 1 \\
|
||||||
0 & 0
|
0 & 0
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
& \textcolor{red}{
|
&
|
||||||
|
\scriptsize
|
||||||
|
\textcolor{red}{
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
1 & 0
|
1 & 0
|
||||||
@ -157,13 +198,14 @@ $$
|
|||||||
}
|
}
|
||||||
\\
|
\\
|
||||||
3 & &
|
3 & &
|
||||||
|
\scriptsize
|
||||||
\textcolor{red}{
|
\textcolor{red}{
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 1 \\
|
1 & 1 \\
|
||||||
0 & 1
|
0 & 1
|
||||||
\end{matrix}\right)
|
\end{matrix}\right)
|
||||||
}
|
}
|
||||||
\quad
|
~~
|
||||||
\textcolor{red}{
|
\textcolor{red}{
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 0 \\
|
1 & 0 \\
|
||||||
@ -172,6 +214,7 @@ $$
|
|||||||
}
|
}
|
||||||
\\
|
\\
|
||||||
4 &
|
4 &
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 1 \\
|
1 & 1 \\
|
||||||
1 & 1
|
1 & 1
|
||||||
@ -184,12 +227,15 @@ The matrices in the right column (in red) have determinant 1, which means they c
|
|||||||
This forms a larger group, of which our field's multiplication group is a subgroup.
|
This forms a larger group, of which our field's multiplication group is a subgroup.
|
||||||
However, it is *not* commutative, since matrix multiplication is not commutative in general.
|
However, it is *not* commutative, since matrix multiplication is not commutative in general.
|
||||||
|
|
||||||
The group of all six matrices of determinant 1 is called the
|
The group of all six matrices with nonzero determinant is called the
|
||||||
[*general linear group*](https://en.wikipedia.org/wiki/General_linear_group)
|
[*general linear group*](https://en.wikipedia.org/wiki/General_linear_group)
|
||||||
of degree 2 over GF(2), written GL(2, 2).
|
of degree 2 over GF(2), written[^1] GL(2, 2).
|
||||||
We can sort the elements into classes by their order, or the number of times we have
|
We can sort the elements into classes by their order, or the number of times we have
|
||||||
to multiply them before getting to the identity matrix (mod 2):
|
to multiply them before getting to the identity matrix (mod 2):
|
||||||
|
|
||||||
|
[^1]: Unfortunately, it's rather easy to confuse "GF" with "GL".
|
||||||
|
Remember that "F" is for "field", with the former standing for "Galois field".
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{array}{}
|
\begin{array}{}
|
||||||
\text{Order 1} & \text{Order 2} & \text{Order 3}
|
\text{Order 1} & \text{Order 2} & \text{Order 3}
|
||||||
@ -232,10 +278,10 @@ $$
|
|||||||
|
|
||||||
If you've studied enough group theory, you know that there are two groups of order 6:
|
If you've studied enough group theory, you know that there are two groups of order 6:
|
||||||
the cyclic group of order 6, *C*~6~, and the symmetric group on three elements, *S*~3~.
|
the cyclic group of order 6, *C*~6~, and the symmetric group on three elements, *S*~3~.
|
||||||
Since the former group has order-6 elements, this group must be isomorphic to the latter.
|
Since the former group has order-6 elements, but none of these matrices are of order 6,
|
||||||
|
the matrix group must be isomorphic to the latter.
|
||||||
Since the group is small, it's not too difficult to construct an isomorphism between the two.
|
Since the group is small, it's not too difficult to construct an isomorphism between the two.
|
||||||
Writing the elements of *S*~3~ in [cycle notation](), we have:
|
Writing the elements of *S*~3~ in [cycle notation](/posts/permutations/1/), we have:
|
||||||
<!-- TODO: permutations link -->
|
|
||||||
|
|
||||||
$$
|
$$
|
||||||
\begin{gather*}
|
\begin{gather*}
|
||||||
@ -293,11 +339,9 @@ Haskell implementation of GL and SL for prime fields
|
|||||||
This implementation will be based on the `Matrix` type from the first post.
|
This implementation will be based on the `Matrix` type from the first post.
|
||||||
Assume we have already defined matrix multiplication and addition.
|
Assume we have already defined matrix multiplication and addition.
|
||||||
|
|
||||||
```{.haskell}
|
```{haskell}
|
||||||
data Matrix a = Mat { unMat :: Array (Int, Int) a }
|
import Data.Array (listArray, bounds, elems)
|
||||||
|
import Data.List (unfoldr)
|
||||||
-- instance Functor Matrix
|
|
||||||
-- instance Num a => Num (Matrix a)
|
|
||||||
|
|
||||||
-- Partition a list into lists of length n
|
-- Partition a list into lists of length n
|
||||||
reshape :: Int -> [a] -> [[a]]
|
reshape :: Int -> [a] -> [[a]]
|
||||||
@ -316,27 +360,29 @@ fromMatrix :: Matrix a -> [[a]]
|
|||||||
fromMatrix (Mat m) = let (_,(_,n)) = bounds m in reshape (n+1) $ elems m
|
fromMatrix (Mat m) = let (_,(_,n)) = bounds m in reshape (n+1) $ elems m
|
||||||
```
|
```
|
||||||
|
|
||||||
With helper functions out of the way, we can move on to generating all matrices (mod *n*)
|
With helper functions out of the way, we can move on to generating all matrices (mod *n*).
|
||||||
before filtering for matrices with nonzero determinant (in the case of GL) and determinant 1
|
Then, we filter for matrices with nonzero determinant (in the case of GL) and determinant 1
|
||||||
(in the case of SL).
|
(in the case of SL).
|
||||||
|
|
||||||
```{.haskell}
|
```{haskell}
|
||||||
allMatrices :: Int -> Int -> Matrix Int
|
import Control.Monad (replicateM)
|
||||||
|
|
||||||
-- All m x m matrices (mod n)
|
-- All m x m matrices (mod n)
|
||||||
allMatrices m n = map toMatrix $ sequence $ replicate m vectors where
|
allMatrices :: Int -> Int -> [Matrix Int]
|
||||||
|
allMatrices m n = map toMatrix $ replicateM m vectors where
|
||||||
-- Construct all vectors mod n using base-n expansions and padding
|
-- Construct all vectors mod n using base-n expansions and padding
|
||||||
vectors = [pad $ coeffs $ asPoly n l | l <- [1..n^m-1]]
|
vectors = [pad $ coeffs $ asPoly n l | l <- [1..n^m-1]]
|
||||||
-- Pad xs to length m with zero
|
-- Pad xs to length m with zero
|
||||||
pad xs = xs ++ replicate 0 (m - length xs)
|
pad xs = xs ++ replicate (m - length xs) 0
|
||||||
|
|
||||||
-- All matrices, but paired with their determinants
|
-- All matrices, but paired with their determinants
|
||||||
matsWithDets :: Int -> Int -> [(Matrix Int, Int)]
|
matsWithDets :: Int -> Int -> [(Matrix Int, Int)]
|
||||||
matsWithDets m n = map (\x -> (x, determinant x `mod` n)) $ allMatrices m n
|
matsWithDets m n = map (\x -> (x, determinant x `mod` n)) $ allMatrices m n
|
||||||
|
|
||||||
-- Nonzero determinants
|
-- Nonzero determinants
|
||||||
mGL m n = map fst $ filter (\(x,d) -> d /= 0) $ matsWithDets' m n
|
mGL m n = map fst $ filter (\(x,d) -> d /= 0) $ matsWithDets m n
|
||||||
-- Determinant is 1
|
-- Determinant is 1
|
||||||
mSL m n = map fst $ filter (\(x,d) -> d == 1) $ matsWithDets' m n
|
mSL m n = map fst $ filter (\(x,d) -> d == 1) $ matsWithDets m n
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@ -346,13 +392,14 @@ mSL m n = map fst $ filter (\(x,d) -> d == 1) $ matsWithDets' m n
|
|||||||
Another important matrix group is the
|
Another important matrix group is the
|
||||||
[*projective general linear group*](https://en.wikipedia.org/wiki/Projective_linear_group),
|
[*projective general linear group*](https://en.wikipedia.org/wiki/Projective_linear_group),
|
||||||
PGL(*n*, *K*).
|
PGL(*n*, *K*).
|
||||||
In this group, two matrices are considered equal if one is a scalar multiple of the other.
|
In this group, two matrices are considered equal if one is a scalar multiple of the other[^2].
|
||||||
Equivalently, the elements *are* these equivalence classes, and the product of two classes is
|
|
||||||
the set of all possible products of items from one class with items from the other.
|
|
||||||
|
|
||||||
Both this and the determinant 1 constraint can apply at the same time,
|
Both this and the determinant 1 constraint can apply at the same time,
|
||||||
forming the *projective special linear group*, PSL(*n*, *K*).
|
forming the *projective special linear group*, PSL(*n*, *K*).
|
||||||
|
|
||||||
|
[^2]: Equivalently, the elements *are* these equivalence classes.
|
||||||
|
The product of two classes is the set of all possible products between the two classes,
|
||||||
|
which is another class.
|
||||||
|
|
||||||
For GF(2), all of these groups are the same, since the only nonzero determinant and scalar multiple is 1.
|
For GF(2), all of these groups are the same, since the only nonzero determinant and scalar multiple is 1.
|
||||||
Therefore, it's beneficial to contrast SL and PGL with another example.
|
Therefore, it's beneficial to contrast SL and PGL with another example.
|
||||||
|
|
||||||
@ -369,23 +416,27 @@ $$
|
|||||||
\large \text{GL}(2, 5)
|
\large \text{GL}(2, 5)
|
||||||
\\
|
\\
|
||||||
\underset{\det = 4}{
|
\underset{\det = 4}{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
1 & 1
|
1 & 1
|
||||||
\end{matrix} \right) },
|
\end{matrix} \right) },
|
||||||
\textcolor{red}{ \underset{\det = 1}{
|
\textcolor{red}{ \underset{\det = 1}{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 2 \\
|
0 & 2 \\
|
||||||
2 & 2
|
2 & 2
|
||||||
\end{matrix} \right)
|
\end{matrix} \right)
|
||||||
}},
|
}},
|
||||||
\underset{\det = 2}{
|
\underset{\det = 2}{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
1 & 0 \\
|
1 & 0 \\
|
||||||
0 & 2
|
0 & 2
|
||||||
\end{matrix} \right)
|
\end{matrix} \right)
|
||||||
},
|
},
|
||||||
\underset{\det = 3}{
|
\underset{\det = 3}{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
2 & 0 \\
|
2 & 0 \\
|
||||||
0 & 4
|
0 & 4
|
||||||
@ -398,6 +449,7 @@ $$
|
|||||||
\large \text{PGL}(2,5)
|
\large \text{PGL}(2,5)
|
||||||
\\
|
\\
|
||||||
\underset{\det = 1, ~4}{
|
\underset{\det = 1, ~4}{
|
||||||
|
\scriptsize
|
||||||
\textcolor{red}{\left\{
|
\textcolor{red}{\left\{
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 1 \\
|
0 & 1 \\
|
||||||
@ -412,6 +464,7 @@ $$
|
|||||||
}}
|
}}
|
||||||
\\
|
\\
|
||||||
\underset{\det = 2, ~ 3}{
|
\underset{\det = 2, ~ 3}{
|
||||||
|
\scriptsize
|
||||||
\left\{ \left(\begin{matrix}
|
\left\{ \left(\begin{matrix}
|
||||||
1 & 0 \\
|
1 & 0 \\
|
||||||
0 & 2
|
0 & 2
|
||||||
@ -432,11 +485,13 @@ $$
|
|||||||
\large \text{SL}(2,5)
|
\large \text{SL}(2,5)
|
||||||
\\
|
\\
|
||||||
\textcolor{red}{
|
\textcolor{red}{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 2 \\
|
0 & 2 \\
|
||||||
2 & 2
|
2 & 2
|
||||||
\end{matrix} \right)
|
\end{matrix} \right)
|
||||||
},
|
},
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 3 \\
|
0 & 3 \\
|
||||||
3 & 3
|
3 & 3
|
||||||
@ -448,6 +503,7 @@ $$
|
|||||||
\large \text{PSL}(2,5)
|
\large \text{PSL}(2,5)
|
||||||
\\
|
\\
|
||||||
\textcolor{red}{ \left\{
|
\textcolor{red}{ \left\{
|
||||||
|
\scriptsize
|
||||||
\left(\begin{matrix}
|
\left(\begin{matrix}
|
||||||
0 & 2 \\
|
0 & 2 \\
|
||||||
2 & 2
|
2 & 2
|
||||||
@ -463,32 +519,30 @@ $$
|
|||||||
\end{matrix}
|
\end{matrix}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
<details>
|
```{haskell}
|
||||||
<summary>
|
--| code-fold: true
|
||||||
Haskell implementation of PGL and PSL for prime fields
|
--| code-summary: "Haskell implementation of PGL and PSL for prime fields"
|
||||||
</summary>
|
|
||||||
PGL and PSL require special equality.
|
|
||||||
It's certainly possible to write a definition which makes the classes explicit, as its own new type.
|
|
||||||
We could then define equality on this type through `Eq`.
|
|
||||||
This is rather inefficient, though, so I'll choose to work with the representatives instead.
|
|
||||||
|
|
||||||
```{.haskell}
|
|
||||||
import Data.List (nubBy)
|
import Data.List (nubBy)
|
||||||
|
|
||||||
scalarTimes :: Int -> Int -> Matrix Int -> Matrix Int
|
-- PGL and PSL require special equality.
|
||||||
|
-- It's certainly possible to write a definition which makes the classes explicit, as its own new type.
|
||||||
|
-- We could then define equality on this type through `Eq`.
|
||||||
|
-- This is rather inefficient, though, so I'll choose to work with the representatives instead.
|
||||||
|
|
||||||
-- Scalar-multiply a matrix (mod p)
|
-- Scalar-multiply a matrix (mod p)
|
||||||
|
scalarTimes :: Int -> Int -> Matrix Int -> Matrix Int
|
||||||
scalarTimes n k = fmap ((`mod` n) . (*k))
|
scalarTimes n k = fmap ((`mod` n) . (*k))
|
||||||
|
|
||||||
projEq :: Int -> Matrix Int -> Matrix Int -> Bool
|
|
||||||
-- Construct all scalar multiples mod n, then check if ys is any of them.
|
-- Construct all scalar multiples mod n, then check if ys is any of them.
|
||||||
-- This is ludicrously inefficient, and only works for fields.
|
-- This is ludicrously inefficient, and only works for fields.
|
||||||
|
projEq :: Int -> Matrix Int -> Matrix Int -> Bool
|
||||||
projEq n xs ys = ys `elem` [scalarTimes n k xs | k <- [1..n-1]]
|
projEq n xs ys = ys `elem` [scalarTimes n k xs | k <- [1..n-1]]
|
||||||
|
|
||||||
-- Strip out duplicates in GL and SL with projective equality
|
-- Strip out duplicates in GL and SL with projective equality
|
||||||
mPGL m n = nubBy (projEq n) $ mGL m n
|
mPGL m n = nubBy (projEq n) $ mGL m n
|
||||||
mPSL m n = nubBy (projEq n) $ mSL m n
|
mPSL m n = nubBy (projEq n) $ mSL m n
|
||||||
```
|
```
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
### Exceptional Isomorphisms
|
### Exceptional Isomorphisms
|
||||||
@ -526,10 +580,10 @@ Within the group, there are three kinds of elements:
|
|||||||
(or more precisely, 1/2 of a turn) about an edge
|
(or more precisely, 1/2 of a turn) about an edge
|
||||||
- 5-cycles, such as *b* = (1 2 3 4 5)
|
- 5-cycles, such as *b* = (1 2 3 4 5)
|
||||||
- This corresponds to a 72 degree rotation (1/5 of a turn)
|
- This corresponds to a 72 degree rotation (1/5 of a turn)
|
||||||
around the center of a face
|
around a vertex
|
||||||
- 3-cycles, such as *ab* = (2 4 5)
|
- 3-cycles, such as *ab* = (2 4 5)
|
||||||
- This corresponds to a 120 degree rotation (1/3 of a turn)
|
- This corresponds to a 120 degree rotation (1/3 of a turn)
|
||||||
around a vertex
|
around the center of a face
|
||||||
|
|
||||||
It happens to be the case that all elements of the group can be expressed
|
It happens to be the case that all elements of the group can be expressed
|
||||||
as a product between *a* and *b* -- they generate the group.
|
as a product between *a* and *b* -- they generate the group.
|
||||||
@ -541,137 +595,82 @@ To create a correspondence with PSL(2, 5), we need to identify permutations with
|
|||||||
Obviously, the identity permutation goes to the identity matrix.
|
Obviously, the identity permutation goes to the identity matrix.
|
||||||
Then, since *a* and *b* generate the group, we can search for two matrices which
|
Then, since *a* and *b* generate the group, we can search for two matrices which
|
||||||
obey the same relations (under projective equality, since we're working in PSL).
|
obey the same relations (under projective equality, since we're working in PSL).
|
||||||
One such correspondence is:
|
|
||||||
|
|
||||||
$$
|
Fortunately, we have a computer, so we can search for candidates rather quickly.
|
||||||
\begin{array}{}
|
First, let's note a matrix *B* which is cyclic of order 5 to correspond with *b*:
|
||||||
\begin{gather*}
|
|
||||||
A = \left(\begin{matrix}
|
|
||||||
1 & 1 \\
|
|
||||||
3 & 4
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
A^2 = \left(\begin{matrix}
|
|
||||||
4 & 0 \\
|
|
||||||
0 & 4
|
|
||||||
\end{matrix}\right) =
|
|
||||||
4 \left(\begin{matrix}
|
|
||||||
1 & 0 \\
|
|
||||||
0 & 1
|
|
||||||
\end{matrix}\right)
|
|
||||||
\qquad
|
|
||||||
\end{gather*}
|
|
||||||
\\ ~ \\ \hline \\
|
|
||||||
\begin{gather*}
|
|
||||||
B = \left(\begin{matrix}
|
|
||||||
0 & 2 \\
|
|
||||||
2 & 2
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
B^2 = \left(\begin{matrix}
|
|
||||||
4 & 4 \\
|
|
||||||
4 & 3
|
|
||||||
\end{matrix}\right)
|
|
||||||
\qquad
|
|
||||||
B^3 = \left(\begin{matrix}
|
|
||||||
3 & 1 \\
|
|
||||||
1 & 4
|
|
||||||
\end{matrix}\right)
|
|
||||||
\\
|
|
||||||
B^4 = \left(\begin{matrix}
|
|
||||||
2 & 3 \\
|
|
||||||
3 & 0
|
|
||||||
\end{matrix}\right)
|
|
||||||
\qquad
|
|
||||||
B^5 = \left(\begin{matrix}
|
|
||||||
1 & 0 \\
|
|
||||||
0 & 1
|
|
||||||
\end{matrix}\right)
|
|
||||||
\end{gather*}
|
|
||||||
\\ ~ \\ \hline \\
|
|
||||||
\begin{gather*}
|
|
||||||
(AB) = \left(\begin{matrix}
|
|
||||||
2 & 4 \\
|
|
||||||
3 & 4
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
(AB)^2 = \left(\begin{matrix}
|
|
||||||
1 & 4 \\
|
|
||||||
3 & 3
|
|
||||||
\end{matrix}\right)
|
|
||||||
\qquad
|
|
||||||
(AB)^3 = \left(\begin{matrix}
|
|
||||||
4 & 0 \\
|
|
||||||
0 & 4
|
|
||||||
\end{matrix}\right)
|
|
||||||
\end{gather*} =
|
|
||||||
4 \left(\begin{matrix}
|
|
||||||
1 & 0 \\
|
|
||||||
0 & 1
|
|
||||||
\end{matrix}\right)
|
|
||||||
\end{array}
|
|
||||||
$$
|
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
--| code-fold: true
|
||||||
|
--| code-summary: "Haskell implementation of finding candidates for B"
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>
|
|
||||||
Haskell implementation using B as a generator to find candidates for A
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
```{.haskell}
|
|
||||||
orderWith :: Eq a => (a -> a -> a) -> (a -> Bool) -> a -> Int
|
|
||||||
-- Repeatedly apply f to p, until the predicate z
|
-- Repeatedly apply f to p, until the predicate z
|
||||||
-- (usually equality to some quantity) becomes True.
|
-- (usually equality to some quantity) becomes True.
|
||||||
-- Get the length of the resulting list
|
-- Get the length of the resulting list
|
||||||
|
orderWith :: Eq a => (a -> a -> a) -> (a -> Bool) -> a -> Int
|
||||||
orderWith f z p = (+1) $ length $ takeWhile (not . z) $ iterate (f p) p
|
orderWith f z p = (+1) $ length $ takeWhile (not . z) $ iterate (f p) p
|
||||||
|
|
||||||
-- Order with respect to PSL(2, 5): using matrix multiplication (mod 5)
|
-- Order with respect to PSL(2, 5): using matrix multiplication (mod 5)
|
||||||
-- and projective equality to the identity matrix
|
-- and projective equality to the identity matrix
|
||||||
orderPSL25 = orderWith (\x -> fmap (`mod` 5) . (x |*|))) (projEq 5 $ eye 2)
|
orderPSL25 = orderWith (\x -> fmap (`mod` 5) . (x |*|)) (projEq 5 $ eye 2)
|
||||||
|
|
||||||
-- Only order 2 elements of PSL(2, 5)
|
-- Only order 5 elements of PSL(2, 5)
|
||||||
psl25_order2 = filter ((==2) . orderPSL25) $ mPSL 2 5
|
psl25_order5 = filter ((==5) . orderPSL25) $ mPSL 2 5
|
||||||
|
|
||||||
|
markdown $ ("$$B = " ++) $ (++ "... $$") $ intercalate " ~,~ " $
|
||||||
|
take 5 $ map texifyMatrix psl25_order5
|
||||||
|
```
|
||||||
|
|
||||||
|
Arbitrarily, let's pick the last entry on this list.
|
||||||
|
Now, we can search for order-2 elements in PSL(2, 5) whose product with *B* has order 3.
|
||||||
|
This matrix (*A*) matches exactly with *a* in *A*~5~.
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
--| code-fold: true
|
||||||
|
--| code-summary: "Haskell implementation using B as a generator to find candidates for A"
|
||||||
|
|
||||||
-- Start with B as a generator
|
-- Start with B as a generator
|
||||||
psl25_gen_B = toMatrix [[0,2],[2,2]]
|
psl25_gen_B = toMatrix [[0,2],[2,2]]
|
||||||
|
|
||||||
|
-- Only order 2 elements of PSL(2, 5)
|
||||||
|
psl25_order2 = filter ((==2) . orderPSL25) $ mPSL 2 5
|
||||||
|
|
||||||
-- Find an order 2 element whose product with `psl25_gen_B` has order 3
|
-- Find an order 2 element whose product with `psl25_gen_B` has order 3
|
||||||
psl25_gen_A_candidates = filter ((==3) . orderPSL25 . (psl25_gen_B |*|)) \
|
psl25_gen_A_candidates = filter ((==3) . orderPSL25 . (psl25_gen_B |*|))
|
||||||
psl25_order2
|
psl25_order2
|
||||||
|
|
||||||
-- Candidate matrices:
|
markdown $ ("$$A = " ++) $ (++ "$$") $ intercalate " ~,~ " $
|
||||||
--
|
map texifyMatrix psl25_gen_A_candidates
|
||||||
-- [1,1]
|
|
||||||
-- [3,4]
|
|
||||||
--
|
|
||||||
-- [1,3]
|
|
||||||
-- [1,4]
|
|
||||||
--
|
|
||||||
-- [2,0]
|
|
||||||
-- [0,3]
|
|
||||||
--
|
|
||||||
-- [2,0]
|
|
||||||
-- [4,3]
|
|
||||||
--
|
|
||||||
-- [2,4]
|
|
||||||
-- [0,3]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're unsatisfied with starting from *B*, realize that we could have filtered out
|
Again, arbitrarily, we'll pick the last entry from this list.
|
||||||
only the order 5 elements of PSL(2, 5) (`filter ((==5) . psl25Order) $ mPSL 2 5`),
|
Let's also peek at what the matrix *AB* looks like.
|
||||||
and picked any element from this list to start.
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
--| code-fold: true
|
||||||
|
|
||||||
|
psl25_gen_AB = (`mod` 5) <$> (psl25_gen_A_candidates !! 4) |*| psl25_gen_B
|
||||||
|
|
||||||
|
markdown $ ("$$" ++) $ (++ "$$") $ intercalate " \\quad " [
|
||||||
|
"(AB) = " ++ texifyMatrix psl25_gen_AB,
|
||||||
|
"(AB)^3 = " ++ texifyMatrix ((`mod` 5) <$> (psl25_gen_AB^3))
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
We now have a correspondence between three elements of *A*~5~ and PSL(2, 5).
|
We now have a correspondence between three elements of *A*~5~ and PSL(2, 5).
|
||||||
We can "run" both sets of the generators until we associate all elements to one another.
|
We can "run" both sets of the generators until we associate all elements to one another.
|
||||||
This is most visually appealing to see as a Cayley graph:
|
This is most visually appealing to see as a Cayley graph:
|
||||||
|
|
||||||
|
[
|
||||||
![
|
![
|
||||||
Cayley graph showing an isomorphism between A5 and PSL(2, 5). <br>
|
Cayley graph showing an isomorphism between A5 and PSL(2, 5). <br>
|
||||||
Order-2 elements are red, order-3 elements are green, and order-5 elements are blue. <br>
|
Order-2 elements are red, order-3 elements are green, and order-5 elements are blue.
|
||||||
Purple arrows are order-5 generators, orange arrows are order-2 generators.
|
Purple arrows are order-5 generators, orange arrows are order-2 generators[^4].
|
||||||
](./a5_psl25_cayley.png)
|
](./a5_psl25_cayley.png){.narrow}
|
||||||
|
](./a5_psl24_cayley.png)
|
||||||
|
|
||||||
|
[^4]: Different generators appear to be used for *A* and *B* in the above image
|
||||||
|
due to some self-imposed turbulence when writing the original post.
|
||||||
|
Under projective equality, both are the same as our choices of *A* and *B*.
|
||||||
|
|
||||||
|
|
||||||
PSL(2, 4)
|
PSL(2, 4)
|
||||||
@ -737,7 +736,7 @@ $$
|
|||||||
|
|
||||||
Scalar multiplication by *α* multiplies the determinant by *α*^2^;
|
Scalar multiplication by *α* multiplies the determinant by *α*^2^;
|
||||||
by *α*^2^ multiplies the determinant by *α*^4^ = *α*.
|
by *α*^2^ multiplies the determinant by *α*^4^ = *α*.
|
||||||
Thus, SL(2, 4) is also PSL(2, 4), since no scalar multiple has determinant 1.
|
Thus, SL(2, 4) is also PSL(2, 4), since a scalar multiple has determinant 1.
|
||||||
|
|
||||||
Let's start by looking at an order-5 matrix over PSL(2, 4).
|
Let's start by looking at an order-5 matrix over PSL(2, 4).
|
||||||
We'll call this matrix *B*' to correspond with our order-5 generator in PSL(2, 5).
|
We'll call this matrix *B*' to correspond with our order-5 generator in PSL(2, 5).
|
||||||
@ -777,8 +776,8 @@ $$
|
|||||||
We need to be able to do three things over GL(2, 4) on a computer:
|
We need to be able to do three things over GL(2, 4) on a computer:
|
||||||
|
|
||||||
- multiply matrices over GF(4),
|
- multiply matrices over GF(4),
|
||||||
- compare those matrices,
|
- compute their determinant,
|
||||||
- compute their determinant, and
|
- visually distinguish between each of them, and
|
||||||
- be able to systematically write down all of them
|
- be able to systematically write down all of them
|
||||||
|
|
||||||
It would then follow for us to repeat what we did with with SL(2, 5).
|
It would then follow for us to repeat what we did with with SL(2, 5).
|
||||||
@ -826,7 +825,7 @@ $$
|
|||||||
f(1) & f(1) \\
|
f(1) & f(1) \\
|
||||||
f(\alpha) & f(\alpha^2)
|
f(\alpha) & f(\alpha^2)
|
||||||
\end{matrix} \right) =
|
\end{matrix} \right) =
|
||||||
f^*((\bar B')^2)
|
f^*((B')^2)
|
||||||
\end{align*}
|
\end{align*}
|
||||||
\end{gather*}
|
\end{gather*}
|
||||||
$$
|
$$
|
||||||
@ -877,14 +876,11 @@ All we need to do is find all possible 4-tuples of **0**, *I*, *C*~*p*~, and *C*
|
|||||||
then arrange each into a 2x2 matrix.
|
then arrange each into a 2x2 matrix.
|
||||||
Multiplication follows from the typical definition and the multiplicative identity is just *f*\*(*I*).
|
Multiplication follows from the typical definition and the multiplicative identity is just *f*\*(*I*).
|
||||||
|
|
||||||
|
```{haskell}
|
||||||
|
--| code-fold: true
|
||||||
|
--| code-summary: "Haskell implementation of PSL(2, 4)"
|
||||||
|
|
||||||
<details>
|
import Data.List (elemIndex)
|
||||||
<summary>
|
|
||||||
Haskell implementation of PSL(2, 4)
|
|
||||||
</summary>
|
|
||||||
|
|
||||||
```{.haskell}
|
|
||||||
import Data.List (findIndex)
|
|
||||||
|
|
||||||
-- Matrices which obey the same relations as the elements of GF(4)
|
-- Matrices which obey the same relations as the elements of GF(4)
|
||||||
zero_f4 = zero 2
|
zero_f4 = zero 2
|
||||||
@ -896,7 +892,7 @@ alpha2_f4 = toMatrix [[1,1],[1,0]]
|
|||||||
field4 = [zero_f4, one_f4, alpha_f4, alpha2_f4]
|
field4 = [zero_f4, one_f4, alpha_f4, alpha2_f4]
|
||||||
|
|
||||||
-- Convenient show function for these matrices
|
-- Convenient show function for these matrices
|
||||||
showF4 x = case findIndex (==x) field4 of
|
showF4 x = case elemIndex x field4 of
|
||||||
Just 0 -> "0"
|
Just 0 -> "0"
|
||||||
Just 1 -> "1"
|
Just 1 -> "1"
|
||||||
Just 2 -> "α"
|
Just 2 -> "α"
|
||||||
@ -909,101 +905,59 @@ psl_24_identity = toMatrix [[one_f4, zero_f4], [zero_f4, one_f4]]
|
|||||||
-- All possible matrices over GF(4)
|
-- All possible matrices over GF(4)
|
||||||
-- Create a list of 4-lists of elements from GF(4), then
|
-- Create a list of 4-lists of elements from GF(4), then
|
||||||
-- Shape them into 2x2 matrices
|
-- Shape them into 2x2 matrices
|
||||||
f4_matrices = map (toMatrix . reshape 2) $ sequence $ replicate 4 field4
|
f4_matrices = map (toMatrix . reshape 2) $ replicateM 4 field4
|
||||||
|
|
||||||
-- Sieve out those which have a determinant of 1 in the field
|
-- Sieve out those which have a determinant of 1 in the field
|
||||||
mPSL24 = filter ((==one_f4) . (fmap (`mod` 2)) . laplaceDet) $ f4_matrices
|
mPSL24 = filter ((==one_f4) . fmap (`mod` 2) . laplaceDet) f4_matrices
|
||||||
```
|
```
|
||||||
</details>
|
|
||||||
|
|
||||||
Now that we can generate the group, we can finally repeat what we did with PSL(2, 5).
|
Now that we can generate the group, we can finally repeat what we did with PSL(2, 5).
|
||||||
All we have to do is filter out order-2 elements, then further filter
|
All we have to do is filter out order-2 elements, then further filter
|
||||||
for those which have an order-3 product with *B*'.
|
for those which have an order-3 product with *B*'.
|
||||||
|
|
||||||
<details>
|
```{haskell}
|
||||||
<summary>
|
--| code-fold: true
|
||||||
Haskell implementation using *B*' as a generator to find candidates for *A*'
|
--| code-summary: "Haskell implementation using *B*' as a generator to find candidates for *A*'"
|
||||||
</summary>
|
|
||||||
|
|
||||||
```{.haskell}
|
|
||||||
-- Order with respect to PSL(2, 4): using matrix multiplication (mod 2)
|
-- Order with respect to PSL(2, 4): using matrix multiplication (mod 2)
|
||||||
-- and projective equality to the identity matrix
|
-- and projective equality to the identity matrix
|
||||||
orderPSL24 = orderWith (\x -> fmap (fmap (`mod` 2)) . (x*))) (== psl_24_identity)
|
orderPSL24 = orderWith (\x -> fmap (fmap (`mod` 2)) . (x*)) (== psl_24_identity)
|
||||||
|
|
||||||
-- Only order 2 elements of PSL(2, 4)
|
-- Only order 2 elements of PSL(2, 4)
|
||||||
psl24_order2 = filter ((==2) . orderPSL24) $ mPSL24
|
psl24_order2 = filter ((==2) . orderPSL24) mPSL24
|
||||||
|
|
||||||
-- Start with B as a generator
|
-- Start with B as a generator
|
||||||
psl24_gen_B = toMatrix [[zero_f4, alpha_f4], [alpha2_f4, alpha2_f4]]
|
psl24_gen_B = toMatrix [[zero_f4, alpha_f4], [alpha2_f4, alpha2_f4]]
|
||||||
|
|
||||||
-- Find an order 2 element whose product with `psl24_gen_B` has order 3
|
-- Find an order 2 element whose product with `psl24_gen_B` has order 3
|
||||||
psl24_gen_A_candidates = filter ((==3) . orderPSL24 . (psl24_gen_B*))
|
psl24_gen_A_candidates = filter ((==3) . orderPSL24 . (psl24_gen_B |*|))
|
||||||
psl24_order2
|
psl24_order2
|
||||||
|
|
||||||
-- Candidate matrices:
|
markdown $ ("$$ A' = " ++) $ (++ "$$") $ intercalate " ~,~ " $
|
||||||
--
|
map (texifyMatrix' showF4) psl24_gen_A_candidates
|
||||||
-- ["0","1"]
|
|
||||||
-- ["1","0"]
|
|
||||||
--
|
|
||||||
-- ["0","α^2"]
|
|
||||||
-- ["α","0"]
|
|
||||||
--
|
|
||||||
-- ["1","0"]
|
|
||||||
-- ["1","1"]
|
|
||||||
--
|
|
||||||
-- ["1","α^2"]
|
|
||||||
-- ["0","1"]
|
|
||||||
--
|
|
||||||
-- ["α","1"]
|
|
||||||
-- ["α","α"]
|
|
||||||
```
|
```
|
||||||
</details>
|
|
||||||
|
|
||||||
Finally, we can decide on an *A*', the order-2 generator with the properties we wanted.
|
We'll pick the second entry as our choice of *A*'.
|
||||||
|
We note that the product *A'B'*, does indeed have order 3.
|
||||||
|
|
||||||
$$
|
```{haskell}
|
||||||
\begin{array}{}
|
--| code-fold: true
|
||||||
\begin{gather*}
|
|
||||||
A' = \left(\begin{matrix}
|
|
||||||
0 & \alpha^2 \\
|
|
||||||
\alpha & 0
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
(A')^2 = \left(\begin{matrix}
|
|
||||||
1 & 0 \\
|
|
||||||
0 & 1
|
|
||||||
\end{matrix}\right)
|
|
||||||
\end{gather*}
|
|
||||||
\\ \\ \hline \\
|
|
||||||
\begin{gather*}
|
|
||||||
A'B' =
|
|
||||||
\left(\begin{matrix}
|
|
||||||
\alpha & \alpha \\
|
|
||||||
0 & \alpha^2
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
(A'B')^2 =
|
|
||||||
\left(\begin{matrix}
|
|
||||||
\alpha^2 & \alpha \\
|
|
||||||
0 & \alpha
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
(A'B')^3 =
|
|
||||||
\left(\begin{matrix}
|
|
||||||
1 & 0 \\
|
|
||||||
0 & 1
|
|
||||||
\end{matrix} \right)
|
|
||||||
\qquad
|
|
||||||
\end{gather*}
|
|
||||||
\end{array}
|
|
||||||
$$
|
|
||||||
|
|
||||||
Then, we can arrange them on a Cayley graph in the same way as PSL(2, 5):
|
psl24_gen_AB = fmap (`mod` 2) <$> (psl24_gen_A_candidates !! 1) |*| psl24_gen_B
|
||||||
|
|
||||||
|
markdown $ ("$$" ++) $ (++ "$$") $ intercalate " \\quad " [
|
||||||
|
"(A'B') = " ++ texifyMatrix' showF4 psl24_gen_AB,
|
||||||
|
"(A'B')^3 = " ++ texifyMatrix' showF4 (fmap (`mod` 2) <$> (psl24_gen_AB^3))
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we can arrange these matrices on a Cayley graph in the same way as PSL(2, 5):
|
||||||
|
|
||||||
|
[
|
||||||
{.narrow}
|
||||||
](./a5_psl24_cayley.png)
|
](./a5_psl24_cayley.png)
|
||||||
|
|
||||||
|
|
||||||
@ -1011,16 +965,20 @@ Closing
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
This post addresses my original goal in implementing finite fields,
|
This post addresses my original goal in implementing finite fields,
|
||||||
namely computationally finding an explicit map between *A*^5^ and PSL(2, 4).
|
namely computationally finding an explicit map between *A*~5~ and PSL(2, 4).
|
||||||
I believe the results are a little more satisfying than attempting to wrap your head
|
I believe the results are a little more satisfying than attempting to wrap your head
|
||||||
around group-theoretic proofs.
|
around group-theoretic proofs.
|
||||||
That's not to discount the power and astounding amount of work that goes into the latter method.
|
That's not to discount the power and incredible logic that goes into the latter method.
|
||||||
It does tend to leave things rather opaque, however.
|
It does tend to leave things rather opaque, however.
|
||||||
|
|
||||||
If you'd prefer a more interactive diagram showing the above isomorphisms,
|
If you'd prefer a more interactive diagram showing the above isomorphisms,
|
||||||
I've gone to the liberty of creating a hoverable SVG:
|
I've gone to the liberty of creating a hoverable SVG:
|
||||||
|
|
||||||

|
[
|
||||||
|
{.narrow}
|
||||||
|
](./a5_psl24_psl25_isomorphism.svg)
|
||||||
|
|
||||||
This post slightly diverts our course from the previous one's focus on fields.
|
This post slightly diverts our course from the previous one's focus on fields.
|
||||||
The [next one](../4) will focus on more results regarding the treatment of layered matrices.
|
The [next one](../4) will focus on more results regarding the treatment of layered matrices.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user