Skip to content

Commit

Permalink
fix: extend abelian_extension for number fields
Browse files Browse the repository at this point in the history
- allow to provide conductors
- fix handling of implicit maximal order
  • Loading branch information
thofma committed May 2, 2024
1 parent b762834 commit 626bd92
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
43 changes: 32 additions & 11 deletions src/FieldFactory/ab_exts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,15 @@ function abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
absolutely_distinct::Bool = false,
ramified_at_inf_plc::Tuple{Bool, Vector{<: InfPlc}} = (false, InfPlc{AbsSimpleNumField, AbsSimpleNumFieldEmbedding}[]),
only_tame::Bool = false,
signatures::Vector{Tuple{Int, Int}} = Tuple{Int, Int}[])
signatures::Vector{Tuple{Int, Int}} = Tuple{Int, Int}[],
conductors = nothing)

if length(signatures) == 0
return _abelian_extensions(K, gtype, absolute_discriminant_bound,
absolutely_distinct = absolutely_distinct,
ramified_at_inf_plc = ramified_at_inf_plc,
only_tame = only_tame)
only_tame = only_tame,
conductors = conductors)
else
if ramified_at_inf_plc[1]
error("Cannot specify ramified place and target signatures simultaneously")
Expand Down Expand Up @@ -270,7 +272,8 @@ function abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
more_fields = _abelian_extensions(K, gtype, absolute_discriminant_bound,
absolutely_distinct = absolutely_distinct,
ramified_at_inf_plc = (true, rlp_ramify),
only_tame = only_tame)
only_tame = only_tame,
conductors = conductors)
for L in more_fields
@assert signature(L) == (R, S)
end
Expand All @@ -285,19 +288,39 @@ function _abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
absolute_discriminant_bound::ZZRingElem;
absolutely_distinct::Bool = false,
ramified_at_inf_plc::Tuple{Bool, Vector{<: InfPlc}} = (false, InfPlc[]),
only_tame::Bool = false)
only_tame::Bool = false,
conductors = nothing)

OK = maximal_order(K)
# quick check
OK = lll(maximal_order(K))
gtype = map(Int, snf(abelian_group(gtype))[1].snf)
n = prod(gtype)
inf_plc = InfPlc[]

fields = ClassField{MapRayClassGrp, FinGenAbGroupHom}[]
bound = div(absolute_discriminant_bound, abs(discriminant(OK))^n)
if iszero(bound)
return fields
end

# TODO: better preprocessing of custom conductors
# what to allow? lists of ideals, lists of factorizations, ...
#
# #Getting conductors first, because we also extrat the maximal order
if conductors === nothing
@vprintln :AbExt 1 "Computing conductors"
l_conductors = conductors_generic(K, gtype, absolute_discriminant_bound, only_tame = only_tame)
else
@vprintln :AbExt 1 "Conductors provided"
if conductors isa Vector{<:Dict}
l_conductors = conductors
else
@assert conductors isa Vector{ideal_type(OK)}
l_conductors = [factor(I) for I in conductors]
end
if !isempty(first(l_conductors))
OK = order(first(keys(first(l_conductors))))
end
end

inf_plc = real_places(K)
if ramified_at_inf_plc[1]
inf_plc = ramified_at_inf_plc[2]
Expand All @@ -313,8 +336,7 @@ function _abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
cgrp = !is_coprime(n, order(Cl))
allow_cache!(mCl)

#Getting conductors
l_conductors = conductors_generic(K, gtype, absolute_discriminant_bound, only_tame = only_tame)

