diff --git a/src/ideal/ideal.jl b/src/ideal/ideal.jl index e2e8e15b0..1b2716187 100644 --- a/src/ideal/ideal.jl +++ b/src/ideal/ideal.jl @@ -1,7 +1,7 @@ export sideal, IdealSet, syz, lead, normalize!, is_constant, is_zerodim, fglm, fres, dimension, highcorner, jet, kbase, minimal_generating_set, independent_sets, maximal_independent_set, mres, mres_with_map, - number_of_generators, ngens, nres, sres, + modStd, number_of_generators, ngens, nres, sres, intersection, homogenize_ideal, homogenize_ideal_with_weights, quotient, reduce, eliminate, kernel, equal, contains, is_var_generated, saturation, saturation2, satstd, slimgb, std, std_with_HC, @@ -675,6 +675,30 @@ function std(I::sideal{S}; complete_reduction::Bool=false) where S <: SPolyUnion return sideal{S}(R, ptr, true, I.isTwoSided) end + +@doc raw""" + modStd(I::sideal{S}; nr_cores::Int=1, exact::Bool=false) where S <: SPolyUnion + +Compute a Groebner basis for the ideal $I$ over $QQ$ with multi-modular methods. +The algorithm computes `nr_cores` modular Groebner basis in parallel. If `exact` is `true`, +`I` is homogeneous or the monomial ordering is local the resulting Groebner basis over `QQ` +for `I` is ensured to be correct. +""" +function modStd(I::sideal{S}; nr_cores::Int=1, exact::Bool=false) where S <: SPolyUnion + R = base_ring(I) + exactness = exact == false ? 0 : 1 + ncores = nr_cores > 0 ? nr_cores : 1 + if base_ring(R) == QQ + ncores_old = LibResources.getcores() + LibResources.setcores(ncores) + G = LibModstd.modStd(I, exactness) + LibResources.setcores(ncores_old) + return G + else + error("modStd is only available over QQ.") + end +end + @doc raw""" std_with_HC(I::sideal{{spoly{T}}, HC::spoly{T}) where T <: Nemo.FieldElem diff --git a/test/ideal/sideal-test.jl b/test/ideal/sideal-test.jl index 3721bcf1c..c875bbb36 100644 --- a/test/ideal/sideal-test.jl +++ b/test/ideal/sideal-test.jl @@ -297,6 +297,18 @@ end @test equal(I, Ideal(R, x^2, y)) end +@testset "sideal.modstd" begin + R, (x, y) = polynomial_ring(QQ, ["x", "y"]) + I = Ideal(R, x^2 + x*y + 1, 2*x*y^2 + 3) + H = Ideal(R, y^2 - 3//2*x - 3//2*y, x^2 + x*y + 1) + G = modStd(I) + @test equal(G, H) + G = modStd(I, exact=true) + @test equal(G, H) + G = modStd(I, nr_cores=2) + @test equal(G, H) +end + @testset "sideal.intersection" begin R, (x, y) = polynomial_ring(QQ, ["x", "y"])