## Section21.7Sage

In Sage, and other places, an extension of the rationals is called a “number field.” They are one of Sage's most mature features.

### SubsectionNumber Fields

There are several ways to create a number field. We are familiar with the syntax where we adjoin an irrational number that we can write with traditional combinations of arithmetic and roots.

M.<a> = QQ[sqrt(2)+sqrt(3)]; M


We can also specify the element we want to adjoin as the root of a monic irreducible polynomial. One approach is to construct the polynomial ring first so that the polynomial has the location of its coefficients specified properly.

F.<y> = QQ[]
p = y^3 - 1/4*y^2 - 1/16*y + 1/4
p.is_irreducible()

N.<b> = NumberField(p, 'b'); N


Rather than building the whole polynomial ring, we can simply introduce a variable as the generator of a polynomial ring and then create polynomials from this variable. This spares us naming the polynomial ring. Notice in the example that both instances of z are necessary.

z = polygen(QQ, 'z')
q = z^3 - 1/4*z^2 - 1/16*z + 1/4
q.parent()

P.<c> = NumberField(q, 'c'); P


We can recover the polynomial used to create a number field, even if we constructed it by giving an expression for an irrational element. In this case, the polynomial is the minimal polynomial of the element.

M.polynomial()

N.polynomial()


For any element of a number field, Sage will obligingly compute its minimal polynomial.

element = -b^2 + 1/3*b + 4
element.parent()

r = element.minpoly('t'); r

r.parent()

r.subs(t=element)


Substituting element back into the alleged minimal polynomial and getting back zero is not convincing evidence that it is the minimal polynomial, but it is heartening.

### SubsectionRelative and Absolute Number Fields

With Sage we can adjoin several elements at once and we can build nested towers of number fields. Sage uses the term “absolute” to refer to a number field viewed as an extension of the rationals themselves, and the term “relative” to refer to a number field constructed, or viewed, as an extension of another (nontrivial) number field.

A.<a,b> = QQ[sqrt(2), sqrt(3)]
A

B = A.base_field(); B

A.is_relative()

B.is_relative()


The number field A has been constructed mathematically as what we would write as $${\mathbb Q}\subset{\mathbb Q}[\sqrt{3}]\subset{\mathbb Q}[\sqrt{3},\sqrt{2}]\text{.}$$ Notice the slight difference in ordering of the elements we are adjoining, and notice how the number fields use slightly fancier internal names (sqrt2, sqrt3) for the new elements.

We can “flatten” a relative field to view it as an absolute field, which may have been our intention from the start. Here we create a new number field from A that makes it a pure absolute number field.

C.<c> = A.absolute_field()
C


Once we construct an absolute number field this way, we can recover isomorphisms to and from the absolute field. Recall that our tower was built with generators a and b, while the flattened tower is generated by c. The .structure() method returns a pair of functions, with the absolute number field as the domain and codomain (in that order).

fromC, toC = C.structure()
fromC(c)

toC(a)

toC(b)


This tells us that the single generator of the flattened tower, c, is equal to $$\sqrt{2}-\sqrt{3}\text{,}$$ and further, each of $$\sqrt{2}$$ and $$\sqrt{3}$$ can be expressed as polynomial functions of c. With these connections, you might want to compute the final two expressions in c by hand, and appreciate the work Sage does to determine these for us. This computation is an example of the conclusion of the upcoming Theorem 23.13.

Many number field methods have both relative and absolute versions, and we will also find it more convenient to work in a tower or a flattened version, thus the isomorphisms between the two can be invaluable for translating both questions and answers.

As a vector space over $${\mathbb Q}\text{,}$$ or over another number field, number fields that are finite extensions have a dimension, called the degree. These are easy to get from Sage, though for a relative field, we need to be more precise about which degree we desire.

B.degree()

A.absolute_degree()

A.relative_degree()


### SubsectionSplitting Fields

Here is a concrete example of how to use Sage to construct a splitting field of a polynomial. Consider $$p(x)=x^4+x^2-1\text{.}$$ We first build a number field with a single root, and then factor the polynomial over this new, larger, field.

x = polygen(QQ, 'x')
p = x^4 + x^2 - 1
p.parent()

p.is_irreducible()

M.<a> = NumberField(p, 'a')
y = polygen(M, 'y')
p = p.subs(x = y)
p

p.parent()

p.factor()

a^2 + 1 in QQ


So our polynomial factors partially into two linear factors and a quadratic factor. But notice that the quadratic factor has a coefficient that is irrational, $$a^2+1\text{,}$$ so the quadratic factor properly belongs in the polynomial ring over M and not over QQ.

