[1]:
using Oscar
$\require{action}$
 -----    -----    -----      -      -----
|     |  |     |  |     |    | |    |     |
|     |  |        |         |   |   |     |
|     |   -----   |        |     |  |-----
|     |        |  |        |-----|  |   |
|     |  |     |  |     |  |     |  |    |
 -----    -----    -----   -     -  -     -

...combining (and extending) ANTIC, GAP, Polymake and Singular
Version 0.5.0 ...
 ... which comes with absolutely no warranty whatsoever
Type: '?Oscar' for more information
(c) 2019-2020 by The Oscar Development Team

Number Theory in OSCAR

Number theory in OSCAR works with a mix of systems that also build on each other: Hecke, Nemo, Flint, AbstractAlgebra, Antic. They are all put together under the name Antic. As a user, you can think about Hecke as being the main system, and find documentation in Hecke.jl: http://www.thofma.com/Hecke.jl/latest/. There is also a nice example of the basics in Hecke.jl written by Claus Fieker: https://nbviewer.jupyter.org/github/oscar-system/OSCARBinder/blob/master/Hecke.ipynb. For this exposition I used these two resources.

Creating number fields

Let’s start with creating a basic number field. This is done by adding the roots of an irreducible polynomial.

[2]:
R, x = PolynomialRing(QQ, "x")
[2]:
($R$, $x$)
[3]:
K, a = NumberField(x^2 - 2, "a")
[3]:
($K$, $a$)

\(a\) is the class of \(x\) in \(\mathbb{Q}[x]/(x^2-2)\):

[4]:
a^2
[4]:
$2$

We can also create a number field without naming the class of \(x\), but we have to be aware that this is a vector with two elements: the field and the class of \(x\).

[5]:
N = NumberField(x^8 - 21*x^6 + 84*x^4 - 105*x^2 + 25)
[5]:
($\text{Number field over Rational field with defining polynomial }x^{8} - 21x^{6} + 84x^{4} - 105x^{2} + 25$, $\alpha$)
[6]:
N[2]^8
[6]:
$21\alpha^{6} - 84\alpha^{4} + 105\alpha^{2} - 25$

There are some standard number fields implemented, and we can check whether two number fields are isomorphic.

[7]:
C = cyclotomic_field(3);
[8]:
C2 = NumberField(x^2+x+1)
[8]:
($\text{Number field over Rational field with defining polynomial }x^{2} + x + 1$, $\alpha$)
[9]:
isisomorphic(C[1],C2[1])
[9]:
(true, $\text{Map from }\text{Number field over Rational field with defining polynomial }_$^{2} + _$ + 1\to \text{Number field over Rational field with defining polynomial }x^{2} + x + 1$)

The output does not give the mathmode correctly. This seems to happen with the command cyclotomic_field. Mathematically there are no errors, though!

We can create non-simple number fields, by adding roots from multiple polynomials…….

