# MAGMA Commands for Galois Theory calculations

Perhaps this is walking over old ground (or the wrong place to ask this), but I'm looking to use MAGMA to perform certain calculations in Galois Thoery. The motivation of this question is to create an archive of 'useful' MAGMA commands for anyone looking to solve (elementary) problems in Galois Theory.

I'm using the following calculator available online: http://magma.maths.usyd.edu.au/calc/

I have in mind the following (non-exhuastive) commands:

1. Factorisation of a given polynomial over a given field

i.e. a template with inputs: polynomial (defined in $\mathbb{Z}[x]$ for these purposes) and whichever field we are working in. The output should be the irreducible factors of the input polynomial over the field.

2. Explicit Calculation of a Splitting Field

So here a template with inputs: polynomial and field over which we want to split it with output: the splitting field

3. Explicit Calculation of a Galois Group for a given polynomial Input: polynomial, base field Output: Galois group

4. Finding the roots of a given polynomial Input: polynomial, base field Output: Roots (and potentially the splitting field)

5. Correspondence Results e.g. lattice of subfields of splitting field and subgroups of Galois group Input: polynomial, base field Output: splitting field, intermediate subfields, Galois group, subgroups (and some way of identifying which subgroups correspond to which fixed subfields under the Galois correspondence)

So this question has an example of 3, but it would be useful to have everything in one place.

There's a sense in which you are trying to do things in a non-Magma way, and that may cause you difficulties. In each case you are separating out the polynomial from the field of interest. In Magma, one would generally first define the polynomial over that field and then apply the obvious function. For instance, I'll start with a couple of polynomials and work through some of those examples. Note that the lines beginning with ">" represent input (the ">" is Magma's prompt) and the others show Magma output from the previous command.

> Qx<x> := PolynomialRing(Rationals());
> Ky<y> := PolynomialRing(GF(11));
> f := x^3 + x + 1;
> g := y^3 + y + 1;


It may be tempting to think of f and g as the "same" polynomial, but that is not the case; f is defined over the rational field (and operations on f will use this field when necessary), while g is defined over the finite field with 11 elements (and operations on g will be in this context).

1. Factorization

> Factorization(f);
[
<x^3 + x + 1, 1>
]
> Factorization(g);
[
<y + 9, 1>,
<y^2 + 2*y + 5, 1>
]


The result of factorizing is a sequence of tuples. As you can see, there was no need to specify the ring of interest for the factorisation since that was deduced from the polynomial's ring of definition.

2. Splitting Field

> SplittingField(f);
Number Field with defining polynomial x^6 + 6*x^4 + 9*x^2 + 31 over the
Rational Field
> SplittingField(g);
Finite field of size 11^2


(Actually, I have elided some output here -- in the former case, there is a second return value, which is a sequence of the roots of f lifted into the splitting field.)

3. Galois Group

> GaloisGroup(f);
Symmetric group acting on a set of cardinality 3
Order = 6 = 2 * 3


(Again, I have elided some output, which consists of p-adic approximations to the roots and some associated Galois data used by the algorithm.)

4. Roots

> Roots(f);
[]
> Roots(g);
[ <2, 1> ]


5. Correspondences

I'm afraid that fully answering the above exceeds my "off the top of my head" knowledge. But certainly the subfield lattice is computable.

> L := SplittingField(f);
> Subfields(L);
[
<Number Field with defining polynomial x^6 + 6*x^4 + 9*x^2 + 31 over the
Rational Field, Mapping from: FldNum: L to FldNum: L>,
<Number Field with defining polynomial x^2 + 31 over the Rational Field,
Mapping from: Number Field with defining polynomial x^2 + 31 over the
Rational Field to FldNum: L>,
<Number Field with defining polynomial x^3 + 3*x^2 - 31 over the Rational
Field, Mapping from: Number Field with defining polynomial x^3 + 3*x^2 - 31
over the Rational Field to FldNum: L>,
<Number Field with defining polynomial x^3 + 3*x^2 - 31 over the Rational
Field, Mapping from: Number Field with defining polynomial x^3 + 3*x^2 - 31
over the Rational Field to FldNum: L>,
<Number Field with defining polynomial x^3 - 6*x^2 + 9*x - 31 over the
Rational Field, Mapping from: Number Field with defining polynomial x^3 -
6*x^2 + 9*x - 31 over the Rational Field to FldNum: L>
]
> A := SubfieldLattice(L);
> A;
Subfield Lattice of L
[1] Rational Field
[2] Subfield generated by a root of x^2 + 31
[3] Subfield generated by a root of x^3 + 3*x^2 - 31
[4] Subfield generated by a root of x^3 + 3*x^2 - 31
[5] Subfield generated by a root of x^3 - 6*x^2 + 9*x - 31
[6] Subfield generated by a root of x^6 + 6*x^4 + 9*x^2 + 31

> MaximalSubfields(A[6]);
[ 2, 3, 4, 5 ]
> MinimalOverfields(A[1]);
[ 2, 3, 4, 5 ]


So the lattice can be seen to be fairly simple in this case.

Now, in order to answer your question as written, we would also need to be able to convert a polynomial from one ring to another. That is easy enough in a few ways, using various of Magma's coercion tools. One way is to evaluate the polynomial at the transcendental from an appropriate polynomial ring, but this does not always work if the two rings are not sensibly related. For instance, there's no sensible overstructure for Q and F11, so this fails:

> Evaluate(f, y);

>> Evaluate(f, y);
^
Runtime error in 'Evaluate': Arguments have incompatible coefficient rings


But if we wanted to lift f to a polynomial over its splitting field, that could work:

> L := SplittingField(f);
> P<t> := PolynomialRing(L);
> Evaluate(f, t);
t^3 + t + 1


Another option is to use ChangeRing, which sometimes works in cases where Evaluate would not:

> ChangeRing(f, GF(11));
y^3 + y + 1
> ChangeRing(f, L);
t^3 + t + 1


However, if Evaluate complains, then you are probably doing something less than sensible in the first place.

So, using all the above, we can produce functions like you asked for for the first four cases. However, they are all thin wrappers around underlying existing functions, and it would be better to create the polynomials over the desired rings in the first place.

1. Factorization

Actually, this turns out to be already present as another way to call Factorization:

> Factorization(f, L);
[
<t + 1/18*(-L.1^4 - 5*L.1^2 - 9*L.1 - 4), 1>,
<t + 1/18*(-L.1^4 - 5*L.1^2 + 9*L.1 - 4), 1>,
<t + 1/9*(L.1^4 + 5*L.1^2 + 4), 1>
]


2. Splitting Field

Here we need the simple wrapper:

> mySplittingField := func<pol, ring | SplittingField(ChangeRing(pol, ring))>;


Or, avoiding the shortcut func notation:

> mySplittingField := function(pol, ring)
>    return SplittingField(ChangeRing(pol, ring));
> end function;


3. Galois Group

> myGaloisGroup := func<pol, ring | GaloisGroup(ChangeRing(pol, ring))>;
> myGaloisGroup(f, L);
Permutation group acting on a set of cardinality 3
Order = 1


4. Roots

This also turns out to be present as an optional alternative:

> Roots(f, L);
[
<1/9*(-L.1^4 - 5*L.1^2 - 4), 1>,
<1/18*(L.1^4 + 5*L.1^2 - 9*L.1 + 4), 1>,
<1/18*(L.1^4 + 5*L.1^2 + 9*L.1 + 4), 1>
]