Groups, Algorithms, Programming
www.gap-system.org
GAP website: www.gap-system.org
Original Document: http://www-circa.mcs.st-and.ac.uk/gapfinite0.php
http://www.math.colostate.edu/~hulpke
GAP knows that there is a unique finite field up to isomorphism of order $n=p^k$ for each prime $p$ and positive integer $k$. It calls it $GF(n)$. (This stands for Galois Field.)
GAP also knows that the multiplicative group of such a finite field is cyclic and it chooses a generator for this cyclic group which it calls $Z(n)$. It then refers to the elements of the field as $\{0*Z(n), Z(n)^0, Z(n)^1,\ldots,Z(n)^{n-2}\}$. Note that $Z(n)^{n-1}=Z(n)^0$ is the multiplicative identity.
GAP supports all finite fields of order less than or equal to $2^{16}$ (= about 65536). Hence $GF(3^{10})$, $GF(5^6)$, $GF(7^5)$, etc. and smaller fields are supported. All prime fields are supported, so $GF(p)$ is supported even when $p>2^{16}$.
We can illustrate how this works with $GF(11)$.
To create this field and name it $F$ we use the command
F:= GF( 11 );
GF(11)
One often calculates with the elements of this field as if they were integers { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } but GAP distinguishes between elements of $GF(11)$ and integers. For example 0 is not an element of $GF(11)$, so we get false if we test this
0 in F;
false
In fact none of the integers { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } are elements of $F$.
The zero of $F$ is given as follows
z:= Zero( F );
0*Z(11)
z in F;
true
and the multiplicative identity is
one:= One( F );
Z(11)^0
one in F;
true
We could denote the zero element by $0\times\text{One}(F)$.
0*one in F;
true
Now we have the elements of $F$ by multiplying the integers { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } each by $\text{One}(F)$
for i in [0..10] do Print(i*one, ": is it in GF(11) ? ", i*one in F, "\n"); od;
0*Z(11): is it in GF(11) ? true Z(11)^0: is it in GF(11) ? true Z(11): is it in GF(11) ? true Z(11)^8: is it in GF(11) ? true Z(11)^2: is it in GF(11) ? true Z(11)^4: is it in GF(11) ? true Z(11)^9: is it in GF(11) ? true Z(11)^7: is it in GF(11) ? true Z(11)^3: is it in GF(11) ? true Z(11)^6: is it in GF(11) ? true Z(11)^5: is it in GF(11) ? true
GAP chooses a generating element of the (cyclic) multiplicative group of the field as $Z(11)$ and displays the elements as 0*Z(11), Z(11)^0, Z(11)^1, Z(11)^2, ... , Z(11)^9
. In fact, for $GF(11)$ the element "2" is denoted by Z(11)^1
or by Z(11)
. We could easily find this out
for i in [0..10] do if (i*one = Z(11)) then Print(i, "\n"); fi; od;
2
There is, however, a better way to convert elements of $GF(11)$ written in GAP notation back to 0, 1, 2, ... using IntFFE
(which stands for Integer form of a Finite Field Element).
IntFFE(Z(11));
2
In general we can convert all the elements of $GF(11)$ back to corresponding integers since 11 is prime.
for i in [0..10] do Print(i*one," is ", IntFFE(i*one), "\n"); od;
0*Z(11) is 0 Z(11)^0 is 1 Z(11) is 2 Z(11)^8 is 3 Z(11)^2 is 4 Z(11)^4 is 5 Z(11)^9 is 6 Z(11)^7 is 7 Z(11)^3 is 8 Z(11)^6 is 9 Z(11)^5 is 10
We can now do calculations in $F$ as follows. All the following calculate the multiplicative inverse of Z(11), which is the same as the multiplicative inverse of "2".
Inverse( Z(11) );
Z(11)^9
2^(-1)*one;
Z(11)^9
Z( 11 )^(-1);
Z(11)^9
Inverse( 2*one );
Z(11)^9
We can add elements of $F$
Z(11)+Z(11)^2;
Z(11)^9
A moment's thought shows that this is right: 2 + 4 = 6 is the inverse of 2 in $GF(11)$.
Again as above, several different commands will give us the additive inverse (i.e. negative) of Z(11).
AdditiveInverse( Z(11) );
Z(11)^6
-2*one;
Z(11)^6
-Z(11);
Z(11)^6
AdditiveInverse(2*one);
Z(11)^6
Now the non-zero elements of $F$ have multiplicative orders which can be calculated as follows
Order( Z(11) );#
$2^{10}\equiv 1(\text{mod}\ 11)$
10
or for all the elements
for i in [1..10] do Print(i," order ", Order(i*one), "\n"); od;
1 order 1 2 order 10 3 order 5 4 order 5 5 order 5 6 order 10 7 order 10 8 order 10 9 order 5 10 order 2
We can see that there are four generators of the multiplicative group of $GF(11)$.
We begin by setting up our field $GF(3)$.
F:= GF( 3 );
GF(3)
one:= One( F );
Z(3)^0
We need an indeterminate in order to look at polynomials over $GF(3)$. We'll use x.
x:= Indeterminate(F,"x");
x
We now set up an empty list and add irreducible polynomials (ones which cannot be written as a product of polynomials of lower degree) to the list. We examine all polynomials of degree up to 4, finding whether they are irreducible and if so add them to the list. GAP does not give any out here.
list:= []; for i in F do for j in F do for k in F do for l in F do for m in F do if IsIrreducibleRingElement(i*x^4+j*x^3+k*x^2+l*x+m) then Add(list, i*x^4+j*x^3+k*x^2+l*x+m); fi; od; od; od; od; od;
To see how many irreducible polynomials there are of degree up to 4 over $GF(3)$ we need only look now at the length of our list.
Length(list);
64
There are 64 of them.
Suppose we want to find how many polynomials of degree up to 4 over $GF(3)$ have one factor, how many have two factors, etc.
list:= [ [],[],[],[] ]; for i in F do for j in F do for k in F do for l in F do for m in F do num:= Length(Factors(i*x^4+j*x^3+k*x^2+l*x+m)); Add(list[num], i*x^4+j*x^3+k*x^2+l*x+m); od; od; od; od; od;
Let us see how many there are of each length
for i in [1..4] do Print("There are ", Length(list[i]), " polynomials with ", i," factors", "\n"); od;
There are 67 polynomials with 1 factors There are 90 polynomials with 2 factors There are 56 polynomials with 3 factors There are 30 polynomials with 4 factors
Notice there were 64 irreducible polynomials but 67 polynomials with a single factor. This is because 0, 1, -1 are polynomials with a single factor but are not irreducible.
The total should be $3^5$ - let us check
Sum(List([1..4], i -> Length(list[i])));
243
We input the field of 4 elements
F:= GF( 4 );
GF(2^2)
one:= One(GF( 4 ));
Z(2)^0
Let us see how GAP represents its elements
Elements( F );
[ 0*Z(2), Z(2)^0, Z(2^2), Z(2^2)^2 ]
Elements of $GF(4)$ are roots of polynomials over $GF(2)$ and so of course not all the elements of $GF(4)$ have representations as integers. We can only apply IntFFE
to the elements of the prime field of $GF(4)$ to get representations of them as integers.
IntFFE(one);
1
Applying IntFFE
to elements not in the prime field produces an error.
IntFFE(Z( 4 ));
IntFFE: <z> must lie in prime field not in any function Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can replace <z> via 'return <z>;' to continue
Now the prime field of F should be $GF(2)$
PrimeField( F );
GF(2)
and F should have degree 2 over its prime subfield
DegreeOverPrimeField( F );
2
F must be defined by an irreducible polynomial over its prime subfield. Let us find the one that GAP is using. Note that GAP calls the indeterminate $x_1$.
DefiningPolynomial( F );
Z(2)^0+x_1+x_1^2
To convince ourselves that it is irreducible, look at its irreducible factors.
Factors(DefiningPolynomial( F ));
[ Z(2)^0+x_1+x_1^2 ]
The generator of F
, which will be Z(4), should be a root of the defining polynomial
RootOfDefiningPolynomial( F );
Z(2^2)
Now we check that Z(4) is a root of 1 + x + x2
one + Z(4) + Z(4)^2;
0*Z(2)
We examine exactly the same features of GF( $2^4$ ) as for GF( 4 )
F:= GF( 2^4 );
GF(2^4)
one:= One(GF( 2^4 ));
Z(2)^0
Elements( F );
[ 0*Z(2), Z(2)^0, Z(2^2), Z(2^2)^2, Z(2^4), Z(2^4)^2, Z(2^4)^3, Z(2^4)^4, Z(2^4)^6, Z(2^4)^7, Z(2^4)^8, Z(2^4)^9, Z(2^4)^11, Z(2^4)^12, Z(2^4)^13, Z(2^4)^14 ]
Now the prime field of $F$ should be $GF(2)$ and $F$ should have degree 4 over $GF(2)$
PrimeField( F );
GF(2)
DegreeOverPrimeField( F );
4
The defining polynomial in this case is
DefiningPolynomial( F );
Z(2)^0+x_1+x_1^4
which, of course, is irreducible
Factors(DefiningPolynomial( F ));
[ Z(2)^0+x_1+x_1^4 ]
Its root will be Z(24)
RootOfDefiningPolynomial( F );
Z(2^4)
and of course Z(24) satisfies this irreducible polynomial
one + Z(2^4) + Z(2^4)^4;
0*Z(2)
But there are other irreducible polynomials of degree 4 over $GF(2)$ that we could use to define a field with 16 elements. Let us use $1+x^3+x^4$.
x:= Indeterminate(GF(2), "x");
x
FF:= GF( 2, 1 + x^3 + x^4 );
GF(2^4)
Now the defining polynomial will be $1+x^3+x^4$ because we have defined it to be this.
DefiningPolynomial( FF );
Z(2)^0+x^3+x^4
The root of the defining polynomial will not now be Z(24) of course. What is it?
RootOfDefiningPolynomial( FF );
Z(2^4)^7
The elements of FF are in fact the same 16 elements that GAP has defined in its version of GF(24).
FF=F;
true
Note the following important fact relating to finite fields.
$GF(p^n)$ is actually a subset of $GF(p^{2n})$. So
IsSubsetSet(Elements(GF( 16 )), Elements(GF( 4 )));
true
will return "true". Of course $GF(4)$ is not contained in $GF(8)$ so
IsSubsetSet(Elements(GF( 8 )), Elements(GF( 4 )));
will return "false".
false
Suppose we wanted to define $GF(2^n)$ by means of a trinomial over $GF(2)$. To do this requires there to be an irreducible polynomial of the form $1+x^i+x^n$ over $GF(2)$ for every $n$. Let us test whether this looks likely. First set up a polynomial ring over $GF(2)$.
F:= GF( 2 );; R:= PolynomialRing(F, 1);; # GF(2)[x_1] indets:= IndeterminatesOfPolynomialRing(R);; # [ x_1 ] x:= indets[1];; # x_1 one:= One(R);; # Z(2)^0 for n in [2..20] do for i in [1..n-1] do p:= x^n + x^i + one; if IsIrreducibleRingElement(p) then Print("Degree ", n, " has irreducible ", p, "\n"); break; fi; od; od;
Degree 2 has irreducible Z(2)^0+x+x^2 Degree 3 has irreducible Z(2)^0+x+x^3 Degree 4 has irreducible Z(2)^0+x+x^4 Degree 5 has irreducible Z(2)^0+x^2+x^5 Degree 6 has irreducible Z(2)^0+x+x^6 Degree 7 has irreducible Z(2)^0+x+x^7 Degree 9 has irreducible Z(2)^0+x+x^9 Degree 10 has irreducible Z(2)^0+x^3+x^10 Degree 11 has irreducible Z(2)^0+x^2+x^11 Degree 12 has irreducible Z(2)^0+x^3+x^12 Degree 14 has irreducible Z(2)^0+x^5+x^14 Degree 15 has irreducible Z(2)^0+x+x^15 Degree 17 has irreducible Z(2)^0+x^3+x^17 Degree 18 has irreducible Z(2)^0+x^3+x^18 Degree 20 has irreducible Z(2)^0+x^3+x^20
In my computer, the result is
Degree 2 has irreducible x_1^2+x_1+Z(2)^0 Degree 3 has irreducible x_1^3+x_1+Z(2)^0 Degree 4 has irreducible x_1^4+x_1+Z(2)^0 Degree 5 has irreducible x_1^5+x_1^2+Z(2)^0 Degree 6 has irreducible x_1^6+x_1+Z(2)^0 Degree 7 has irreducible x_1^7+x_1+Z(2)^0 Degree 9 has irreducible x_1^9+x_1+Z(2)^0 Degree 10 has irreducible x_1^10+x_1^3+Z(2)^0 Degree 11 has irreducible x_1^11+x_1^2+Z(2)^0 Degree 12 has irreducible x_1^12+x_1^3+Z(2)^0 Degree 14 has irreducible x_1^14+x_1^5+Z(2)^0 Degree 15 has irreducible x_1^15+x_1+Z(2)^0 Degree 17 has irreducible x_1^17+x_1^3+Z(2)^0 Degree 18 has irreducible x_1^18+x_1^3+Z(2)^0 Degree 20 has irreducible x_1^20+x_1^3+Z(2)^0
We see that there is no such polynomial for degree 8, 13, 16, 19, ...
Perhaps we should print out the numbers for which there is no irreducible trinomial. We will use the fact that
if $1+x^i+x^n$ is irreducible then so is $1+x^{(n-i)}+x^n$.
So, for $n>2$, we will never find that the first irreducible we reach is beyond $1+x^m+x^n$ where $m=\text{Int}(n/2)$, the integer part of $n/2$. This observation speeds up the calculation.
for n in [3..50] do for i in [1..Int(n/2)+1] do p:= x^n + x^i + one; if IsIrreducibleRingElement(p) then break; fi; od; if (i = Int(n/2+1)) then Print("Degree ", n, " has no irreducible trinomial", "\n"); fi; od;
Degree 8 has no irreducible trinomial Degree 13 has no irreducible trinomial Degree 16 has no irreducible trinomial Degree 19 has no irreducible trinomial Degree 24 has no irreducible trinomial Degree 26 has no irreducible trinomial Degree 27 has no irreducible trinomial Degree 32 has no irreducible trinomial Degree 37 has no irreducible trinomial Degree 38 has no irreducible trinomial Degree 40 has no irreducible trinomial Degree 43 has no irreducible trinomial Degree 45 has no irreducible trinomial Degree 48 has no irreducible trinomial Degree 50 has no irreducible trinomial
We have used a break;
statement which makes GAP jump out of its loop. If there are several loops inside one another, it will just jump out of the innermost one.
It seems as if there is no irreducible trinomial for $n$ a multiple of 8. Is this true? Perhaps we should look for more evidence
for n in 8*[1..20] do for i in [1..Int(n/2)] do p:= x^n + x^i + one; if IsIrreducibleRingElement(p) then break; fi; od; if (i = Int(n/2)) then Print("Degree ", n, " has no irreducible trinomial", "\n"); fi; od;
Degree 8 has no irreducible trinomial Degree 16 has no irreducible trinomial Degree 24 has no irreducible trinomial Degree 32 has no irreducible trinomial Degree 40 has no irreducible trinomial Degree 48 has no irreducible trinomial Degree 56 has no irreducible trinomial Degree 64 has no irreducible trinomial Degree 72 has no irreducible trinomial Degree 80 has no irreducible trinomial Degree 88 has no irreducible trinomial Degree 96 has no irreducible trinomial Degree 104 has no irreducible trinomial Degree 112 has no irreducible trinomial Degree 120 has no irreducible trinomial Degree 128 has no irreducible trinomial Degree 136 has no irreducible trinomial Degree 144 has no irreducible trinomial Degree 152 has no irreducible trinomial Degree 160 has no irreducible trinomial
So these multiples of 8 all have no irreducible trinomial. Must be worth trying to prove a theorem.
Can you spot any other likely theorems?