if absolutely_distinct
l_conductors = _sieve_conjugates(auts, l_conductors)
end
Expand All @@ -326,7 +348,7 @@ function _abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
#Now, the big loop
for (i, k) in enumerate(l_conductors)
if i % 10000 == 0
@vprintln :AbExt 1 "Left: $(length(l_conductors) - i)"
@vprintln :AbExt 1 "Conductors left: $(length(l_conductors) - i) (fields found: $(length(fields)))"
end
r, mr = ray_class_group_quo(OK, k, inf_plc, ctx)
if !has_quotient(r, gtype)
Expand Down Expand Up @@ -368,7 +390,6 @@ function _abelian_extensions(K::AbsSimpleNumField, gtype::Vector{Int},
end
end
if cC[1] == mr.defining_modulus[1] && norm(discriminant(C)) <= bound
@vprintln :AbExt 1 "New Field"
push!(new_fields, C)
end
end
Expand Down
12 changes: 9 additions & 3 deletions src/FieldFactory/conductors_generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,15 @@ end


function conductors_generic(K::AbsSimpleNumField, gtype::Vector{Int}, absolute_bound::ZZRingElem; only_tame::Bool = false)
return conductors_generic(lll(maximal_order(K)), gtype, absolute_bound; only_tame = only_tame)
end

function conductors_generic(OK::AbsSimpleNumFieldOrder, gtype::Vector{Int}, absolute_bound::ZZRingElem; only_tame::Bool = false)
#I am assuming that gtype is in "SNF"
conds_tame = conductors_generic_tame(K, gtype, absolute_bound)
conds_tame = conductors_generic_tame(OK, gtype, absolute_bound)
if only_tame
return Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}[(x[1], Dict{AbsNumFieldOrderIdeal{AbsSimpleNumField, AbsSimpleNumFieldElem}, Int}()) for x in conds_tame]
end
OK = maximal_order(K)
wild = collect(keys(factor(gtype[end]).fac))
n = prod(gtype)
bound = div(absolute_bound, abs(discriminant(OK))^n)
Expand Down Expand Up @@ -670,7 +673,10 @@ function conductors_generic(K::AbsSimpleNumField, gtype::Vector{Int}, absolute_b
end

function conductors_generic_tame(K::AbsSimpleNumField, gtype::Vector{Int}, absolute_bound::ZZRingElem)
OK = maximal_order(K)
return conductors_generic_tame(lll(maximal_order(K), gtype, absolute_bound))
end

function conductors_generic_tame(OK::AbsSimpleNumFieldOrder, gtype::Vector{Int}, absolute_bound::ZZRingElem)
n = prod(gtype)
wild = collect(keys(factor(n).fac))
pmin = Int(minimum(wild))
Expand Down
21 changes: 21 additions & 0 deletions test/RCF/rcf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,24 @@ end
l = abelian_extensions([2], collect(1:10^3))
@test length(l) == 607
end

let
Qx, x = QQ["x"]
K, a = rationals_as_number_field()
all_fields = abelian_extensions(K, [2], ZZRingElem(10)^3, absolutely_distinct = true)
OK = maximal_order(K)
lp = prime_ideals_up_to(OK, 10^3)
prime_cond = abelian_extensions(K, [2], ZZRingElem(10)^3, absolutely_distinct = true, conductors = lp)
@test length(prime_cond) == count(is_prime.(first.(conductor.(all_fields))))

# with target signatures
K, a = number_field(x^3 - x^2 - 2*x + 1, cached = false)
l = abelian_extensions(K, [2, 2], ZZRingElem(10)^12)
conds = Hecke.conductors_generic(K, [2, 2], ZZ(10)^12)
l = abelian_extensions(K, [2, 2], ZZRingElem(10)^12)
ll = abelian_extensions(K, [2, 2], ZZRingElem(10)^12, conductors = conds)
@test length(l) == length(ll)
l1 = abelian_extensions(K, [2, 2], ZZRingElem(10)^12, signatures = [(4, 4)])
ll1 = abelian_extensions(K, [2, 2], ZZRingElem(10)^12, signatures = [(4, 4)], conductors = conds)
@test length(l1) == length(ll1)
end

0 comments on commit 626bd92

Please sign in to comment.