We can compute the Galois group of a number field using the `galois_group`
function, which by default calls Pari (http://pari.math.u-bordeaux.fr/). You do
not have to worry about installing Pari, since *Pari is part of Sage*. In
fact, despite appearances much of the difficult algebraic number theory in Sage
is actually done by the Pari C library (be sure to also cite Pari in papers
that use Sage).

```
sage: K.<alpha> = NumberField(x^6 + 40*x^3 + 1372)
sage: G = K.galois_group()
sage: G
Galois group of Number Field in alpha with defining polynomial x^6 + 40*x^3 + 1372
```

Internally G is represented as a group of permutations, but we can also apply any element of G to any element of the field:

```
sage: G.order()
6
sage: G.gens()
[(1,2)(3,4)(5,6), (1,4,6)(2,5,3)]
sage: f = G.1; f(alpha)
1/36*alpha^4 + 1/18*alpha
```

Some more advanced number-theoretical tools are available via G:

```
sage: P = K.primes_above(2)[0]
sage: G.inertia_group(P)
Subgroup [(), (1,4,6)(2,5,3), (1,6,4)(2,3,5)] of Galois group of Number Field in alpha with defining polynomial x^6 + 40*x^3 + 1372
sage: sorted([G.artin_symbol(Q) for Q in K.primes_above(5)])
[(1,3)(2,6)(4,5), (1,2)(3,4)(5,6), (1,5)(2,4)(3,6)]
```

If the number field is not Galois over \(\QQ\), then the `galois_group`
command will construct its Galois closure and return the Galois group of that;
you need to give it a variable name for the generator of the Galois closure:

```
sage: K.<a> = NumberField(x^3 - 2)
sage: G = K.galois_group(names='b'); G
Galois group of Galois closure in b of Number Field in a with defining polynomial x^3 - 2
sage: G.order()
6
```

We compute two more Galois groups of degree \(5\) extensions, and see that one has Galois group \(S_5\), so is not solvable by radicals. For these purposes we only want to know the structure of the Galois group as an abstract group, rather than as an explicit group of automorphisms of the splitting field; this is much quicker to calculate. PARI has a type for representing “abstract Galois groups”, and Sage can use this.:

```
sage: NumberField(x^5 - 2, 'a').galois_group(type="pari")
Galois group PARI group [20, -1, 3, "F(5) = 5:4"] of
degree 5 of the Number Field in a with defining
polynomial x^5 - 2
sage: NumberField(x^5 - x + 2, 'a').galois_group(type="pari")
Galois group PARI group [120, -1, 5, "S5"] of degree 5 of
the Number Field in a with defining polynomial x^5 - x + 2
```

Recent versions of Magma have an algorithm for computing Galois groups that in
theory applies when the input polynomial has any degree. There are no open
source implementation of this algorithm (as far as I know). If you have Magma,
you can use this algorithm from Sage by calling the `galois_group` function
and giving the `algorithm='magma'` option. The return value is one of the
groups in the GAP transitive groups database.

```
sage: K.<a> = NumberField(x^3 - 2)
sage: K.galois_group(type="gap", algorithm='magma') # optional
verbose...
Galois group Transitive group number 2 of degree 3 of
the Number Field in a with defining polynomial x^3 - 2
```

We emphasize that the above example should not work if you don’t have Magma.

You can also enumerate all complex embeddings of a number field:

```
sage: K.complex_embeddings()
[
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Complex Field with 53 bits of precision
Defn: a |--> -0.629960524947437 - 1.09112363597172*I,
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Complex Field with 53 bits of precision
Defn: a |--> -0.629960524947437 + 1.09112363597172*I,
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Complex Field with 53 bits of precision
Defn: a |--> 1.25992104989487
]
```

The class group \(C_K\) of a number field \(K\) is the group
of fractional ideals of the maximal order \(R\) of \(K\)
modulo the subgroup of principal fractional ideals. One of the main
theorems of algebraic number theory asserts that \(C_K\) is a
finite group. For example, the quadratic number field
\(\QQ(\sqrt{-23})\) has class number \(3\), as we see
using the Sage `class number` command.

```
sage: L.<a> = NumberField(x^2 + 23)
sage: L.class_number()
3
```

There are only 9 quadratic imaginary field \(\QQ(\sqrt{D})\) that have class number \(1\):

\[D = -3, -4, -7, -8, -11, -19, -43, -67, -163\]

To find this list using Sage, we first experiment with making lists
in Sage. For example, typing `[1..10]` makes the
list of integers between \(1\) and \(10\).

```
sage: [1..10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

We can also make the list of odd integers between \(1\) and
\(11\), by typing `[1,3,..,11]`, i.e., by giving the second term
in the arithmetic progression.

```
sage: [1,3,..,11]
[1, 3, 5, 7, 9, 11]
```

Applying this idea, we make the list of negative numbers from \(-1\) down to \(-10\).

```
sage: [-1,-2,..,-10]
[-1, -2, -3, -4, -5, -6, -7, -8, -9, -10]
```

The first two lines below makes a list \(v\) of every \(D\) from \(-1\) down to \(-200\) such that \(D\) is a fundamental discriminant (the discriminant of a quadratic imaginary field).

Note

Note that you will not see the ... in the output below; this ... notation just means that part of the output is omitted below.

```
sage: w = [-1,-2,..,-200]
sage: v = [D for D in w if is_fundamental_discriminant(D)]
sage: v
[-3, -4, -7, -8, -11, -15, -19, -20, ..., -195, -199]
```

Finally, we make the list of \(D\) in our list \(v\) such that
the quadratic number field \(\QQ(\sqrt{D})\) has class
number \(1\). Notice that `QuadraticField(D)` is a shorthand for
`NumberField(x^2 - D)`.

```
sage: [D for D in v if QuadraticField(D,'a').class_number()==1]
[-3, -4, -7, -8, -11, -19, -43, -67, -163]
```

Of course, we have *not* proved that this is the list of all
negative \(D\) so that \(\QQ(\sqrt{D})\) has
class number \(1\).

A frustrating open problem is to prove that there are infinitely many number fields with class number \(1\). It is quite easy to be convinced that this is probably true by computing a bunch of class numbers of real quadratic fields. For example, over 58 percent of the real quadratic number fields with discriminant \(D<1000\) have class number \(1\)!

```
sage: w = [1..1000]
sage: v = [D for D in w if is_fundamental_discriminant(D)]
sage: len(v)
302
sage: len([D for D in v if QuadraticField(D,'a').class_number() == 1])
176
sage: 176.0/302
0.582781456953642
```

For more intuition about what is going on, read about the Cohen-Lenstra heuristics.

Sage can also compute class numbers of extensions of higher degree,
within reason. Here we use the shorthand `CyclotomicField(n)` to
create the number field \(\QQ(\zeta_n)\).

```
sage: CyclotomicField(7)
Cyclotomic Field of order 7 and degree 6
sage: for n in [2..15]: print n, CyclotomicField(n).class_number()
2 1
3 1
...
15 1
```

In the code above, the notation `for n in [2..15]: ...` means
“do ... for \(n\) equal to each of the integers \(2,3,4,\dots,15\).”

Note

Exercise: Compute what is omitted (replaced by ...) in the output of the previous example.

Computations of class numbers and class groups in Sage is done by the
Pari C library, and *unlike in Pari*, by default Sage tells Pari *not
to assume* any conjectures. This can make some commands vastly slower
than they might be directly in Pari, which *does assume unproved
conjectures* by default. Fortunately, it is easy to tell Sage to be
more permissive and allow Pari to assume conjectures, either just for
this one call or henceforth for all number field functions. For
example, with `proof=False` it takes only a few seconds to verify,
modulo the conjectures assumed by Pari, that the class number of
\(\QQ(\zeta_{23})\) is \(3\).

```
sage: CyclotomicField(23).class_number(proof=False)
3
```

Note

Exercise: What is the smallest \(n\) such that \(\QQ(\zeta_n)\) has class number bigger than \(1\)?

In addition to computing class numbers, Sage can also compute the group structure and generators for class groups. For example, the quadratic field \(\QQ(\sqrt{-30})\) has class group \(C = (\ZZ/2\ZZ)^{\oplus 2}\), with generators the ideal classes containing \((5,\sqrt{-30})\) and \((3,\sqrt{-30})\).

```
sage: K.<a> = QuadraticField(-30)
sage: C = K.class_group()
sage: C
Class group of order 4 with structure C2 x C2 of Number Field
in a with defining polynomial x^2 + 30
sage: category(C)
Category of groups
sage: C.gens()
(Fractional ideal class (5, a), Fractional ideal class (3, a))
```

In Sage, the notation `C.i` means “the \(i^{th}\) generator of the
object \(C\),” where the generators are indexed by numbers
\(0, 1, 2, \dots\). Below, when we write `C.0 \* C.1`, this
means “the product of the 0th and 1st generators of the class group
\(C\).”

```
sage: K.<a> = QuadraticField(-30)
sage: C = K.class_group()
sage: C.0
Fractional ideal class (5, a)
sage: C.0.ideal()
Fractional ideal (5, a)
sage: I = C.0 * C.1
sage: I
Fractional ideal class (2, a)
```

Next we find that the class of the fractional ideal \((2,\sqrt{-30}+4/3)\) is equal to the ideal class \(I\).

```
sage: A = K.ideal([2, a+4/3])
sage: J = C(A)
sage: J
Fractional ideal class (2/3, 1/3*a)
sage: J == I
True
```

Unfortunately, there is currently no Sage function that writes a fractional ideal class in terms of the generators for the class group.