Skip to content

Commit

Permalink
Comparison of Groebner bases (#2622)
Browse files Browse the repository at this point in the history
* Add comparison for IdealGens

* doc tests

* test
  • Loading branch information
jankoboehm authored Aug 6, 2023
1 parent c620222 commit a6e3c0f
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 19 deletions.
4 changes: 3 additions & 1 deletion src/Rings/groebner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,9 @@ julia> B,m = Oscar._compute_standard_basis_with_transform(A, degrevlex(R))
(Ideal generating system with elements
1 -> x*y - 3*x
2 -> -6*x^2 + y^3
3 -> 6*x^3 - 27*x, [1 2*x -2*x^2+y^2+3*y+9; 0 1 -x])
3 -> 6*x^3 - 27*x
with associated ordering
degrevlex([x, y]), [1 2*x -2*x^2+y^2+3*y+9; 0 1 -x])
```
"""
function _compute_standard_basis_with_transform(B::IdealGens, ordering::MonomialOrdering, complete_reduction::Bool = false)
Expand Down
117 changes: 99 additions & 18 deletions src/Rings/mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,23 +287,25 @@ end

function show(io::IO, I::IdealGens)
if I.isGB
if is_global(I.ord)
print(io, "Gröbner basis with elements")
else
print(io, "Standard basis with elements")
end
for (i,g) in enumerate(gens(I))
print(io, "\n", i, " -> ", OscarPair(g, I.ord))
end
if is_global(I.ord)
print(io, "Gröbner basis with elements")
else
print(io, "Standard basis with elements")
end
for (i,g) in enumerate(gens(I))
print(io, "\n", i, " -> ", OscarPair(g, I.ord))
end
print(io, "\nwith respect to the ordering")
print(io, "\n", I.ord)
else
print(io, "Ideal generating system with elements")
for (i,g) in enumerate(gens(I))
print(io, "\n", i, " -> ", g)
end
end
if I.isGB
print(io, "\nwith respect to the ordering")
print(io, "\n", I.ord)
print(io, "Ideal generating system with elements")
for (i,g) in enumerate(gens(I))
print(io, "\n", i, " -> ", g)
end
if isdefined(I, :ord)
print(io, "\nwith associated ordering")
print(io, "\n", I.ord)
end
end
end

Expand Down Expand Up @@ -379,10 +381,68 @@ function elements(I::IdealGens)
return collect(I)
end

function ordering(G::Oscar.IdealGens)
return G.ord
function ordering(G::IdealGens)
isdefined(G, :ord) ? G.ord : error("The ideal generating system does not have an associated ordering")
end

# for internal use only
function set_ordering!(G::IdealGens, monord::MonomialOrdering)
@assert base_ring(G) == monord.R "Base rings of IdealGens and MonomialOrdering are inconsistent"
isdefined(G, :ord) && G.ord !== monord && error("Monomial ordering is already set to a different value")
G.ord = monord
end


@doc raw"""
set_ordering(I::IdealGens, monord::MonomialOrdering)
Return an ideal generating system with an associated monomial ordering.
# Examples
```jldoctest
julia> R, (x0, x1, x2) = polynomial_ring(QQ, ["x0","x1","x2"]);
julia> I = ideal([x0*x1, x2]);
julia> g = generating_system(I);
julia> set_ordering(g, degrevlex(gens(R)))
Ideal generating system with elements
1 -> x0*x1
2 -> x2
with associated ordering
degrevlex([x0, x1, x2])
```
"""
function set_ordering(G::IdealGens, monord::MonomialOrdering)
@assert base_ring(G) == monord.R "Base rings of IdealGens and MonomialOrdering are inconsistent"
H = IdealGens(base_ring(G), gens(G))
if isdefined(G, :ord) && G.ord != monord
H.isGB = false
H.isReduced = false
end
H.keep_ordering = H.keep_ordering
H.ord = monord
return H
end


function Base.:(==)(G1::IdealGens, G2::IdealGens)
@assert !G1.isGB || isdefined(G1, :ord) "Gröbner basis must have an ordering"
@assert !G2.isGB || isdefined(G2, :ord) "Gröbner basis must have an ordering"
if isdefined(G1, :ord) != isdefined(G2, :ord)
return false
end
if G1.isGB != G2.isGB
return false
end
if isdefined(G1, :ord) && G1.ord != G2.ord
return false
end
return G1.gens == G2.gens
end


##############################################################################
#
# Conversion to and from Singular: in particular, some Rings are
Expand Down Expand Up @@ -705,6 +765,27 @@ function map_entries(R, M::Singular.smatrix)
return matrix(S, s[1], s[2], elem_type(S)[R(M[i,j]) for i=1:s[1] for j=1:s[2]])
end

@doc raw"""
generating_system(I::MPolyIdeal)
Return the system of generators of `I`.
# Examples
```jldoctest
julia> R,(x,y) = polynomial_ring(QQ, ["x","y"]);
julia> I = ideal([x*(x+1), x^2-y^2+(x-2)*y]);
julia> generating_system(I)
Ideal generating system with elements
1 -> x^2 + x
2 -> x^2 + x*y - y^2 - 2*y
```
"""
function generating_system(I::MPolyIdeal)
return I.gens
end

function syzygy_module(a::Vector{MPolyRingElem})
#only graded modules exist
error("not implemented yet")
Expand Down
2 changes: 2 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ export gen
export general_linear_group
export generalized_jordan_block
export generalized_jordan_form
export generating_system
export generator_matrix
export generic_fraction
export generic_fractions
Expand Down Expand Up @@ -1226,6 +1227,7 @@ export set_coordinate_names
export set_coordinate_names_of_torus
export set_grading
export set_name!
export set_ordering
export set_power!
export set_relative_order!
export set_relative_orders!
Expand Down
15 changes: 15 additions & 0 deletions test/Rings/mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,18 @@ end
test_ideal = ideal([x[1, 2]*x[2, 2] + 6*x[2, 1]*x[1, 3] + x[1, 1]*x[2, 3]])
@test grassmann_pluecker_ideal(R, 2, 4) == test_ideal
end

@testset "IdealGens" begin
R, (x0, x1, x2) = PolynomialRing(QQ, ["x0", "x1", "x2"])
I = ideal([x0*x1,x2])
g = generating_system(I)
@test elements(g) == [x0*x1, x2]
@test g.isGB == false
@test isdefined(g, :ord) == false
h = set_ordering(g, degrevlex(gens(R)))
@test h != g
@test ordering(h) == degrevlex(gens(R))
h1 = Oscar.IdealGens(base_ring(g), gens(g))
Oscar.set_ordering!(h1, lex(R))
@test ordering(h1) == lex(gens(R))
end

0 comments on commit a6e3c0f

Please sign in to comment.