In this section we will show you some basic computations with fields. GAP supports at present the following fields. The rationals, cyclotomic extensions of rationals and their subfields (which we will refer to as number fields in the following), and finite fields.
Let us first take a look at the infinite fields mentioned above. While
the set of rational numbers is a predefined domain in GAP to which you
may refer by its identifier Rationals
, cyclotomic fields are
constructed by using the function CyclotomicField
, which may be
abbreviated as CF
.
gap> IsField( Rationals ); true gap> Size( Rationals ); "infinity" gap> f := CyclotomicField( 8 ); CF(8) gap> IsSubset( f, Rationals ); true
The integer argument n
of the function call to CF
specifies that the
cyclotomic field containing all n-th roots of unity should be returned.
Cyclotomic fields are constructed as extensions of the Rationals by
primitive roots of unity. Thus a primitive n-th root of unity is always
an element of CF(n), where n is a natural number. In GAP, one may
construct a primitive n-th root of unity by calling E(n)
.
gap> (E(8) + E(8)^3)^2; -2 gap> E(8) in f; true
For every field extension you can compute the Galois group, i.e., the group of automorphisms that leave the subfield fixed. For an example, cyclotomic fields are an extension of the rationals, so you can compute their Galois group over the rationals.
gap> Galf := GaloisGroup( f ); Group( NFAutomorphism( CF(8) , 7 ), NFAutomorphism( CF(8) , 5 ) ) gap> Size( Galf ); 4
The above cyclotomic field is a small example where the Galois group is not cyclic.
gap> IsCyclic( Galf ); false gap> IsAbelian( Galf ); true gap> AbelianInvariants( Galf ); [ 2, 2 ]
This shows us that the 8th cyclotomic field has a Galois group which is isomorphic to group V_4.
The elements of the Galois group are GAP automorphisms, so they may be applied to the elements of the field in the same way as all mappings are usually applied to objects in GAP.
gap> g := Galf.generators[1]; NFAutomorphism( CF(8) , 7 ) gap> E(8) ^ g; -E(8)^3
There are two functions, Norm
and Trace
, which compute the norm and
the trace of elements of the field, respectively. The norm and the trace
of an element a are defined to be the product and the sum of the images
of a under the Galois group. You should usually specify the field as a
first argument. This argument is however optional. If you omit a
default field will be used. For a cyclotomic a this is the smallest
cyclotomic field that contains a (note that this is not the smallest
field that contains a, which may be a number field that is not a
cyclotomic field).
gap> orb := List( Elements( Galf ), x -> E(8) ^ x ); [ E(8), E(8)^3, -E(8), -E(8)^3 ] gap> Sum( orb ) = Trace( f, E(8) ); true gap> Product( orb ) = Norm( f, E(8) ); true gap> Trace( f, 1 ); 4
The basic way to construct a finite field is to use the function
GaloisField
which may be abbreviated, as usual in algebra, as GF
.
Thus
gap> k := GF( 3, 4 ); GF(3^4)
or
gap> k := GaloisField( 81 ); GF(3^4)
will assign the finite field of order 3^4 to the variable k
.
In fact, what GF
does is to set up a record which contains all
necessary information, telling that it represents a finite field of
degree 4 over its prime field with 3 elements. Of course, all arguments
to GF
others than those which represent a prime power are rejected --
for obvious reasons.
Some of the more important entries of the field record are zero
, one
and root
, which hold the corresponding elements of the field. All
elements of a finite field are represented as a certain power of an
appropriate primitive root, which is written as Z(q)
. As can be seen
below the smallest possible primitive root is used.
gap> k.one + k.root + k.root^10 - k.zero; Z(3^4)^52 gap> k.root; Z(3^4) gap> k.root ^ 20; Z(3^2)^2 gap> k.one; Z(3)^0
Note that of course elements from fields of different characteristic cannot be combined in operations.
gap> Z(3^2) * k.root + k.zero + Z(3^8); Z(3^8)^6534 gap> Z(2) * k.one; Error, Finite field *: operands must have the same characteristic
In this example we tried to multiply a primitive root of the field with
two elements with the identity element of the field k
. As the
characteristic of k
equals 3, there is no way to perform the
multiplication. The first statement of the example shows, that if all
the elements of the expression belong to fields of the same
characteristic, the result will be computed.
As soon as a primitive root is demanded, GAP internally sets up all relevant data structures that are necessary to compute in the corresponding finite field. Each finite field is constructed as a splitting field of a Conway polynomial. These polynomials, as a set, have special properties that make it easy to embed smaller fields in larger ones and to convert the representation of the elements when doing so. All Conway polynomials for fields up to an order of 65536 have been computed and installed in the GAP kernel.
But now look at the following example.
gap> Z(3^3) * Z(3^4); Error, Finite field *: smallest common superfield to large
Although both factors are elements of fields of characteristic 3, the product can not be evaluated by GAP. The reason for this is very easy to explain: In order to compute the product, GAP has to find a field in which both of the factors lie. Here in our example the smallest field containing Z(3^3) and Z(3^4) is GF(3^{12}), the field with 531441 elements. As we have mentioned above that the size of finite fields in GAP is limited at present by 65536 we now see that there is no chance to set up the internal data structures for the common field to perform the computation.
As before with cyclotomic fields, the Galois group of a finite field and the norm and trace of its elements may be computed. The calling conventions are the same as for cyclotomic fields.
gap> Galk := GaloisGroup( k ); Group( FrobeniusAutomorphism( GF(3^4) ) ) gap> Size( Galk ); 4 gap> IsCyclic( Galk ); true gap> Norm( k, k.root ^ 20 ); Z(3)^0 gap> Trace( k, k.root ^ 20 ); 0*Z(3)
So far, in our examples, we were always interested in the Galois group of
a field extension k over its prime field. In fact it often will occur
that, given a subfield l of k the Galois group of k over l is
desired. In GAP it is possible to change the structure of a field by
using the /
operator. So typing
gap> l := GF(3^2); GF(3^2) gap> IsSubset( k, l ); true gap> k / l; GF(3^4)/GF(3^2)
changes the representation of k from a field extension of degree 4 over GF(3) to a field given as an extension of degree 2 over GF(3^2). The actual elements of the fields are still the same, only the structure of the field has changed.
gap> k = k / l; true gap> Galkl := GaloisGroup( k / l ); Group( FrobeniusAutomorphism( GF(3^4)/GF(3^2) )^2 ) gap> Size( Galkl ); 2
Of course, all the relevant functions behave in a different way when they
refer to k / l
instead of k
gap> Norm( k / l, k.root ^ 20 ); Z(3) gap> Trace( k / l, k.root ^ 20 ); Z(3^2)^6
This feature, to change the structure of the field without changing the underlying set of elements, is also available for cyclotomic fields, which we have seen at the beginning of this chapter.
gap> g := CyclotomicField( 4 ); GaussianRationals gap> IsSubset( f, g ); true gap> f / g; CF(8)/GaussianRationals gap> Galfg := GaloisGroup( f / g ); Group( NFAutomorphism( CF(8)/GaussianRationals , 5 ) ) gap> Size( Galfg ); 2
The examples should have shown that, although the structure of finite fields and cyclotomic fields is rather different, there is a similar interface to them in GAP, which makes it easy to write programs that deal with both types of fields in the same way.
GAP 3.4.4