[1]:
using Oscar
----- ----- ----- - -----
| | | | | | | | | |
| | | | | | | |
| | ----- | | | |-----
| | | | |-----| | |
| | | | | | | | | |
----- ----- ----- - - - -
...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]:
[3]:
K, a = NumberField(x^2 - 2, "a")
[3]:
\(a\) is the class of \(x\) in \(\mathbb{Q}[x]/(x^2-2)\):
[4]:
a^2
[4]:
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]:
[6]:
N[2]^8
[6]:
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]:
[9]:
isisomorphic(C[1],C2[1])
[9]:
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]:
[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]:
It is generated by a polynomial of degree 8. Could it be isomorphic to N?
[13]:
isisomorphic(S[1],N[1])
[13]:
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]:
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]:
[19]:
gen(N[1])^8
[19]:
[20]:
gen(C[1])
[20]:
[21]:
gens(L)
[21]:
3-element Array{NfAbsNSElem,1}:
_$1
_$2
_$3
[22]:
minpoly(a)
[22]:
[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]:
[25]:
basis(N[1])
[25]:
[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]:
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]:
[30]:
automorphisms(K)[2](a)
[30]:
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]:
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]:
[36]:
Gal, C = galois_group(k[1])
[36]:
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]:
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]:
[40]:
isisomorphic(ans[1], galois_group(k[1])[1])
[40]:
Of course, when the field extension is a Galois extension, the Galois group is equal to the automorphism group.
[41]:
N
[41]:
[42]:
G = galois_group(N[1])
[42]:
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]: