Skip to content

Class Field Theory

This section deals with abelian extensions of number fields and abelian extensions of the rational numbers in particular.

In Hecke, abelian extensions are parametrized by quotients of ray class groups. The use of ray class groups is particularly amenable to computational algorithms.

Ray Class Groups

Let K be a number field. Given an integral ideal m0OK of the ring of integers OK, and a list of real places m, the ray class group modulo m=(m0,m) is defined as the group Clm of fractional ideals coprime to m0 modulo the principal ideals generated by elements aK such that

vp(a1)vp(m0) for all prime ideals pm0.

and also

a(v)>0 for al places vm.

Here we write a(v) for the image of a under embedding corresponding to the place v.

This is a finite abelian group, cf. [2] (Theorem 1.7, Chapter V).

For m0=OK and m= the empty list, we get a ray class group Cl that is simply the class group of K. If m0=OK and m contains all real places, we obtain the narrow class group, or strict class group, of K.

ray_class_group Method
julia
ray_class_group(m::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}; n_quo::Int, lp::Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}) -> FinGenAbGroup, MapRayClassGrp

Given an ideal m and a set of infinite places of K, this function returns the corresponding ray class group as an abstract group Clm and a map going from the group into the group of ideals of K that are coprime to m. If n_quo is set, it will return the group modulo n_quo. The factorization of m can be given with the keyword argument lp.

source
class_group Method
julia
class_group(K::AbsSimpleNumField) -> FinGenAbGroup, Map

Shortcut for class_group(maximal_order(K)): returns the class group as an abelian group and a map from this group to the set of ideals of the maximal order.

