From 490c19cd2d5d3ef17ea8ed3191451be918993eec Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 13:40:06 +0200 Subject: [PATCH 1/7] adds quotients for modules --- src/module/module.jl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/module/module.jl b/src/module/module.jl index fd7c9c3b4..a43b7aa56 100644 --- a/src/module/module.jl +++ b/src/module/module.jl @@ -1,6 +1,6 @@ export jet, minimal_generating_set, ModuleClass, rank, smodule, slimgb, eliminate, modulo, lift, division, divrem, prune_with_map, - prune_with_map_projection + prune_with_map_projection, quotient ############################################################################### # @@ -446,6 +446,7 @@ function nres(I::smodule{spoly{T}}, max_length::Int) where T <: Nemo.FieldElem return sresolution{spoly{T}}(R, r, Bool(minimal), false) end + ############################################################################### # # Module constructors @@ -650,3 +651,16 @@ function hilbert_series(M::smodule{spoly{T}}, w::Vector{<:Integer}, shifts::Vect GC.@preserve M R libSingular.scHilbWeighted(M.ptr, R.ptr, w, shifts, z) return z end + +############################################################################### +# +# Quotient +# +############################################################################### + +function quotient(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo.FieldElem + R = base_ring(I) + S = elem_type(R) + ptr = GC.@preserve I J R libSingular.id_Quotient(I.ptr, J.ptr, I.isGB, R.ptr) + return Module(smatrix{spoly{T}}(R, ptr)) +end From 26240e33e505b85676ac61e3235c1847135c6dd7 Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 13:40:26 +0200 Subject: [PATCH 2/7] adds test for quotients for modules --- test/module/smodule-test.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/module/smodule-test.jl b/test/module/smodule-test.jl index f15a93dfe..9bd77cb72 100644 --- a/test/module/smodule-test.jl +++ b/test/module/smodule-test.jl @@ -330,3 +330,15 @@ end @test p[3] == 2 end + +@testset "smodule.quotient" begin + R, (x, y) = polynomial_ring(QQ, ["x", "y"]) + + I = Singular.Module(R, vector(R,x^2 + x*y + 1), vector(R,2y^2 + 3)) + J = Singular.Module(R, vector(R,x*y^2 + x + 1), vector(R,2x*y + 1), vector(R,x*y + 1)) + + A = quotient(I, J) + B = Singular.Module(R, vector(R, 2*y^2+3), vector(R, x^2+x*y+1)) + @test A[1] == B[1] + @test A[2] == B[2] +end From bb084d5277310bdc0f3d78f320bc9d53f3ce6a67 Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 14:33:50 +0200 Subject: [PATCH 3/7] adds saturation for modules --- src/module/module.jl | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/module/module.jl b/src/module/module.jl index a43b7aa56..065684a95 100644 --- a/src/module/module.jl +++ b/src/module/module.jl @@ -1,6 +1,6 @@ export jet, minimal_generating_set, ModuleClass, rank, smodule, slimgb, eliminate, modulo, lift, division, divrem, prune_with_map, - prune_with_map_projection, quotient + prune_with_map_projection, quotient, contains, saturation ############################################################################### # @@ -652,6 +652,20 @@ function hilbert_series(M::smodule{spoly{T}}, w::Vector{<:Integer}, shifts::Vect return z end +############################################################################### +# +# Containment +# +############################################################################### + +function contains(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo.FieldElem + check_parent(I, J) + if !I.isGB + I = std(I) + end + return iszero(reduce(J, I)) +end + ############################################################################### # # Quotient @@ -664,3 +678,25 @@ function quotient(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo.Fi ptr = GC.@preserve I J R libSingular.id_Quotient(I.ptr, J.ptr, I.isGB, R.ptr) return Module(smatrix{spoly{T}}(R, ptr)) end + +############################################################################### +# +# Saturation +# +############################################################################### +function saturation(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo.FieldElem + check_parent(I, J) + has_global_ordering(base_ring(I)) || error("Must be over a ring with global ordering") + if !I.isGB + I = std(I) + end + k = 0 + done = false + while !done + Q = quotient(I, J) + done = contains(I, Q) + I = std(Q) + k += 1 + end + return I, k - 1 +end From 3cd757894be6a2312a2a3bb561d39ca4f90c01ee Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 14:34:05 +0200 Subject: [PATCH 4/7] adds test for saturation for modules --- test/module/smodule-test.jl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/module/smodule-test.jl b/test/module/smodule-test.jl index 9bd77cb72..204427e2b 100644 --- a/test/module/smodule-test.jl +++ b/test/module/smodule-test.jl @@ -342,3 +342,17 @@ end @test A[1] == B[1] @test A[2] == B[2] end + +@testset "smodule.saturation" begin + R, (x, y) = polynomial_ring(QQ, ["x", "y"]) + + I = Singular.Module(R, vector(R,(x^2 + x*y + 1)*(2y^2+1)^3), vector(R,(2y^2 + 3)*(2y^2+1)^2)) + J = Singular.Module(R, vector(R,2y^2 + 1)) + + A,k = saturation(I, J) + + B = Singular.Module(R, vector(R,2*y^2+3), vector(R,x^2+x*y+1)) + @test A[1] == B[1] + @test A[2] == B[2] + @test k == 2 +end From 6d6c3380efe39a10a07530203ae97d89c15f745f Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 14:39:22 +0200 Subject: [PATCH 5/7] adds containment test for modules --- test/module/smodule-test.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/module/smodule-test.jl b/test/module/smodule-test.jl index 204427e2b..6e1c3af60 100644 --- a/test/module/smodule-test.jl +++ b/test/module/smodule-test.jl @@ -331,6 +331,16 @@ end end +@testset "smodule.contains" begin + R, (x, y) = polynomial_ring(QQ, ["x", "y"]) + + I = Singular.Module(R, vector(R,y^3)) + J = Singular.Module(R, vector(R,y^2)) + + @test contains(I, J) == false + @test contains(J, I) == true +end + @testset "smodule.quotient" begin R, (x, y) = polynomial_ring(QQ, ["x", "y"]) From 4358b0a75f4aa0dcac94a6affdad9853b0e18df9 Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 14:49:04 +0200 Subject: [PATCH 6/7] adds second saturation variant for modules --- src/module/module.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/module/module.jl b/src/module/module.jl index 065684a95..60e85327f 100644 --- a/src/module/module.jl +++ b/src/module/module.jl @@ -1,6 +1,6 @@ export jet, minimal_generating_set, ModuleClass, rank, smodule, slimgb, eliminate, modulo, lift, division, divrem, prune_with_map, - prune_with_map_projection, quotient, contains, saturation + prune_with_map_projection, quotient, contains, saturation, saturation2 ############################################################################### # @@ -700,3 +700,11 @@ function saturation(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo. end return I, k - 1 end + +function saturation2(I::smodule{spoly{T}}, J::smodule{spoly{T}}) where T <: Nemo.FieldElem + check_parent(I, J) + R = base_ring(I) + has_global_ordering(R) || error("Must be over a ring with global ordering") + ptr_res,k=libSingular.id_Saturation(I.ptr,J.ptr,R.ptr) + return (Module(smatrix{spoly{T}}(R,ptr_res))),k +end From 14e8c692143d0ff35d6e157ec0583e8c11c02600 Mon Sep 17 00:00:00 2001 From: ederc Date: Wed, 18 Sep 2024 14:50:43 +0200 Subject: [PATCH 7/7] adds tests for second saturation variant for modules --- test/module/smodule-test.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/module/smodule-test.jl b/test/module/smodule-test.jl index 6e1c3af60..1beaa86d3 100644 --- a/test/module/smodule-test.jl +++ b/test/module/smodule-test.jl @@ -365,4 +365,10 @@ end @test A[1] == B[1] @test A[2] == B[2] @test k == 2 + + A,k = saturation2(I, J) + + @test A[1] == B[1] + @test A[2] == B[2] + @test k == 2 end