We build an extension containing a root of the quadratic factor, called q here. Then, rather than using the polygen() function, we build an entire polynomial ring R over N with the indeterminate z. The reason for doing this is we can illustrate how we “upgrade” the polynomial p with the syntax R(p) to go from having coefficients in M to having coefficients in N.

q = y^2 + a^2 + 1
N.<b> = NumberField(q, 'b')
R.<z> = N[]
s = R(p)
s

s.parent()

s.factor()

a in N, b in N


So we have a field, N, where our polynomial factors into linear factors with coefficients from the field. We can get another factorization by converting N to an absolute number field and factoring there. We need to recreate the polynomial over N, since a substitution will carry coefficients from the wrong ring.

P.<c> = N.absolute_field()
w = polygen(P, 'w')
p = w^4 + w^2- 1
p.factor()


This is an interesting alternative, in that the roots of the polynomial are expressions in terms of the single generator c. Since the roots involve a seventh power of c, we might suspect (but not be certain) that the minimal polynomial of c has degree $$8$$ and that P is a degree $$8$$ extension of the rationals. Indeed P (or N) is a splitting field for $$p(x)=x^4+x^2-1\text{.}$$ The roots are not really as bad as they appear — lets convert them back to the relative number field.

First we want to rewrite a single factor (the first) in the form $$(w-r)$$ to identify the root with the correct signs.

(w -  7/18966*c^7 + 110/9483*c^5 + 923/9483*c^3 + 3001/6322*c) =
(w - (7/18966*c^7 - 110/9483*c^5 - 923/9483*c^3 - 3001/6322*c))


With the conversion isomorphisms, we can recognize the roots for what they are.

fromP, toP = P.structure()
fromP(7/18966*c^7 - 110/9483*c^5 - 923/9483*c^3 - 3001/6322*c)


So the rather complicated expression in c is just the negative of the root we adjoined in the second step of constructing the tower of number fields. It would be a good exercise to see what happens to the other three roots (being careful to get the signs right on each root).

This is a good opportunity to illustrate Theorem 21.17.

M.degree()

N.relative_degree()

P.degree()

M.degree()*N.relative_degree() == P.degree()


### SubsectionAlgebraic Numbers

Corollary 21.24 says that the set of all algebraic numbers forms a field. This field is implemented in Sage as QQbar. This allows for finding roots of polynomials as exact quantities which display as inexact numbers.

x = polygen(QQ, 'x')
p = x^4 + x^2 - 1
r = p.roots(ring=QQbar); r


So we asked for the roots of a polynomial over the rationals, but requested any root that may lie outside the rationals and within the field of algebraic numbers. Since the field of algebraic numbers contains all such roots, we get a full four roots of the fourth-degree polynomial. These roots are computed to lie within an interval and the question mark indicates that the preceding digits are accurate. (The integers paired with each root are the multiplicities of that root. Use the keyword multiplicities=False to turn them off.) Let us take a look under the hood and see how Sage manages the field of algebraic numbers.

r1 = r[0][0]; r1

r1.as_number_field_element()


Three items are associated with this initial root. First is a number field, with generator a and a defining polynomial similar to the polynomial we are finding the roots of, but not identical. Second is an expression in the generator a, which is the actual root. You might evaluate this expression with the numerical approximation of a, coming next, to verify this is a root. Finally, there is a ring homomorphism from the number field to the “Algebraic Real Field”, AA, the subfield of QQbar with just real elements, which associates the generator a with the number -1.272019649514069?. Let us verify, in two ways, that the root given is really a root.

r1^4 + r1^2 - 1

N, rexact, homomorphism = r1.as_number_field_element()
(rexact)^4 + rexact^2 - 1


Now that we have enough theory to understand the field of algebraic numbers, and a natural way to represent them exactly, you might consider the operations in the field. If we take two algebraic numbers and add them together, we get another algebraic number (Corollary 21.24). So what is the resulting minimal polynomial? How is it computed in Sage? You could read the source code if you wanted the answer.

### SubsectionGeometric Constructions

Sage can do a lot of things, but it is not yet able to lay out lines with a straightedge and compass. However, we can very quickly determine that trisecting a $$60$$ degree angle is impossible. We adjoin the cosine of a $$20$$ degree angle (in radians) to the rationals, determine the degree of the extension, and check that it is not an integer power of $$2\text{.}$$ In one line. Sweet.

log(QQ[cos(pi/9)].degree(), 2) in ZZ