Skip to content

Commit

Permalink
feat: improve locally free class group (thofma#1573)
Browse files Browse the repository at this point in the history
- compute the idempotents in the center
  • Loading branch information
thofma authored Aug 7, 2024
1 parent 8693382 commit e593146
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
17 changes: 16 additions & 1 deletion src/AlgAssAbsOrd/LocallyFreeClassGroup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,22 @@ function K1_order_mod_conductor(O::AlgAssAbsOrd, OA::AlgAssAbsOrd, F::AlgAssAbsO
end
# Make the generators coprime to the other ideals
if length(moduli) != 0 # maybe O is maximal
k1 = make_coprime(elements_for_crt, moduli)
# we compute the idempotents using the ideals in the center
# and map them to the order
# this is faster than computing the idempotents in the order itself
if length(moduli) >= 2
idemZ = _idempotents_for_make_coprime([q * OinZ for (q,_) in prim])
idems = [O(ZtoA(elem_in_algebra.(x))) for x in idemZ]
for i in 1:length(idems)
u = idems[i]
@assert u in moduli[i]
@assert all(1 - u in moduli[j] for j in 1:length(moduli) if j != i)
end
else
# only one moduli, so no idempotent
idems = elem_type(O)[]
end
k1 = make_coprime(elements_for_crt, moduli, idems)
else
k1 = elem_type(O)[]
end
Expand Down
34 changes: 29 additions & 5 deletions src/NumFieldOrd/NfOrd/ResidueRingMultGrp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1170,9 +1170,20 @@ end
#
################################################################################

function _idempotents_for_make_coprime(ideals)
products = _compute_products_for_make_coprime(ideals)
n = length(ideals)
res = elem_type(order_type(algebra(ideals[1])))[]
for i = 1:n
u, v = idempotents(ideals[i], products[i])
push!(res, u)
end
return res
end

# For an element x of elements[i] this computes an element y with
# x \equiv y mod ideals[i] and x \equiv 1 mod ideals[j] for all j not equal i.
function make_coprime(elements::Vector{Vector{S}}, ideals::Vector{T}) where { S <: Union{ AbsNumFieldOrderElem, AlgAssAbsOrdElem }, T <: Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl } }
function make_coprime(elements::Vector{Vector{S}}, ideals::Vector{T}, idempotents::Vector{S}) where { S <: Union{ AbsNumFieldOrderElem, AlgAssAbsOrdElem }, T <: Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl } }
@assert !isempty(ideals)
@assert length(elements) == length(ideals)

Expand All @@ -1181,20 +1192,33 @@ function make_coprime(elements::Vector{Vector{S}}, ideals::Vector{T}) where { S
return elements[1]
end

products = _compute_products_for_make_coprime(ideals)

One = one(order(ideals[1]))
result = Vector{S}()
for i = 1:n
u, v = idempotents(ideals[i], products[i])
u = idempotents[i]

for j = 1:length(elements[i])
t = elements[i][j] * v + One * u
t = elements[i][j] * (1 - u) + One * u
push!(result, t)
end
end
return result
end

function make_coprime(elements::Vector{Vector{S}}, ideals::Vector{T}) where { S <: Union{ AbsNumFieldOrderElem, AlgAssAbsOrdElem }, T <: Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl } }
@assert !isempty(ideals)
@assert length(elements) == length(ideals)

n = length(ideals)
if n == 1
return elements[1]
end

idempotents = _idempotents_for_make_coprime(ideals)

return make_coprime(elements, ideals, idempotents)
end

# Build the products \prod_{j\neq i} ideals[j] for all i
function _compute_products_for_make_coprime(ideals::Vector{T}) where { T <: Union{ AbsNumFieldOrderIdeal, AlgAssAbsOrdIdl } }
n = length(ideals)
Expand Down

0 comments on commit e593146

Please sign in to comment.