From e6579c36ffc51f46d027b1186a58183b1c21b2aa Mon Sep 17 00:00:00 2001 From: Claus Fieker Date: Tue, 15 Jul 2025 10:35:37 +0200 Subject: [PATCH] bug in galois groups --- src/NumberTheory/GaloisGrp/GaloisGrp.jl | 55 +++++++++++++++++++++++-- test/NumberTheory/galthy.jl | 4 ++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/NumberTheory/GaloisGrp/GaloisGrp.jl b/src/NumberTheory/GaloisGrp/GaloisGrp.jl index 192335910d8b..77c92949813c 100644 --- a/src/NumberTheory/GaloisGrp/GaloisGrp.jl +++ b/src/NumberTheory/GaloisGrp/GaloisGrp.jl @@ -87,6 +87,17 @@ function *(a::ZZRingElem, b::BoundRingElem) # @show a, ":*", b, ":=", c return c end + +function Oscar.divexact(a::BoundRingElem{ZZRingElem}, b::ZZRingElem; check::Bool = true) + c = BoundRingElem(ceil(ZZRingElem, a.val//b), a.p) +# @show a, ":/", b, ":=", c + return c +end + +function Oscar.divexact(a::BoundRingElem, b::ZZRingElem; check::Bool = true) + return a #TODO: for power series we can get the degree down! +end + function ^(a::BoundRingElem, b::Int) c = BoundRingElem(a.p.pow(a.val, b), a.p) # @show a, ":^", b, ":=", c @@ -2089,7 +2100,18 @@ function descent(GC::GaloisCtx, G::PermGroup, F::GroupFilter, si::PermGroupElem; @vprint :GaloisGroup 2 "of maximal degree $(total_degree(I)*degree(ts))\n" @vprint :GaloisGroup 2 "root upper_bound: $(value(B))\n" - c = roots(GC, bound_to_precision(GC, B, extra)) + pr = bound_to_precision(GC, B, extra) + # if |I(r)| <= B, then I(r) is an algebraic number and + # N(I) := prod_(G//s) I^sigma(r) is an integer, by assumption on G + # p-adically: I(r) = mu mod p^k implies p^k | N(I(r)-mu) + # so either |N| = N = 0 or larger than p^k + # arithmetic mean: + # prod |I(r) - mu| <= (sum |I(r)-mu|/n)^n for n = |G/s|, the index + # <= (2B/n)^n + # thus if p^k > (2B/n)^n, we're safe. In general this is too large + # (and for complex roots we need s.th. different, for symbolics this + # is a no-op) + c = roots(GC, pr) c = map(ts, c) local fd @@ -2132,8 +2154,33 @@ function descent(GC::GaloisCtx, G::PermGroup, F::GroupFilter, si::PermGroupElem; push!(cs, e) fl, l = isinteger(GC, B, e) if fl - @vprint :GaloisGroup 2 "found descent at $t and value $l\n" - push!(fd, t) + if isa(e, FlintLocalFieldElem) && index(G, s) < 10 + #TODO: better strategy, add 10%? use n = min(10, index)? + # Fabian found e with 5 consecutive 0 digits mod 17 + # so it can happen... + @vprint :GaloisGroup 2 "found possible descent at $t and value $l, proving now ..." + + + n = index(G, s) + local _pr = bound_to_precision(GC, (2*B/n)^n, extra) + local _c = roots(GC, _pr) + _c = map(ts, _c) + local _e = evaluate(I, t, _c) + fl, l = isinteger(GC, B, _e) + if fl + @vprint :GaloisGroup 2 "confirmed!\n" + push!(fd, t) + else + @vprint :GaloisGroup 2 "failed, no descent!\n" + if is_normalized_by(s, G) + @vprint :GaloisGroup 2 "no descent here, group is normal, giving up\n" + break + end + end + else + @vprint :GaloisGroup 2 "found descent at $t and value $l\n" + push!(fd, t) + end end end if length(cs) == length(lt) @@ -2369,7 +2416,7 @@ function fixed_field(GC::GaloisCtx, U::PermGroup, extra::Int = 5) k = extension_field(f, check = false, cached = false)[1] @assert all(x->isone(denominator(x)), coefficients(k.pol)) @assert is_monic(k.pol) - return k + return k#, a, T, ts end """ diff --git a/test/NumberTheory/galthy.jl b/test/NumberTheory/galthy.jl index fb8e9a78f97e..17b1832ec7ee 100644 --- a/test/NumberTheory/galthy.jl +++ b/test/NumberTheory/galthy.jl @@ -57,6 +57,10 @@ G, C = galois_group((x^3-2)^2*(x^3-5)^2*(x^2-6)) @test order(G) == 36 @test degree(G) == 14 + + #Fabian Gundlach... + G, C = galois_group(x^8 - 2*x^7 - 48*x^6 + 58*x^5 + 846*x^4 - 4614*x^3 + 6609*x^2 + 48742*x + 493474) + @test order(G) == 32 end import Oscar.GaloisGrp: primitive_by_shape, an_sn_by_shape, cycle_structures