source
norm_group Method
julia
norm_group(f::Nemo.PolyRingElem, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

norm_group(f::Array{PolyRingElem{AbsSimpleNumFieldElem}}, mR::Hecke.MapRayClassGrp, is_abelian::Bool = true; of_closure::Bool = false) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

Computes the subgroup of the Ray Class Group R given by the norm of the extension generated by a/the roots of f. If is_abelian is set to true, then the code assumes the field to be abelian, hence the algorithm stops when the quotient by the norm group has the correct order. Even though the algorithm is probabilistic by nature, in this case the result is guaranteed. If of_closure is given, then the norm group of the splitting field of the polynomial(s) is computed. It is the callers responsibility to ensure that the ray class group passed in is large enough.

source
norm_group Method
julia
norm_group(K::RelSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

norm_group(K::RelNonSimpleNumField{AbsSimpleNumFieldElem}, mR::Hecke.MapRayClassGrp) -> Hecke.FinGenGrpAb, Hecke.FinGenGrpAbMap

Computes the subgroup of the Ray Class Group R given by the norm of the extension.

source

Ray Class Fields

Each quotient of a ray class group defines a ray class field L/K. The defining property of a ray class field L/K is that the (relative over K) automorphism group is canonically isomorphic to the quotient of the ray class group via the Artin (or Frobenius) map.

Since, in Hecke, the ray class groups of K have no link to the field K itself, constructing ray class fields has to be specified using the associated maps.

Info

It should be noted that the following are lazy functions that return formal objects of type ClassField. Nothing is computed at this point.

ray_class_field Method
julia
ray_class_field(m::MapClassGrp) -> ClassField
ray_class_field(m::MapRayClassGrp) -> ClassField

Creates the (formal) abelian extension defined by the map m:AI where I is the set of ideals coprime to the modulus defining m and A is a quotient of the ray class group (or class group). The map m must be the map returned from a call to {class_group} or {ray_class_group}.

source
ray_class_field Method
julia
ray_class_field(m::Union{MapClassGrp, MapRayClassGrp}, quomap::FinGenAbGroupHom) -> ClassField

For m a map computed by either {ray_class_group} or {class_group} and q a canonical projection (quotient map) as returned by {quo} for q quotient of the domain of m and a subgroup of m, create the (formal) abelian extension where the (relative) automorphism group is canonically isomorphic to the codomain of q.

source
ray_class_field Method
julia
ray_class_field(I::AbsNumFieldOrderIdeal; n_quo = 0) -> ClassField

The ray class field modulo I. If n_quo is given, then the largest subfield of exponent n is computed.

source
ray_class_field Method
julia
ray_class_field(I::AbsNumFieldOrderIdeal, inf::Vector{InfPlc}; n_quo = 0) -> ClassField

The ray class field modulo I and the infinite places given. If n_quo is given, then the largest subfield of exponent n is computed.

source
hilbert_class_field Method
julia
hilbert_class_field(k::AbsSimpleNumField) -> ClassField

The Hilbert class field of k as a formal (ray-) class field.

source
ring_class_field Method
julia
ring_class_field(O::AbsNumFieldOrder) -> ClassField

The ring class field of O, i.e. the maximal abelian extension ramified only at primes dividing the conductor with the automorphism group isomorphic to the Picard group.

source
cyclotomic_field Method
julia
cyclotomic_field(::Type{ClassField}, n::Int) -> ClassField

The n-th cyclotomic field as a ray_class_field

source

Example

Here we give an example constructing the class field object of the number field Q(10).

julia
julia> Qx, x = polynomial_ring(QQ, :x);

julia> K, a = number_field(x^2 - 10, :a);

julia> c, mc = class_group(K)
(Z/2, Class group map of set of ideals of O_K)

julia> A = ray_class_field(mc)
Class field
  over number field with defining polynomial x^2 - 10
    over rational field
with modulus
  finite part <1>
  infinite part
    []
with structure
  Z/2

Conversions

Given a ray class field, it's possible to compute defining equation(s) for this field. The number field constructed this way will be non-simple and defined by one polynomial for each maximal cyclic quotient of prime power order in the defining group.

number_field Method
julia
number_field(CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

Given a (formal) abelian extension, compute the class field by finding defining polynomials for all prime power cyclic subfields.

Note, the return type is always a non-simple extension.

source
julia
number_field(AbsSimpleNumField, CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

Given a (formal) abelian extension, compute the class field by finding an absolute primitive element thus return a simple extension of Q.

source
julia
number_field(SimpleNumField, CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

Given a (formal) abelian extension, compute the class field by finding an primitive element over the base field of the class field, thus return a simple extension of the base field.

source
number_field Method
julia
number_field(SimpleNumField, CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

Given a (formal) abelian extension, compute the class field by finding an primitive element over the base field of the class field, thus return a simple extension of the base field.

source
number_field Method
julia
number_field(AbsSimpleNumField, CF::ClassField) -> RelNonSimpleNumField{AbsSimpleNumFieldElem}

Given a (formal) abelian extension, compute the class field by finding an absolute primitive element thus return a simple extension of Q.

source
julia
julia> Qx, x = polynomial_ring(QQ, :x);

julia> k, a = number_field(x^2 - 10, :a);

julia> c, mc = class_group(k);

julia> A = ray_class_field(mc)
Class field
  over number field with defining polynomial x^2 - 10
    over rational field
with modulus
  finite part <1>
  infinite part
    []
with structure
  Z/2

julia> K = number_field(A)
Relative non-simple number field with defining polynomials [x^2 - 2]
  over number field with defining polynomial x^2 - 10
    over rational field

julia> ZK = maximal_order(K)
Maximal order
  of relative non-simple number field with defining polynomials [x^2 - 2]
    over number field of degree 2 over QQ
with pseudo-basis
  (1, <1, 1>//1)
  (_$1 + a, <2, a>//4)

julia> isone(discriminant(ZK))
true

Tip

The algorithm employed is based on Kummer-theory and requires the addition of a suitable root of unity.

Computation progress can be monitored by setting set_verbose_level(:ClassField, n) where 0n3.

ray_class_field Method
julia
ray_class_field(K::RelSimpleNumField{AbsSimpleNumFieldElem}) -> ClassField
ray_class_field(K::AbsSimpleNumField) -> ClassField

For a (relative) abelian extension, compute an abstract representation as a class field.

source
genus_field Method
julia
genus_field(A::ClassField, k::AbsSimpleNumField) -> ClassField

The maximal extension contained in A that is the compositum of K with an abelian extension of k.

source
maximal_abelian_subfield Method
julia
maximal_abelian_subfield(A::ClassField, k::AbsSimpleNumField) -> ClassField

The maximal abelian extension of k contained in A. k must be a subfield of the base field of A.

source
maximal_abelian_subfield Method
julia
maximal_abelian_subfield(K::RelSimpleNumField{AbsSimpleNumFieldElem}; of_closure::Bool = false) -> ClassField

Using a probabilistic algorithm for the norm group computation, determine the maximal abelian subfield in K over its base field. If of_closure is set to true, then the algorithm is applied to the normal closure of K (without computing it).

source
decomposition_field Method
julia
decomposition_field(C::ClassField, p::[InfPlc | AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}]) -> ClassField

Compute the decomposition field, ie. the field fixed by the decomposition group as a class field.

source
inertia_field Method
julia
inertia_field(C::ClassField, p::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}) -> ClassField

Compute the inertia field, ie. the field fixed by the decomposition group as a class field.

source
fixed_field Method
julia
fixed_field(A::ClassField, U::FinGenAbGroup)

For a subgroup U of the norm group of A, return the class field fixed by U, ie. norm group the quotient by U.

source
grunwald_wang Method
julia
grunwald_wang(dp::Dict{<:NumFieldOrderIdeal, Int})
grunwald_wang(dp::Dict{<:NumFieldOrderIdeal, Int}, di::Dict{<:NumFieldEmb, Int})

For a collection of places given via ideals as keys of dp and embeddings given as keys of di find a cyclic extension where the completions at the places have the degrees as the values of the dictionaries.

The degree will be the lcm of the local degree (values), the extension will be unramified at the places in dp unless they involve primes above 2.

The field will be constructed as a ray_class_field.

EXAMPLES

julia
julia> A = grunwald_wang(Dict(3*ZZ => 3, 5*ZZ => 2))
Class field defined mod (<13, 13>, InfPlc{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}[]) of structure Abelian group with structure: Z/6

julia> K = absolute_simple_field(number_field(A))[1];

julia> prime_decomposition_type(maximal_order(K), 5)
3-element Vector{Tuple{Int64, Int64}}:
 (2, 1)
 (2, 1)
 (2, 1)


julia> prime_decomposition_type(maximal_order(K), 3)
2-element Vector{Tuple{Int64, Int64}}:
 (3, 1)
 (3, 1)
source
cyclotomic_extension Method
julia
cyclotomic_extension(k::ClassField, n::Int) -> ClassField

Computes k(ζn), as a class field, as an extension of the same base field.

source
cyclotomic_extension Method
julia
cyclotomic_extension(ClassField, k::AbsSimpleNumField, n::Int) -> ClassField

Computes k(ζn), as a class field, as an extension of the same base field.

source

Invariants

degree Method
julia
degree(A::ClassField)

The degree of A over its base field, i.e. the size of the defining ideal group.

source
exponent Method
julia
exponent(A::ClassField)

The exponent of A over its base field, i.e. the exponent of the Galois group of the extension.

source
base_ring Method
julia
base_ring(A::ClassField)

The maximal order of the field that A is defined over.

source
base_field Method
julia
base_field(A::ClassField)

The number field that A is defined over.

source
discriminant Method
julia
discriminant(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}

Using the conductor-discriminant formula, compute the (relative) discriminant of C. This does not use the defining equations.

source
conductor Method
julia
conductor(C::ClassField) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Vector{InfPlc}

Return the conductor of the abelian extension corresponding to C.

source
signature Method
julia
signature(C::ClassField) -> Int, Int

Return the signature of the number field defined by C.

source
defining_modulus Method
julia
defining_modulus(CF::ClassField)

The modulus, i.e. an ideal of the set of real places, used to create the class field.

source
is_cyclic Method
julia
is_cyclic(C::ClassField)

Tests if the (relative) automorphism group of C is cyclic (by checking the defining ideal group).

source
is_conductor Method
julia
is_conductor(C::Hecke.ClassField, m::AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, inf_plc::Vector{InfPlc}=InfPlc[]; check) -> AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Vector{InfPlc}

Checks if (m, inf_plc) is the conductor of the abelian extension corresponding to C. If check is false, it assumes that the given modulus is a multiple of the conductor. This is usually faster than computing the conductor.

source
is_normal Method
julia
is_normal(C::ClassField) -> Bool

For a class field C defined over a normal base field k, decide if C is normal over Q.

source
is_central Method
julia
is_central(C::ClassField) -> Bool

For a class field C defined over a normal base field k, decide if C is central over Q.

source
automorphism_group Method
julia
automorphism_group(C::ClassField)

The group of automorphisms fixing the base field, returned as an abstract abelian group and a map from the group into the automorphisms. This map admits a pointwise pre-image.

source
absolute_automorphism_group Method
julia
absolute_automorphism_group(C::ClassField)

Computes a generating set for the automorphisms of the number field corresponding to C. It assumes that the base field is normal. If "check" is true, the function checks if the extension is normal.

source
decomposition_group Method
julia
decomposition_group(C::ClassField, p::[InfPlc | AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}]) -> FinGenAbGroup

Compute the decomposition group of any infinite place or prime ideal of the base field (ring) as a subgroup of the norm group.

source
frobenius_map Method
julia
frobenius_map(C::ClassField)
artin_map(C::ClassField)

Compute the map linking unramified ideals onto the automorphisms under the Artin-Frobenius map.

source
complex_conjugation Method
julia
complex_conjugation(C::ClassField, p::InfPlc)

Given an infinite place p ramifying in C, return the automorphism of number_field(C), which induces complex conjugation on the complex embeddings extending p.

julia
julia> K, = quadratic_field(21);

julia> OK = maximal_order(K);

julia> C = ray_class_field(6 * OK, real_places(K));

julia> complex_conjugation(C, real_places(K)[1]);
source

Operations

* Method
julia
*(A::ClassField, B::ClassField) -> ClassField

The compositum of a and b as a (formal) class field.

source
compositum Method
julia
compositum(a::ClassField, b::ClassField) -> ClassField

The compositum of a and b as a (formal) class field.

source
== Method
julia
==(a::ClassField, b::ClassField)

Tests if a and b are equal.

source
intersect Method
julia
intersect(a::ClassField, b::ClassField) -> ClassField

The intersection of a and b as a class field.

source
prime_decomposition_type Method
julia
prime_decomposition_type(C::ClassField, p::AbsNumFieldOrderIdeal) -> (Int, Int, Int)

For a prime p in the base ring of r, determine the splitting type of p in r. ie. the tuple (e,f,g) giving the ramification degree, the inertia and the number of primes above p.

source
is_subfield Method
julia
is_subfield(a::ClassField, b::ClassField) -> Bool

Determines if a is a subfield of b.

source
is_local_norm Method
julia
is_local_norm(r::ClassField, a::AbsNumFieldOrderElem) -> Bool

Tests if a is a local norm at all finite places in the extension implicitly given by r.

source
is_local_norm Method
julia
is_local_norm(r::ClassField, a::AbsNumFieldOrderElem, p::AbsNumFieldOrderIdeal) -> Bool

Tests if a is a local norm at p in the extension implicitly given by r. Currently the conductor cannot have infinite places.

source
normal_closure Method
julia
normal_closure(C::ClassField) -> ClassField

For a ray class field C extending a normal base field k, compute the normal closure over Q.

source
subfields Method
julia
subfields(C::ClassField; degree::Int, is_normal, type) -> Vector{ClassField}

Find all subfields of C over the base field.

If the optional keyword argument degree is positive, then only those with prescribed degree will be returned.

If the optional keyword is_normal is given, then only those that are normal over the field fixed by the automorphisms is returned. For normal base fields, this amounts to extensions that are normal over Q.

If the optional keyword is_normal is set to a list of automorphisms, then only those wil be considered.

type can be set to the desired relative Galois group, given as a vector of integers describing the structure.

Note

This will not find all subfields over Q, but only the ones sharing the same base field.

source