From 8ffdfb12cd194e6be00ee8f503cc99a5195515a9 Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Wed, 8 May 2024 13:54:42 +0200 Subject: [PATCH 1/6] Hook in zero dimensional primary decomposition. --- src/Rings/mpoly-ideals.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index 42f811538a67..25a4414da15b 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -1068,6 +1068,12 @@ julia> L = minimal_primes(I) function minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ, cache::Bool=true) has_attribute(I, :minimal_primes) && return get_attribute(I, :minimal_primes)::Vector{typeof(I)} R = base_ring(I) + if is_zero(dim(I)) + L = Singular.LibAssprimeszerodim.assPrimes(singular_generators(I)) + result = typeof(I)[ideal(R, q) for q in L] + cache && set_attribute!(I, :minimal_primes=>result) + return result + end if isa(base_ring(R), NumField) && !isa(base_ring(R), AbsSimpleNumField) A, mA = absolute_simple_field(base_ring(R)) mp = minimal_primes(map_coefficients(pseudo_inv(mA), I); algorithm = algorithm) @@ -1157,6 +1163,14 @@ function minimal_primes( return final_list end + if base_ring(R) isa QQField && is_zero(dim(I)) # Special functionality available here + # Flattening does not do good in the examples we tested + L = Singular.LibAssprimeszerodim.assPrimes(singular_generators(I)) + result = typeof(I)[ideal(R, q) for q in L] + cache && set_attribute!(I, :minimal_primes=>result) + return result + end + R_flat, iso, iso_inv = _expand_coefficient_field_to_QQ(R) I_flat = ideal(R_flat, elem_type(R_flat)[g for g in iso_inv.(gens(I))]) dec = minimal_primes(I_flat; algorithm) @@ -2241,3 +2255,4 @@ function flag_pluecker_ideal(ring::MPolyRing{<: FieldElem}, dimensions::Vector{I isReduced=true, isGB=true)) end + From 6f1fcc1e5d25259e0ab077cfe2ddb1e146733b42 Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Wed, 8 May 2024 14:09:19 +0200 Subject: [PATCH 2/6] Add tests. --- test/Rings/mpoly.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/Rings/mpoly.jl b/test/Rings/mpoly.jl index b6c695cf5527..942df4fce954 100644 --- a/test/Rings/mpoly.jl +++ b/test/Rings/mpoly.jl @@ -220,6 +220,19 @@ end R, (x, y) = polynomial_ring(QQ, ["x", "y"]) I = ideal(R, [one(R)]) @test is_prime(I) == false + + J = ideal(R, [x*(x-1), y*(y-1), x*y]) + l = minimal_primes(J) + @test length(l) == 3 + + QQt, t = QQ[:t] + kk, a = extension_field(t^2 + 1) + + R, (x, y) = kk[:x, :y] + J = ideal(R, [x^2 + 1, y^2 + 1, (x - a)*(y - a)]) + l = minimal_primes(J) + @test length(l) == 3 + end @testset "Groebner" begin @@ -574,3 +587,5 @@ end @test default_ordering(T) == old_default end end + + From 2cd696ec1904d605f7f830ed32ebffad914bb4bb Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Wed, 8 May 2024 20:14:29 +0200 Subject: [PATCH 3/6] Restrict usages of special decomposition. --- src/Rings/mpoly-ideals.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index 25a4414da15b..b912a8842564 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -1068,7 +1068,7 @@ julia> L = minimal_primes(I) function minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ, cache::Bool=true) has_attribute(I, :minimal_primes) && return get_attribute(I, :minimal_primes)::Vector{typeof(I)} R = base_ring(I) - if is_zero(dim(I)) + if coefficient_ring(R) isa QQField && is_zero(dim(I)) L = Singular.LibAssprimeszerodim.assPrimes(singular_generators(I)) result = typeof(I)[ideal(R, q) for q in L] cache && set_attribute!(I, :minimal_primes=>result) From c6e89fec4e7c782c114aed9452eb244785214c5e Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Sat, 29 Jun 2024 21:28:53 +0200 Subject: [PATCH 4/6] Fix initialization. --- src/Rings/mpoly-ideals.jl | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index b912a8842564..fd296dec3b5e 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -1139,11 +1139,12 @@ function minimal_primes( # This will in many cases lead to an easy simplification of the problem if factor_generators - J = typeof(I)[ideal(R, elem_type(R)[])] + J = [ideal(R, gens(I))] # A copy of I as initialization for g in gens(I) K = typeof(I)[] is_zero(g) && continue for (b, k) in factor(g) + # Split the already collected components with b for j in J push!(K, j + ideal(R, b)) end @@ -1163,14 +1164,6 @@ function minimal_primes( return final_list end - if base_ring(R) isa QQField && is_zero(dim(I)) # Special functionality available here - # Flattening does not do good in the examples we tested - L = Singular.LibAssprimeszerodim.assPrimes(singular_generators(I)) - result = typeof(I)[ideal(R, q) for q in L] - cache && set_attribute!(I, :minimal_primes=>result) - return result - end - R_flat, iso, iso_inv = _expand_coefficient_field_to_QQ(R) I_flat = ideal(R_flat, elem_type(R_flat)[g for g in iso_inv.(gens(I))]) dec = minimal_primes(I_flat; algorithm) From af7a9c418b6526fcb06865abd0c38b3b7984d453 Mon Sep 17 00:00:00 2001 From: HechtiDerLachs Date: Sun, 30 Jun 2024 03:17:33 +0200 Subject: [PATCH 5/6] Avoid usage of unique. --- src/Rings/mpoly-ideals.jl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index fd296dec3b5e..d4b86e2cb49e 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -1151,7 +1151,22 @@ function minimal_primes( end J = K end - result = unique!(filter!(!is_one, vcat([minimal_primes(j; algorithm, factor_generators=false) for j in J]...))) + + unique_comp = typeof(I)[] + for q in J + is_one(q) && continue + q in unique_comp && continue + push!(unique_comp, q) + end + J = unique_comp + result = typeof(I)[] + # `unique!` does not work for lists of ideals. I don't know why, but for the moment we need the + # following workaround. + for p in filter!(!is_one, vcat([minimal_primes(j; algorithm, factor_generators=false) for j in J]...)) + p in result && continue + push!(result, p) + end + # The list might not consist of minimal primes only. We have to discard the embedded ones final_list = typeof(I)[] for p in result From 70905dee449fe7abfc11ec7a5a0889e5d6f6bafe Mon Sep 17 00:00:00 2001 From: ederc Date: Sun, 30 Jun 2024 18:04:23 +0200 Subject: [PATCH 6/6] adds caching of isGB information --- src/Rings/mpoly-ideals.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Rings/mpoly-ideals.jl b/src/Rings/mpoly-ideals.jl index d4b86e2cb49e..e77982810f90 100644 --- a/src/Rings/mpoly-ideals.jl +++ b/src/Rings/mpoly-ideals.jl @@ -2054,7 +2054,8 @@ function small_generating_set( computed_gb = IdealGens(ring, sing_gb, true) if !haskey(I.gb,computed_gb.ord) # if not yet present, store gb for later use - I.gb[computed_gb.ord] = computed_gb + I.gb[computed_gb.ord] = computed_gb + I.gb[computed_gb.ord].isGB = true end # we do not have a notion of minimal generating set in this context!