From 50b081ea620eab2ea7c1788e71b8d472a0b05c04 Mon Sep 17 00:00:00 2001 From: Claus Fieker Date: Wed, 11 Dec 2024 19:48:56 +0100 Subject: [PATCH] fix galois_group problem. (#4396) The previous last fix changed the order in which the factors were processed - this broke unfortunately that part in the end that adds the multiplicity back in. The current version is not perfect (unneccessary computations are done) but fixes the problem --- src/NumberTheory/GaloisGrp/GaloisGrp.jl | 50 ++++++++++++++++++++----- test/NumberTheory/galthy.jl | 15 +++++++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/NumberTheory/GaloisGrp/GaloisGrp.jl b/src/NumberTheory/GaloisGrp/GaloisGrp.jl index 330058711174..26e7d3f9d5ac 100644 --- a/src/NumberTheory/GaloisGrp/GaloisGrp.jl +++ b/src/NumberTheory/GaloisGrp/GaloisGrp.jl @@ -2667,6 +2667,10 @@ function Hecke.absolute_minpoly(a::Oscar.NfNSGenElem{QQFieldElem, QQMPolyRingEle end function blow_up(G::PermGroup, C::GaloisCtx, lf::Vector, con::PermGroupElem=one(G)) + #TODO: currently con is useless here, the cluster detection and the reduce + # tree is re-arranging the factors in lf randomly + # one would need to trace the re-arranged lf as well + # Since we don't, we have to compute roots and evaluate if all(x->x[2] == 1, lf) return G, C @@ -2678,28 +2682,53 @@ function blow_up(G::PermGroup, C::GaloisCtx, lf::Vector, con::PermGroupElem=one( icon = inv(con) - gs = map(Vector{Int}, gens(G)) + rr = roots(C, 2; raw = true) + renum = Int[] for (g, k) = lf + l = findall(iszero, map(g, rr)) + append!(renum, l) + end + re = inv(symmetric_group(degree(G))(renum)) + + gs = map(Vector{Int}, gens(G)) + + # G is a sub group of prod G_i <= prod sym(n_i) the galois groups + # of the factors + # con describes the current ordering of the roots in so G^con <= prod G_i + #for the factors with multiplicity > 1, we need to append more factors + H = [G] + mps = [gens(G)] + n = degree(G) + for (g,k) = lf + if k == 1 + st += degree(g) + continue + end + S = symmetric_group(degree(g)) + #need proj G -> G_i, so need a subset of the points (st+1:st+deg(g)) + # moved by re, then mapped to 1:deg(g) + h = [S([(i+st)^(gg^re)-st for i=1:degree(g)]) for gg = gens(G)] for j=2:k - for i=1:degree(g) - mp[n+i] = (st+i)^con - end - for h = gs - for i=1:degree(g) - push!(h, h[(st+i)^con]^icon-st+n) - end + S = symmetric_group(degree(g)) + push!(H, S) + push!(mps, h) + for i = 1:degree(g) + mp[n+i] = (st+i)^icon end n += degree(g) end st += degree(g) end + D, emb, pro = inner_direct_product(H; morphisms = true) + h = hom(G, D, [prod(emb[i](mps[i][j]) for i=1:length(H)) for j=1:ngens(G)]) + C.rt_num = mp - S = symmetric_group(n) - GG, _ = sub(S, map(S, gs)) + GG, _ = image(h) h = hom(G, GG, gens(G), gens(GG)) @assert is_injective(h) && is_surjective(h) + C.G = GG return GG, C end @@ -2825,6 +2854,7 @@ function galois_group(f::PolyRingElem{<:FieldElem}; prime=0, pStart::Int = 2*deg @vprint :GaloisGroup 1 "found $(length(cl)) connected components\n" res = Vector{Tuple{typeof(C[1]), PermGroupElem}}() + llf = Int[] function setup(C::Vector{<:GaloisCtx}) G, emb, pro = inner_direct_product([x.G for x = C], morphisms = true) g = prod(x.f for x = C) diff --git a/test/NumberTheory/galthy.jl b/test/NumberTheory/galthy.jl index c776f5384e97..fb8e9a78f97e 100644 --- a/test/NumberTheory/galthy.jl +++ b/test/NumberTheory/galthy.jl @@ -10,7 +10,7 @@ @test degree(L) == order(G) @test length(roots(L, k.pol)) == 5 - R, x = polynomial_ring(QQ, :x) + R, x = polynomial_ring(QQ, :x; cached = false) pol = x^6 - 366*x^4 - 878*x^3 + 4329*x^2 + 14874*x + 10471 g, C = galois_group(pol) @test order(g) == 18 @@ -24,7 +24,7 @@ G, C = galois_group((1//13)*x^2+2) @test order(G) == 2 - K, a = number_field(x^4-2) + K, a = number_field(x^4-2; cached = false) G, C = galois_group(K) Gc, Cc = galois_group(K, algorithm = :Complex) Gs, Cs = galois_group(K, algorithm = :Symbolic) @@ -46,6 +46,17 @@ G, C = galois_group((2*x+1)^2) @test order(G) == 1 @test degree(G) == 2 + + #from errors: + G, C = galois_group((x^4 + 1)^3 * x^2 * (x^2 - 4*x + 1)^5) + @test order(G) == 8 + @test degree(G) == 24 + k = fixed_field(C, sub(G, [one(G)])[1]) + @test degree(k) == 8 + + G, C = galois_group((x^3-2)^2*(x^3-5)^2*(x^2-6)) + @test order(G) == 36 + @test degree(G) == 14 end import Oscar.GaloisGrp: primitive_by_shape, an_sn_by_shape, cycle_structures