Section 23.7 Sage
Again, our competence at examining fields with Sage will allow us to study the main concepts of Galois Theory easily. We will thoroughly examine Example 7 carefully using our computational tools.
Subsection Galois Groups
We will repeat Example 23.25 and analyze carefully the splitting field of the polynomial We begin with an initial field extension containing at least one root.
xxxxxxxxxx
x = polygen(QQ, 'x')
N.<a> = NumberField(x^4 - 2); N
The
.galois_closure()
method will create an extension containing all of the roots of the defining polynomial of a number field.xxxxxxxxxx
L.<b> = N.galois_closure(); L
xxxxxxxxxx
L.degree()
xxxxxxxxxx
y = polygen(L, 'y')
(y^4 - 2).factor()
From the factorization, it is clear that
L
is the splitting field of the polynomial, even if the factorization is not pretty. It is easy to then obtain the Galois group of this field extension.xxxxxxxxxx
G = L.galois_group(); G
We can examine this group, and identify it. Notice that since the field is a degree extension, the group is described as a permutation group on symbols. (It is just a coincidence that the group has elements.) With a paucity of nonabelian groups of order it is not hard to guess the nature of the group.
xxxxxxxxxx
G.is_abelian()
xxxxxxxxxx
G.order()
xxxxxxxxxx
G.list()
xxxxxxxxxx
G.is_isomorphic(DihedralGroup(4))
Thatβs it. But maybe not very satisfying. Let us dig deeper for more understanding. We will start over and create the splitting field of again, but the primary difference is that we will make the roots extremely obvious so we can work more carefully with the Galois group and the fixed fields. Along the way, we will see another example of linear algebra enabling certain computations. The following construction should be familiar by now.
xxxxxxxxxx
x = polygen(QQ, 'x')
p = x^4 - 2
N.<a> = NumberField(p); N
xxxxxxxxxx
y = polygen(N, 'y')
p = p.subs(x=y)
p.factor()
xxxxxxxxxx
M.<b> = NumberField(y^2 + a^2); M
xxxxxxxxxx
z = polygen(M, 'z')
(z^4 - 2).factor()
The important thing to notice here is that we have arranged the splitting field so that the four roots, and (or their negatives).
a, -a, b, -b
, are very simple functions of the generators. In more traditional notation, a
is b
is We will find it easier to compute in the flattened tower, a now familiar construction.
xxxxxxxxxx
L.<c> = M.absolute_field(); L
xxxxxxxxxx
fromL, toL = L.structure()
We can return to our original polynomial (over the rationals), and ask for its roots in the flattened tower, custom-designed to contain these roots.
xxxxxxxxxx
roots = p.roots(ring=L, multiplicities=False); roots
Hmmm. Do those look right? If you look back at the factorization obtained in the field constructed with the
.galois_closure()
method, then they look right. But we can do better.xxxxxxxxxx
[fromL(r) for r in roots]
Yes, those are the roots.
xxxxxxxxxx
G = End(L); G
We can check that each of these automorphisms fixes the rational numbers elementwise. If a field homomorphism fixes 1, then it will fix the integers, and thus fix all fractions of integers.
xxxxxxxxxx
[tau(1) for tau in G]
So each element of
G
fixes the rationals elementwise and thus G
is the Galois group of the splitting field L
over the rationals.
Proposition 23.5 is fundamental. It says every automorphism in the Galois group of a field extension creates a permutation of the roots of a polynomial with coefficients in the base field. We have all of those ingredients here. So we will evaluate each automorphism of the Galois group at each of the four roots of our polynomial, which in each case should be another root. (We use the
Sequence()
constructor just to get nicely-aligned output.)xxxxxxxxxx
Sequence([[fromL(tau(r)) for r in roots] for tau in G], cr=True)
Each row of the output is a list of the roots, but permuted, and so corresponds to a permutation of four objects (the roots). For example, the second row shows the second automorphism interchanging It is overkill, but we can then build the permutation group by letting all of these elements generate a group.
a
with -a
, and b
with -b
. (Notice that the first row is the result of the identity automorphism, so we can mentally comine the first row with any other row to imagine a βtwo-rowβ form of a permutation.) We can number the roots, 1 through 4, and create each permutation as an element of xxxxxxxxxx
S4 = SymmetricGroup(4)
elements = [S4([1, 2, 3, 4]),
S4([4, 3, 2, 1]),
S4([2, 4, 1, 3]),
S4([1, 3, 2, 4]),
S4([3, 4, 1, 2]),
S4([2, 1, 4, 3]),
S4([4, 2, 3, 1]),
S4([3, 1, 4, 2])]
elements
xxxxxxxxxx
P = S4.subgroup(elements)
P.is_isomorphic(DihedralGroup(4))
Notice that we now have built an isomorphism from the Galois group to a group of permutations using just four symbols, rather than the eight used previously.
Subsection Fixed Fields
In a previous Sage exercise, we computed the fixed fields of single field automorphisms for finite fields. This was βeasyβ in the sense that we could just test every element of the field to see if it was fixed, since the field was finite. Now we have an infinite field extension. How are we going to determine which elements are fixed by individual automorphisms, or subgroups of automorphisms?
The answer is to use the vector space structure of the flattened tower. As a degree extension of the rationals, the first powers of the primitive element
c
form a basis when the field is viewed as a vector space with the rationals as the scalars. It is sufficient to know how each field automorphism behaves on this basis to fully specify the definition of the automorphism. To wit,So we can compute the value of a field automorphism at any linear combination of powers of the primitive element as a linear combination of the values of the field automorphism at just the powers of the primitive element. This is known as the βpower basisβ, which we can obtain simply with the is totally defined by the value of since as a field automorphism However, we still need to work with the entire power basis to exploit the vector space structure.)
.power_basis()
method. We will begin with an example of how we can use this basis. We will illustrate with the fourth automorphism of the Galois group. Notice that the .vector()
method is a convenience that strips a linear combination of the powers of c
into a vector of just the coefficients. (Notice too that xxxxxxxxxx
basis = L.power_basis(); basis
xxxxxxxxxx
tau = G[3]
z = 4 + 5*c+ 6*c^3-7*c^6
tz = tau(4 + 5*c+ 6*c^3-7*c^6); tz
xxxxxxxxxx
tz.vector()
xxxxxxxxxx
tau_matrix = column_matrix([tau(be).vector() for be in basis])
tau_matrix
xxxxxxxxxx
tau_matrix*z.vector()
xxxxxxxxxx
tau_matrix*(z.vector()) == (tau(z)).vector()
The last line expresses the fact that permutation of the roots, the inverse of the matrix is itself. But these facts are just verifications that we have the right thing, we are interested in other properties.
tau_matrix
is a matrix representation of the field automorphism, viewed as a linear transformation of the vector space structure. As a representation of an invertible field homomorphism, the matrix is invertible. As an order To construct fixed fields, we want to find elements fixed by automorphisms. Continuing with or elements of the null space of
tau
from above, we seek elements z
(written as vectors) such that tau_matrix*z=z
. These are eigenvectors for the eigenvalue (tau_matrix - I)
(null spaces are obtained with .right_kernel()
in Sage).xxxxxxxxxx
K = (tau_matrix-identity_matrix(8)).right_kernel(); K
Each row of the basis matrix is a vector representing an element of the field, specifically
1
, c + (1/38)*c^5
, c^2 - (1/22)*c^6
, c^3 + (1/278)*c^7
. Letβs take a closer look at these fixed elements, in terms we recognize.xxxxxxxxxx
fromL(1)
xxxxxxxxxx
fromL(c + (1/38)*c^5)
xxxxxxxxxx
fromL(c^2 - (1/22)*c^6)
xxxxxxxxxx
fromL(c^3 + (1/278)*c^7)
Any element fixed by ) and ). Furthermore, to the rationals. So the elements fixed by
tau
will be a linear combination of these four elements. We can ignore any rational multiples present, the first element is just saying the rationals are fixed, and the last element is just a product of the middle two. So fundamentally tau
is fixing rationals, b
(which is a^2
(which is b^2 = -a^2
(the check follows), so we can create any fixed element of tau
by just adjoining b
=tau
are xxxxxxxxxx
a^2 + b^2
Subsection Galois Correspondence
The entire subfield structure of our splitting field is determined by the subgroup structure of the Galois group (Theorem 23.23), which is isomorphic to a group we know well. What are the subgroups of our Galois group, expressed as permutation groups? (For brevity, we just list the generators of each subgroup.)
xxxxxxxxxx
sg = P.subgroups();
[H.gens() for H in sg]
xxxxxxxxxx
[H.order() for H in sg]
tau
above is the fourth element of the automorphism group, and the fourth permutation in elements
is the permutation (2,3)
, the generator (of order 2) for the second subgroup. So as the only nontrivial element of this subgroup, we know that the corresponding fixed field is Let us analyze another subgroup of order 2, without all the explanation, and starting with the subgroup. The sixth subgroup is generated by the fifth automorphism, so let us determine the elements that are fixed.
xxxxxxxxxx
tau = G[4]
tau_matrix = column_matrix([tau(be).vector() for be in basis])
(tau_matrix-identity_matrix(8)).right_kernel()
xxxxxxxxxx
fromL(tau(1))
xxxxxxxxxx
fromL(tau(c+(1/158)*c^5))
xxxxxxxxxx
fromL(tau(c^2+(1/78)*c^6))
xxxxxxxxxx
fromL(tau(c^3+(13/614)*c^7))
The first element indicates that the rationals are fixed (we knew that). Scaling the second element gives
b - a
as a fixed element. Scaling the third and fourth fixed elements, we recognize that they can be obtained from powers of b - a
.xxxxxxxxxx
(b-a)^2
xxxxxxxxxx
(b-a)^3
So the fixed field of this subgroup can be formed by adjoining so the fixed field is
b - a
to the rationals, which in mathematical notation is We can create this fixed field, though as created here it is not strictly a subfield of
L
. We will use an expression for b - a
that is a linear combination of powers of c
.xxxxxxxxxx
subinfo = L.subfield((79/120)*(c+(1/158)*c^5)); subinfo
The β you can check that is indeed a root of the polynomial
.subfield()
method returns a pair. The first item is a new number field, isomorphic to a subfield of L
. The second item is an injective mapping from the new number field into L
. In this case, the image of the primitive element c0
is the element we have specified as the generator of the subfield. The primitive element of the new field will satisfy the defining polynomial There are five subgroups of order we have found fixed fields for two of them. The other three are similar, so it would be a good exercise to work through them. Our automorphism group has three subgroups of order 4, and at least one of each possible type (cyclic versus non-cyclic). Fixed fields of larger subgroups require that we find elements fixed by all of the automorphisms in the subgroup. (We were conveniently ignoring the identity automorphism above.) This will require more computation, but will restrict the possibilities (smaller fields) to where it will be easier to deduce a primitive element for each field.
The seventh subgroup is generated by two elements of order and is composed entirely of elements of order (except the identity), so is isomorphic to The permutations correspond to automorphisms number 0, 1, 3, and 6. To determine the elements fixed by all four automorphisms, we will build the kernel for each one and as we go, we form the intersection of all four kernels. We will work via a loop over the four automorphisms.
xxxxxxxxxx
V = QQ^8
for tau in [G[0], G[1], G[3], G[6]]:
tau_matrix = column_matrix([tau(be).vector() for be in basis])
K = (tau_matrix-identity_matrix(8)).right_kernel()
V = V.intersection(K)
V
Outside of the rationals, there is a single fixed element.
xxxxxxxxxx
fromL(tau(c^2 - (1/22)*c^6))
Removing a scalar multiple, our primitive element is so the fixed field is Again, we can build this fixed field, but ignore the mapping.
a^2
, which mathematically is xxxxxxxxxx
F, mapping = L.subfield((11/150)*(c^2 - (1/22)*c^6))
F
One more subgroup. The penultimate subgroup has a permutation of order 4 as a generator, so is a cyclic group of order 4. The individual permutations of the subgroup correspond to automorphisms 0, 1, 2, 7.
xxxxxxxxxx
V = QQ^8
for tau in [G[0], G[1], G[2], G[7]]:
tau_matrix = column_matrix([tau(be).vector() for be in basis])
K = (tau_matrix-identity_matrix(8)).right_kernel()
V = V.intersection(K)
V
So we compute the primitive element.
xxxxxxxxxx
fromL(tau(c^4))
Since rationals are fixed, we can remove the and the multiple and take so we might as well use just as the primitive element and the fixed field is We can then build the fixed field (and ignore the mapping also returned).
a^3*b
as the primitive element. Mathematically, this is xxxxxxxxxx
F, mapping = L.subfield((c^4+14)/-48)
F
There is one more subgroup of order which we will leave as an exercise to analyze. There are also two trivial subgroups (the identity and the full group) which are not very interesting or surprising.
If the above seems like too much work, you can always just have Sage do it all with the
.subfields()
method.xxxxxxxxxx
L.subfields()
Ten subfields are described, which is what we would expect, given the 10 subgroups of the Galois group. Each begins with a new number field that is a subfield. Technically, each is not a subset of
L
, but the second item returned for each subfield is an injective homomorphism, also known generally as an βembedding.β Each embedding describes how a primitive element of the subfield translates to an element of L
. Some of these primitive elements could be manipulated (as we have done above) to yield slightly simpler minimal polynomials, but the results are quite impressive nonetheless. Each item in the list has a third component, which is almost always None
, except when the subfield is the whole field, and then the third component is an injective homomorphism βin the other direction.βSubsection Normal Extensions
Consider the third subgroup in the list above, generated by the permutation it only has one nontrivial element, which here corresponds to the seventh automorphism. We determine the fixed elements as before.
(1,4)
. As a subgroup of order xxxxxxxxxx
tau = G[6]
tau_matrix = column_matrix([tau(be).vector() for be in basis])
(tau_matrix-identity_matrix(8)).right_kernel()
xxxxxxxxxx
fromL(tau(1))
xxxxxxxxxx
fromL(tau(c+(-1/82)*c^5))
xxxxxxxxxx
fromL(tau(c^2+(-1/22)*c^6))
xxxxxxxxxx
fromL(tau(c^3+(11/58)*c^7))
As usual, ignoring rational multiples, we see powers of Recognize that and was used to create the first part of original tower, and the fixed field of
a
and recognize that a
alone will be a primitive element for the fixed field, which is thus a
was our first root of N
. So N
is both xxxxxxxxxx
sg[2].is_normal(P)
As expected.