1
1
``` @meta
2
2
CurrentModule = Nemo
3
+ CollapsedDocStrings = true
3
4
DocTestSetup = quote
4
5
using Nemo
5
6
end
6
7
```
7
8
8
- # Algebraic numbers
9
+ # Algebraic closure of the rational numbers
9
10
10
- Nemo allows working with exact real and complex algebraic numbers.
11
+ An implementation of the field of all algebraic numbers, that is, an algebraic closure of the field of rational numbers, is provided through the type ` QQBarField ` and the corresponding element type ` QQBarFieldElem ` .
11
12
12
- The default algebraic number type in Nemo is provided by Calcium. The
13
- associated field of algebraic numbers can be constructed using
14
- ` QQBar = algebraic_closure(QQ) ` . We will leave out this line from
15
- all code blocks on this page for brevity.
13
+ Note that the field of algebraic closure is implemented as an ordered field,
14
+ see [ Comparing algebraic numbers]
16
15
17
- Library | Element type | Parent type
18
- ----------------|------------------|--------------------
19
- Calcium | ` QQBarFieldElem ` | ` QQBarField `
16
+ ## Constructing the field of algebraic numbers
20
17
21
- ** Important note on performance**
22
-
23
- The default algebraic number type represents algebraic numbers
24
- in canonical form using minimal polynomials. This works well for representing
25
- individual algebraic numbers, but it does not provide the best
26
- performance for field arithmetic.
27
- For fast calculation in $\overline{\mathbb{Q}}$,
28
- ` CalciumField ` should typically be used instead (see the section
29
- on * Exact real and complex numbers* ).
30
- Alternatively, to compute in a fixed subfield of $\overline{\mathbb{Q}}$,
31
- you may fix a generator $a$ and construct a number field to represent $\mathbb{Q}(a)$.
18
+ ``` jldoctest
19
+ julia> algebraic_closure(QQ)
20
+ Algebraic closure of rational field
21
+ ```
32
22
33
23
## Algebraic number functionality
34
24
35
- ### Constructing algebraic numbers
36
-
37
25
Methods to construct algebraic numbers include:
38
26
39
27
* Conversion from other numbers and through arithmetic operations
@@ -47,24 +35,28 @@ Methods to construct algebraic numbers include:
47
35
48
36
Arithmetic:
49
37
50
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
51
- julia> ZZRingElem(QQBar(3))
38
+ ``` jldoctest
39
+ julia> Qb = algebraic_closure(QQ);
40
+
41
+ julia> ZZRingElem(Qb(3))
52
42
3
53
43
54
- julia> QQFieldElem(QQBar (3) // 2)
44
+ julia> QQFieldElem(Qb (3) // 2)
55
45
3//2
56
46
57
- julia> QQBar (-1) ^ (QQBar (1) // 3)
47
+ julia> Qb (-1) ^ (Qb (1) // 3)
58
48
Root 0.500000 + 0.866025*im of x^2 - x + 1
59
49
```
60
50
61
51
Solving the quintic equation:
62
52
63
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
53
+ ``` jldoctest
54
+ julia> Qb = algebraic_closure(QQ);
55
+
64
56
julia> R, x = polynomial_ring(QQ, "x")
65
57
(Univariate polynomial ring in x over QQ, x)
66
58
67
- julia> v = roots(QQBar , x^5-x-1)
59
+ julia> v = roots(Qb , x^5-x-1)
68
60
5-element Vector{QQBarFieldElem}:
69
61
Root 1.16730 of x^5 - x - 1
70
62
Root 0.181232 + 1.08395*im of x^5 - x - 1
78
70
79
71
Computing exact eigenvalues of a matrix:
80
72
81
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
82
- julia> eigenvalues(QQBar, ZZ[1 1 0; 0 1 1; 1 0 1])
73
+ ``` jldoctest
74
+ julia> Qb = algebraic_closure(QQ);
75
+
76
+ julia> eigenvalues(Qb, ZZ[1 1 0; 0 1 1; 1 0 1])
83
77
3-element Vector{QQBarFieldElem}:
84
78
Root 2.00000 of x - 2
85
79
Root 0.500000 + 0.866025*im of x^2 - x + 1
@@ -106,11 +100,13 @@ Algebraic numbers can be evaluated
106
100
numerically to arbitrary precision by converting
107
101
to real or complex Arb fields:
108
102
109
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
110
- julia> RR = ArbField(64); RR(sqrt(QQBar(2)))
103
+ ``` jldoctest
104
+ julia> Qb = algebraic_closure(QQ);
105
+
106
+ julia> RR = ArbField(64); RR(sqrt(Qb(2)))
111
107
[1.414213562373095049 +/- 3.45e-19]
112
108
113
- julia> CC = AcbField(32); CC(QQBar (-1) ^ (QQBar (1) // 4))
109
+ julia> CC = AcbField(32); CC(Qb (-1) ^ (Qb (1) // 4))
114
110
[0.707106781 +/- 2.74e-10] + [0.707106781 +/- 2.74e-10]*im
115
111
```
116
112
@@ -121,11 +117,13 @@ julia> CC = AcbField(32); CC(QQBar(-1) ^ (QQBar(1) // 4))
121
117
Retrieving the minimal polynomial and algebraic conjugates
122
118
of a given algebraic number:
123
119
124
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
125
- julia> minpoly(polynomial_ring(ZZ, "x")[1], QQBar(1+2im))
120
+ ``` jldoctest
121
+ julia> Qb = algebraic_closure(QQ);
122
+
123
+ julia> minpoly(polynomial_ring(ZZ, "x")[1], Qb(1+2im))
126
124
x^2 - 2*x + 5
127
125
128
- julia> conjugates(QQBar (1+2im))
126
+ julia> conjugates(Qb (1+2im))
129
127
2-element Vector{QQBarFieldElem}:
130
128
Root 1.00000 + 2.00000*im of x^2 - 2x + 5
131
129
Root 1.00000 - 2.00000*im of x^2 - 2x + 5
@@ -154,17 +152,19 @@ height_bits(x::QQBarFieldElem)
154
152
155
153
** Examples**
156
154
157
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
158
- julia> real(sqrt(QQBar(1im)))
155
+ ``` jldoctest
156
+ julia> Qb = algebraic_closure(QQ);
157
+
158
+ julia> real(sqrt(Qb(1im)))
159
159
Root 0.707107 of 2x^2 - 1
160
160
161
- julia> abs(sqrt(QQBar (1im)))
161
+ julia> abs(sqrt(Qb (1im)))
162
162
Root 1.00000 of x - 1
163
163
164
- julia> floor(sqrt(QQBar (1000)))
164
+ julia> floor(sqrt(Qb (1000)))
165
165
Root 31.0000 of x - 31
166
166
167
- julia> sign(QQBar (-10-20im))
167
+ julia> sign(Qb (-10-20im))
168
168
Root -0.447214 - 0.894427*im of 5x^4 + 6x^2 + 5
169
169
```
170
170
@@ -212,11 +212,13 @@ first.
212
212
213
213
** Examples**
214
214
215
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
216
- julia> 1 < sqrt(QQBar(2)) < QQBar(3)//2
215
+ ``` jldoctest
216
+ julia> Qb = algebraic_closure(QQ);
217
+
218
+ julia> 1 < sqrt(Qb(2)) < Qb(3)//2
217
219
true
218
220
219
- julia> x = QQBar (3+4im)
221
+ julia> x = Qb (3+4im)
220
222
Root 3.00000 + 4.00000*im of x^2 - 6x + 25
221
223
222
224
julia> is_equal_abs(x, -x)
@@ -249,23 +251,25 @@ is_less_root_order(a::QQBarFieldElem, b::QQBarFieldElem)
249
251
250
252
** Examples**
251
253
252
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
253
- julia> root(QQBar(2), 5)
254
+ ``` jldoctest
255
+ julia> Qb = algebraic_closure(QQ);
256
+
257
+ julia> root(Qb(2), 5)
254
258
Root 1.14870 of x^5 - 2
255
259
256
- julia> sinpi(QQBar (7) // 13)
260
+ julia> sinpi(Qb (7) // 13)
257
261
Root 0.992709 of 4096x^12 - 13312x^10 + 16640x^8 - 9984x^6 + 2912x^4 - 364x^2 + 13
258
262
259
- julia> tanpi(atanpi(sqrt(QQBar (2)) + 1))
263
+ julia> tanpi(atanpi(sqrt(Qb (2)) + 1))
260
264
Root 2.41421 of x^2 - 2x - 1
261
265
262
- julia> root_of_unity(QQBar , 5)
266
+ julia> root_of_unity(Qb , 5)
263
267
Root 0.309017 + 0.951057*im of x^4 + x^3 + x^2 + x + 1
264
268
265
- julia> root_of_unity(QQBar , 5, 4)
269
+ julia> root_of_unity(Qb , 5, 4)
266
270
Root 0.309017 - 0.951057*im of x^4 + x^3 + x^2 + x + 1
267
271
268
- julia> w = (1 - sqrt(QQBar (-3)))//2
272
+ julia> w = (1 - sqrt(Qb (-3)))//2
269
273
Root 0.500000 - 0.866025*im of x^2 - x + 1
270
274
271
275
julia> is_root_of_unity(w)
@@ -304,8 +308,10 @@ atanpi(a::QQBarFieldElem)
304
308
305
309
An algebraic number can be recovered from a numerical value:
306
310
307
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
308
- julia> RR = RealField(); guess(QQBar, RR("1.41421356 +/- 1e-6"), 2)
311
+ ``` jldoctest
312
+ julia> Qb = algebraic_closure(QQ);
313
+
314
+ julia> RR = RealField(); guess(Qb, RR("1.41421356 +/- 1e-6"), 2)
309
315
Root 1.41421 of x^2 - 2
310
316
```
311
317
@@ -314,16 +320,18 @@ approximation, you should add an error estimate; otherwise, at best the only
314
320
algebraic number that can be guessed is the binary floating-point number
315
321
itself, at worst no guess is possible.
316
322
317
- ``` jldoctest; setup = :(QQBar = algebraic_closure(QQ))
323
+ ``` jldoctest
324
+ julia> Qb = algebraic_closure(QQ);
325
+
318
326
julia> RR = RealField();
319
327
320
328
julia> x = RR(0.1) # note: 53-bit binary approximation of 1//10 without radius
321
329
[0.10000000000000000555 +/- 1.12e-21]
322
330
323
- julia> guess(QQBar , x, 1)
331
+ julia> guess(Qb , x, 1)
324
332
ERROR: No suitable algebraic number found
325
333
326
- julia> guess(QQBar , x + RR("+/- 1e-10"), 1)
334
+ julia> guess(Qb , x + RR("+/- 1e-10"), 1)
327
335
Root 0.100000 of 10x - 1
328
336
```
329
337
@@ -333,3 +341,15 @@ Root 0.100000 of 10x - 1
333
341
guess
334
342
```
335
343
344
+ # Important note on performance
345
+
346
+ The default algebraic number type represents algebraic numbers
347
+ in canonical form using minimal polynomials. This works well for representing
348
+ individual algebraic numbers, but it does not provide the best
349
+ performance for field arithmetic.
350
+ For fast calculation in $\overline{\mathbb{Q}}$,
351
+ ` CalciumField ` should typically be used instead (see the section
352
+ on * Exact real and complex numbers* ).
353
+ Alternatively, to compute in a fixed subfield of $\overline{\mathbb{Q}}$,
354
+ you may fix a generator $a$ and construct a number field to represent $\mathbb{Q}(a)$.
355
+
0 commit comments