[10]:
L, b = number_field([x^2-2, x^2-3, x^2-5])
[10]:
($L$, [NfAbsNSElem[_$1, _$2, _$3])
[11]:
for i = 1:3
    println(b[i]^2)
end
2
3
5

… and convert it to a simple field!

[12]:
S = simple_extension(L)
[12]:
($\text{Number field over Rational field with defining polynomial }x^{8} - 40x^{6} + 352x^{4} - 960x^{2} + 576$, $\text{Map from }\text{Number field over Rational field with defining polynomial }x^{8} - 40x^{6} + 352x^{4} - 960x^{2} + 576\to L$)

It is generated by a polynomial of degree 8. Could it be isomorphic to N?

[13]:
isisomorphic(S[1],N[1])
[13]:
(false, $\text{Map from }\text{Number field over Rational field with defining polynomial }x^{8} - 40x^{6} + 352x^{4} - 960x^{2} + 576\to \text{Number field over Rational field with defining polynomial }x^{8} - 21x^{6} + 84x^{4} - 105x^{2} + 25$)

Representing a field as a simple extension is often needed for computations. For example, to compare it to other simple number fields.

[14]:
issubfield(K,L)
MethodError: no method matching issubfield(::AnticNumberField, ::NfAbsNS)
Closest candidates are:
  issubfield(::AnticNumberField, !Matched::AnticNumberField) at /home/taylor/.julia/packages/Hecke/SROq0/src/NumField/NfAbs/NfAbs.jl:466

Stacktrace:
 [1] top-level scope at In[14]:1
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

The above gives an error since we can not compare \(K\) and \(L\). But we can compare \(K\) and \(S\)!

[15]:
issubfield(K,S[1])
[15]:
(true, $\text{Map from }K\to \text{Number field over Rational field with defining polynomial }x^{8} - 40x^{6} + 352x^{4} - 960x^{2} + 576$)

Invariants and elements

Let’s recall the fields that we have defined so far.

[16]:
println(K)
println()
println(N[1])
println()
println(C)
println()
println(L)
println()
println(S[1])
Number field over Rational Field with defining polynomial x^2 - 2

Number field over Rational Field with defining polynomial x^8 - 21*x^6 + 84*x^4 - 105*x^2 + 25

(Cyclotomic field of order 3, z_3)

Non-simple number field with defining polynomials fmpq_mpoly[x1^2 - 2, x2^2 - 3, x3^2 - 5]

Number field over Rational Field with defining polynomial x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576

We compute the degree of each field, and find a generator. If the field is not a simple extension (in our case, the field \(L\)), we have to ask for gens instead of gen.

[17]:
for field in [K,N[1],C[1],L,S[1]]
    println(degree(field))
end
2
8
2
8
8
[18]:
gen(K)
[18]:
$a$
[19]:
gen(N[1])^8
[19]:
$21\alpha^{6} - 84\alpha^{4} + 105\alpha^{2} - 25$
[20]:
gen(C[1])
[20]:
$\zeta_{3}$
[21]:
gens(L)
[21]:
3-element Array{NfAbsNSElem,1}:
 _$1
 _$2
 _$3
[22]:
minpoly(a)
[22]:
$x^{2} - 2$
[23]:
println(gens(L) == b)
println(minpoly(b[1]))
println(minpoly(b[2]))
println(minpoly(b[3]))
println(minpoly(b[1]+b[2]+b[3]))
true
x^2 - 2
x^2 - 3
x^2 - 5
x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576

It is also easy to compute a basis.

[24]:
basis(K)
[24]:
[$1$, $a$]
[25]:
basis(N[1])
[25]:
[$1$, $\alpha$, $\alpha^{2}$, $\alpha^{3}$, $\alpha^{4}$, $\alpha^{5}$, $\alpha^{6}$, $\alpha^{7}$]
[26]:
[x^2 for x = basis(L)]
[26]:
8-element Array{NfAbsNSElem,1}:
 1
 2
 3
 6
 5
 10
 15
 30

Automorphisms and Galois groups

With ? we can ask what to do with a command.

[27]:
?automorphisms
search: automorphisms inner_automorphisms_group automorphism_group_generators

[27]:
automorphisms(G::GrpGen) -> A::Array{GrpGenToGrpGenMor,1}

Returns all group isomorphisms from \(G\) to \(G\).


automorphisms(K::AnticNumberField) -> Vector{NfToNfMor}

Returns the set of automorphisms of K


automorphisms(C::CyclotomicExt; gens::Vector{NfToNfMor}) -> Vector{NfToNfMor}

Computes the automorphisms of the absolute field defined by the cyclotomic extension, i.e. of absolute_field(C). It assumes that the base field is normal. gens must be a set of generators for the automorphism group of the base field of C

[28]:
automorphisms(K)
[28]:
[$\text{Map from }K\to K$, $\text{Map from }K\to K$]

This gives the number of automorphisms, but for the rest it is not very insightfull yet…. We get more information by asking how the automorphisms act on an element in the number field.

[29]:
automorphisms(K)[1](a)
[29]:
$a$
[30]:
automorphisms(K)[2](a)
[30]:
$-a$

Also here, we can not work with a non-simple extension.

[44]:
automorphisms(L)
MethodError: no method matching automorphisms(::NfAbsNS)
Closest candidates are:
  automorphisms(!Matched::CyclotomicExt; gens, copy) at /home/taylor/.julia/packages/Hecke/SROq0/src/RCF/cyclo.jl:397
  automorphisms(!Matched::AnticNumberField; copy) at /home/taylor/.julia/packages/Hecke/SROq0/src/Map/NumberField.jl:445
  automorphisms(!Matched::GrpGen) at /home/taylor/.julia/packages/Hecke/SROq0/src/Grp/Morphisms.jl:198
  ...

Stacktrace:
 [1] top-level scope at In[44]:1
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
[32]:
[f(gen(N[1])) for f in automorphisms(N[1])]
[32]:
[$\alpha$, $\frac{21}{50}\alpha^{7} - \frac{203}{25}\alpha^{5} + \frac{552}{25}\alpha^{3} - \frac{133}{10}\alpha$, $-\alpha$, $-\frac{21}{50}\alpha^{7} + \frac{203}{25}\alpha^{5} - \frac{552}{25}\alpha^{3} + \frac{133}{10}\alpha$, $-\frac{7}{20}\alpha^{7} + \frac{33}{5}\alpha^{5} - \frac{77}{5}\alpha^{3} + \frac{27}{4}\alpha$, $-\frac{53}{100}\alpha^{7} + \frac{252}{25}\alpha^{5} - \frac{618}{25}\alpha^{3} + \frac{189}{20}\alpha$, $\frac{7}{20}\alpha^{7} - \frac{33}{5}\alpha^{5} + \frac{77}{5}\alpha^{3} - \frac{27}{4}\alpha$, $\frac{53}{100}\alpha^{7} - \frac{252}{25}\alpha^{5} + \frac{618}{25}\alpha^{3} - \frac{189}{20}\alpha$]

There is more possible than what is found in the online documentation, look also in the examples in Oscar.jl! For example, we can compute the Galois group of a number field by first loading the example Oscar.example(“GaloisGrp.jl”).

[33]:
Oscar.example("GaloisGrp.jl")
#I  Getting PackageInfo URLs...
#I  Retrieving PackageInfo.g from https://gap-packages.github.io/ferret/PackageInfo.g ...
#I  The newest version of package "ferret" is already installed
[34]:
?galois_group
search: galois_group

[34]:

No documentation found.

Main.GaloisGrp.galois_group is a Function.

# 2 methods for generic function "galois_group":
[1] galois_group(K::AnticNumberField, extra::Int64) in Main.GaloisGrp at /home/taylor/.julia/packages/Oscar/YX0cd/examples/GaloisGrp.jl:508
[2] galois_group(K::AnticNumberField) in Main.GaloisGrp at /home/taylor/.julia/packages/Oscar/YX0cd/examples/GaloisGrp.jl:508

When computing a Galois group of a field extension, we get a group as well as some extra data.

[35]:
k = number_field(x^5-2)
[35]:
($\text{Number field over Rational field with defining polynomial }x^{5} - 2$, $\alpha$)
[36]:
Gal, C = galois_group(k[1])
[36]:
(Group([ (2,4,3,5), (2,3)(4,5), (1,2,4,5,3) ]), Galois Context for x^5 - 2 and prime 1048589)

The group is given in terms of permutations of the roots of the polynomial, which are approximated \(p\)-adically (in this case 1048589-adically). We can ask for these roots up to some precision.

[37]:
roots(C, 10)
[37]:
5-element Array{qadic,1}:
 (583730 + 787380*1048589^1 + 903235*1048589^2 + 589921*1048589^3 + 88635*1048589^4 + 403887*1048589^5 + 372677*1048589^6 + 951114*1048589^7 + 31719*1048589^8 + 433674*1048589^9 + O(1048589^10))
 (333313 + 332507*1048589^1 + 859848*1048589^2 + 615817*1048589^3 + 524847*1048589^4 + 916840*1048589^5 + 671321*1048589^6 + 644787*1048589^7 + 745453*1048589^8 + 565201*1048589^9 + O(1048589^10))*a + (655516 + 757137*1048589^1 + 763232*1048589^2 + 175390*1048589^3 + 891376*1048589^4 + 590715*1048589^5 + 82785*1048589^6 + 133145*1048589^7 + 740684*1048589^8 + 528669*1048589^9 + O(1048589^10))
 (715276 + 716081*1048589^1 + 188740*1048589^2 + 432771*1048589^3 + 523741*1048589^4 + 131748*1048589^5 + 377267*1048589^6 + 403801*1048589^7 + 303135*1048589^8 + 483387*1048589^9 + O(1048589^10))*a + (576975 + 770960*1048589^1 + 885101*1048589^2 + 715170*1048589^3 + 1046468*1048589^4 + 995006*1048589^5 + 506705*1048589^6 + 10382*1048589^7 + 95967*1048589^8 + 119635*1048589^9 + O(1048589^10))
 (641808 + 805075*1048589^1 + 492836*1048589^2 + 1037930*1048589^3 + 837771*1048589^4 + 918775*1048589^5 + 807900*1048589^6 + 1048190*1048589^7 + 219893*1048589^8 + 616621*1048589^9 + O(1048589^10))*a + (419477 + 566070*1048589^1 + 1022543*1048589^2 + 853783*1048589^3 + 877045*1048589^4 + 994949*1048589^5 + 642986*1048589^6 + 200223*1048589^7 + 728044*1048589^8 + 685727*1048589^9 + O(1048589^10))
 (406781 + 243513*1048589^1 + 555752*1048589^2 + 10658*1048589^3 + 210817*1048589^4 + 129813*1048589^5 + 240688*1048589^6 + 398*1048589^7 + 828695*1048589^8 + 431967*1048589^9 + O(1048589^10))*a + (910069 + 264217*1048589^1 + 620242*1048589^2 + 811499*1048589^3 + 242240*1048589^4 + 161207*1048589^5 + 492022*1048589^6 + 802312*1048589^7 + 500762*1048589^8 + 329471*1048589^9 + O(1048589^10))

The Galois group has 3 generators. But there is only one field automorphism of \(k\)!

[38]:
automorphisms(k[1])
[38]:
[$\text{Map from }\text{Number field over Rational field with defining polynomial }x^{5} - 2\to \text{Number field over Rational field with defining polynomial }x^{5} - 2$]

This is because the field extension is not normal, so OSCAR computed the Galois group of the splitting field of the polynomial. Let’s check that this is indeed the case.

[39]:
galois_group(splitting_field(x^5-2))
[39]:
(Group([ (1,16,8,20)(2,13,4,18)(3,15,5,11)(6,17,10,19)(7,14,9,12), (1,8)(2,4)(3,5)(6,10)(7,9)(11,15)(12,14)(13,18)(16,20)(17,19), (1,5,7,4,10)(2,9,3,8,6)(11,18,16,14,19)(12,20,13,15,17) ]), Galois Context for x^20 + 156*x^15 + 39376*x^10 + 421776*x^5 + 2576816 and prime 1048589)
[40]:
isisomorphic(ans[1], galois_group(k[1])[1])
[40]:
(true, Group homomorphism from Group([ (1,16,8,20)(2,13,4,18)(3,15,5,11)(6,17,10,19)(7,14,9,12), (1,8)(2,4)(3,5)(6,10)(7,9)(11,15)(12,14)(13,18)(16,20)(17,19), (1,5,7,4,10)(2,9,3,8,6)(11,18,16,14,19)(12,20,13,15,17) ]) to Group([ (2,4,3,5), (2,3)(4,5), (1,2,4,5,3) ]) )

Of course, when the field extension is a Galois extension, the Galois group is equal to the automorphism group.

[41]:
N
[41]:
($\text{Number field over Rational field with defining polynomial }x^{8} - 21x^{6} + 84x^{4} - 105x^{2} + 25$, $\alpha$)
[42]:
G = galois_group(N[1])

[42]:
(Group([ (), (1,7)(2,6)(3,5)(4,8), (1,8,3,6)(2,5,4,7) ]), Galois Context for x^8 - 21*x^6 + 84*x^4 - 105*x^2 + 25 and prime 1048583)

How can we find out which group this is? We are lucky that we are working in OSCAR, and can ask our group specialist (i.e. Mima)! She told us to just give her an id of the group, and the rest will be taken care of.

[43]:
small_group_identification(G[1])
[43]:
($8$, $3$)