Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more monomial and module orderings #723

Merged
merged 38 commits into from
Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
19b0353
Factoring orderings out to separate file and rename weightlex -> wlex…
wbhart Oct 4, 2021
85374bd
Restrict to one module ordering per block ordering.
wbhart Oct 5, 2021
92aa1c6
Hook up to Singular.jl.
wbhart Oct 5, 2021
d4ecf51
Add some missing orderings.
wbhart Oct 5, 2021
17eb506
Add missing functions for creating orderings.
wbhart Oct 5, 2021
79e489a
Add weighted orderings with weight vector, add missing ordering funct…
wbhart Oct 7, 2021
9b07333
Add docs for monomial orderings and fix some broken tests.
wbhart Oct 7, 2021
3d72582
Add better printing for module orderings.
wbhart Oct 7, 2021
969a95e
Add more monomial ordering tests.
wbhart Oct 7, 2021
fae927b
Rename wneg to negw.
wbhart Oct 8, 2021
89a1606
Clean up printing of module ordering and add revlex module ordering.
wbhart Oct 8, 2021
5eb7097
Add weight matrices for all new orderings (except block orderings).
wbhart Oct 15, 2021
c8641f7
Fix some weight matrices.
wbhart Oct 19, 2021
88d1b8c
Make groebner_basis and singular_assure accept an ordering argument.
wbhart Oct 19, 2021
cd276ed
Back to named arguments.
wbhart Oct 19, 2021
1d7abfb
Back to ord argument.
wbhart Oct 19, 2021
6287e62
Fix docstring.
wbhart Oct 19, 2021
98f8e1e
Fix test.
wbhart Oct 19, 2021
027f738
Fix doctest.
wbhart Oct 21, 2021
260186c
Implement modStd version of groebner_basis_with_transformation_matrix.
wbhart Oct 21, 2021
0976d1b
Version of groebner_assure and leading_ideal with ordering object.
wbhart Oct 21, 2021
af3ebf4
Fix failing test.
wbhart Oct 21, 2021
54e2292
Fix doctest.
wbhart Oct 21, 2021
9eb3f62
Correct degrevlex weight matrix. Add some ordering comparison tests a…
wbhart Oct 29, 2021
c9646f7
Add new tests for the groebner basis command with new orderings.
wbhart Oct 29, 2021
2a460ff
Add more Groebner basis tests.
wbhart Oct 29, 2021
30ca2b2
Correct leading_ideal tests.
wbhart Oct 29, 2021
9b324ac
Whoops, cut'n'pasta error.
wbhart Oct 29, 2021
a313dda
Make lt_from_ordering and terms/monomials/coefficients/exponent_vecto…
wbhart Nov 4, 2021
7f525ac
Fix bugs in weighted orderings and add monomials tests (some currentl…
wbhart Nov 4, 2021
8c7cc49
Fix some bugs in the orderings. Others remain.
wbhart Nov 5, 2021
3423fa1
Add missing ordering and correct some orderings.
wbhart Nov 5, 2021
6807d02
fix: negwdegrevlex
hannes14 Dec 17, 2021
3dc3553
Merge branch 'master' into ordering_gb_meeting
fingolfin Jan 18, 2022
6fe80d7
Fix tests
fingolfin Jan 18, 2022
f4cba57
the original negwdegrevlex test was correct and the code was wrong
tthsqe12 Jan 27, 2022
7b12f0d
Merge branch 'master' into ordering_gb_meeting
tthsqe12 Jan 28, 2022
ad787d2
doc test fix
tthsqe12 Jan 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion docs/src/CommutativeAlgebra/ideals.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,62 @@ m_{i-1}\alpha\ =m_{i-1}\beta,\ m_i\alpha>m_i\beta$

To create matrix orderings, OSCAR allows for matrices with integer coefficients as input matrices.

### Normal Forms
#### Functions for creating orderings

When computing Gröbner bases an ordering must be supplied. Standard Singular
orderings, including block orderings, weighted orderings and local orderings
are available.

The basic orderings are `:lex`, `:revlex`, `:deglex`, `:degrevlex`,
`:neglex`, `:negrevlex`, `:negdeglex`, `:negdegrevlex`, `:wdeglex`,
`:wdegrevlex`, `:negwdeglex` and `:negwdegrevlex`.

The orderings starting with `w` are weighted orderings.

The following functions exist for creating orderings:

```@docs
lex(::AbstractVector{<:MPolyElem})
revlex(::AbstractVector{<:MPolyElem})
deglex(::AbstractVector{<:MPolyElem})
degrevlex(::AbstractVector{<:MPolyElem})
neglex(::AbstractVector{<:MPolyElem})
negrevlex(::AbstractVector{<:MPolyElem})
negdeglex(::AbstractVector{<:MPolyElem})
negdegrevlex(::AbstractVector{<:MPolyElem})
```

```@docs
wdeglex(::AbstractVector{<:MPolyElem}, ::Vector{Int})
wdegrevlex(::AbstractVector{<:MPolyElem}, ::Vector{Int})
negwdeglex(::AbstractVector{<:MPolyElem}, ::Vector{Int})
negwdegrevlex(::AbstractVector{<:MPolyElem}, ::Vector{Int})
```

Block orderings can be obtained by concatening monomial orderings using the `*`
operator.

Term over position and position over term module orderings are also available.
These are also specified byy concatenation using the `*` operator. One creates
the requisite module ordering (`lex` or `revlex`) for the generators of the
free module.

Term over position is specified by appending the module ordering to the
monomial ordering and position over term by prepending the module ordering.

###### Examples

```@repl oscar
R, (x, y, s, t, u) = PolynomialRing(QQ, ["x", "y", "s", "t", "u"])
O1 = degrevlex(gens(R))
O2 = lex([x, y])*deglex([s, t, u])
O3 = wdeglex(gens(R), [2, 3, 5, 7, 3])

K = FreeModule(R, 3)
O4 = revlex(gens(K))*degrevlex(gens(R))
```

## Normal Forms

```@docs
normal_form(f::T, J::MPolyIdeal) where { T <: MPolyElem }
Expand Down
23 changes: 17 additions & 6 deletions experimental/ModStd/ModStdQ.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ function Oscar.groebner_assure(I::MPolyIdeal{fmpq_mpoly}, ord::Symbol = :degrevl
end
end

function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}; ordering::Symbol = :degrevlex, complete_reduction::Bool = true, use_hilbert::Bool = false)

function groebner_basis_with_transform_inner(I::MPolyIdeal{fmpq_mpoly}, ord::MonomialOrdering; complete_reduction::Bool = true, use_hilbert::Bool = false)
if iszero(I)
I.gb = BiPolyArray(base_ring(I), fmpq_mpoly[], isGB = true, keep_ordering = false)
singular_assure(I.gb)
I.gb.ord = ord.o
singular_assure(I.gb, ord)
return fmpq_mpoly[], matrix(base_ring(I), ngens(I), 0, fmpq_mpoly[])
end

Expand Down Expand Up @@ -147,7 +147,7 @@ function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}; ordering
R = GF(p)
Rt, t = PolynomialRing(R, [string(s) for s = symbols(Qt)], cached = false)
@vtime :ModStdQ 3 Ip = Oscar.BiPolyArray([Rt(x) for x = gI], keep_ordering = false)
Gp, Tp = Oscar.groebner_basis_with_transform(Ip, ord = ordering, complete_reduction = complete_reduction)
Gp, Tp = Oscar.groebner_basis_with_transform(Ip, ord; complete_reduction = complete_reduction)
length_gc = length(Gp)
Jp = vcat(map(x->lift(Zt, x), Gp), map(x->lift(Zt, x), reshape(collect(Tp), :)))

Expand Down Expand Up @@ -193,10 +193,13 @@ function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}; ordering
T = matrix(Qt, length_gc, length(gI), gd[length_gc+1:end])
#at this point we SHOULD have T*gens(I) == G...
if T*matrix(Qt, length(gI), 1, gI) == matrix(Qt, length_gc, 1, G)
if ordering == :degrevlex && !isdefined(I, :gb)
if !isdefined(I.gens, :ord)
I.gens.ord = ord.o
end
if ord.o == I.gens.ord && !isdefined(I, :gb)
I.gb = BiPolyArray(gd[1:length_gc], keep_ordering = false)
I.gb.isGB = true
singular_assure(I.gb)
I.gb.S.isGB = true
end
return G, T
else
Expand All @@ -209,6 +212,14 @@ function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}; ordering
end
end

function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}; ordering::Symbol = :degrevlex, complete_reduction::Bool = true, use_hilbert::Bool = false)
ord = Oscar.Orderings.MonomialOrdering(base_ring(I), Oscar.Orderings.ordering(gens(base_ring(I)), ordering))
return groebner_basis_with_transform_inner(I, ord; complete_reduction=complete_reduction, use_hilbert=use_hilbert)
end

function Oscar.groebner_basis_with_transform(I::MPolyIdeal{fmpq_mpoly}, ord::MonomialOrdering; complete_reduction::Bool = true, use_hilbert::Bool = false)
return groebner_basis_with_transform_inner(I, ord; complete_reduction=complete_reduction, use_hilbert=use_hilbert)
end

function Oscar.lift(R::Nemo.Ring, f::Union{gfp_mpoly, nmod_mpoly})
g = MPolyBuildCtx(R)
Expand Down
4 changes: 2 additions & 2 deletions src/Modules/FreeModules-graded.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#TODO make d and S a function optionally - to support HUGE degree
export presentation, grading_group
export presentation, grading_group, ModuleOrdering

abstract type ModuleFP_dec{T} end

Expand Down Expand Up @@ -117,7 +117,7 @@ end
dim(F::FreeModule_dec) = length(F.d)
ngens(F::FreeModule_dec) = dim(F)

struct FreeModuleElem_dec{T}
struct FreeModuleElem_dec{T} <: AbstractAlgebra.ModuleElem{T}
r::SRow{T}
parent::FreeModule_dec{T}
end
Expand Down
1 change: 1 addition & 0 deletions src/Oscar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ include("Groups/GrpAb.jl")

include("Rings/integer.jl")
include("Rings/rational.jl")
include("Rings/orderings.jl")
include("Rings/mpoly.jl")
include("Rings/mpoly-graded.jl")
include("Rings/mpoly-ideals.jl")
Expand Down
1 change: 1 addition & 0 deletions src/Rings/MPolyQuo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ function simplify(f::MPolyQuoElem)
g = f.f
return R(I.gens.Ox(reduce(Sx(g), I.gb.S)))
end

function simplify!(f::MPolyQuoElem)
R = parent(f)
I = R.I
Expand Down
79 changes: 53 additions & 26 deletions src/Rings/groebner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ export groebner_basis, groebner_basis_with_transformation_matrix, leading_ideal

# groebner stuff #######################################################
@doc Markdown.doc"""
groebner_assure(I::MPolyIdeal)
groebner_assure(I::MPolyIdeal; complete_reduction::Bool = false)
groebner_assure(I::MPolyIdeal, ord::MonomialOrdering; complete_reduction::Bool = false)

**Note**: Internal function, subject to change, do not use.

Expand All @@ -27,19 +28,15 @@ julia> Oscar.groebner_assure(I)
x^3 - 9//2*x

julia> I.gb
Oscar.BiPolyArray{fmpq_mpoly}(fmpq_mpoly[x*y - 3*x, y^3 - 6*x^2, x^3 - 9//2*x], Singular ideal over Singular Polynomial Ring (QQ),(x,y),(dp(2),C) with generators (x*y - 3*x, y^3 - 6*x^2, x^3 - 9//2*x), Multivariate Polynomial Ring in x, y over Rational Field, Singular Polynomial Ring (QQ),(x,y),(dp(2),C), false, #undef, false)
Oscar.BiPolyArray{fmpq_mpoly}(fmpq_mpoly[x*y - 3*x, y^3 - 6*x^2, x^3 - 9//2*x], Singular ideal over Singular Polynomial Ring (QQ),(x,y),(dp(2),C) with generators (x*y - 3*x, y^3 - 6*x^2, x^3 - 9//2*x), Multivariate Polynomial Ring in x, y over Rational Field, Singular Polynomial Ring (QQ),(x,y),(dp(2),C), true, #undef, false)
```
"""
function groebner_assure(I::MPolyIdeal; complete_reduction::Bool = false)
if !isdefined(I, :gb)
singular_assure(I)
# @show "std on", I.gens.S
if complete_reduction
i = Singular.std(I.gens.S, complete_reduction = complete_reduction)
I.gb = BiPolyArray(base_ring(I), i)
else
I.gb = BiPolyArray(base_ring(I), Singular.std(I.gens.S))
end
i = Singular.std(I.gens.S; complete_reduction = complete_reduction)
I.gb = BiPolyArray(base_ring(I), i)
I.gb.isGB = true
I.gb.O = [I.gb.Ox(x) for x = gens(I.gb.S)]
end
end
Expand Down Expand Up @@ -82,7 +79,7 @@ function groebner_basis(B::BiPolyArray; ordering::Symbol = :degrevlex, complete_
end

#= @doc Markdown.doc"""
= groebner_basis(I::MPolyIdeal)
= groebner_basis(I::MPolyIdeal; ordering::Symbol = :degrevlex, complete_reduction::Bool = false)
=
= Compute a Groebner basis w.r.t. the given monomial ordering of the polynomial ring.
=
Expand All @@ -108,7 +105,8 @@ end

@doc Markdown.doc"""
groebner_basis(I::MPolyIdeal; ordering::Symbol = :degrevlex, complete_reduction::Bool = false)

groebner_basis(I::MPolyIdeal, ord::MonomialOrdering; complete_reduction::Bool=false)

Given an ideal `I` and optional parameters monomial ordering `ordering` and `complete_reduction`,
compute a Groebner basis (if `complete_reduction = true` the reduced Groebner basis) of `I`
w.r.t. the given monomial ordering `ordering` (as default `:degrevlex`).
Expand All @@ -121,7 +119,7 @@ julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"], ordering=:degrevlex)
julia> I = ideal([x*y-3*x,y^3-2*x^2*y])
ideal(x*y - 3*x, -2*x^2*y + y^3)

julia> H = groebner_basis(I, ordering=:lex)
julia> H = groebner_basis(I; ordering=:lex)
3-element Vector{fmpq_mpoly}:
y^4 - 3*y^3
x*y - 3*x
Expand All @@ -136,7 +134,8 @@ function groebner_basis(I::MPolyIdeal; ordering::Symbol = :degrevlex, complete_r
end

@doc Markdown.doc"""
groebner_basis_with_transform(B::BiPolyArray; ord::Symbol = :degrevlex, complete_reduction::Bool = false)
groebner_basis_with_transform(B::BiPolyArray; ordering::Symbol = :degrevlex, complete_reduction::Bool = false)
groebner_basis_with_transform(B::BiPolyArray, ord::MonomialOrdering; complete_reduction::Bool = false)

**Note**: Internal function, subject to change, do not use.

Expand Down Expand Up @@ -173,9 +172,9 @@ function groebner_basis_with_transform(B::BiPolyArray; ord::Symbol = :degrevlex,
return BiPolyArray(B.Ox, i), map_entries(x->B.Ox(x), m)
end


@doc Markdown.doc"""
groebner_basis_with_transformation_matrix(I::MPolyIdeal; ordering::Symbol = :degrevlex, complete_reduction::Bool=false)
groebner_basis_with_transformation_matrix(I::MPolyIdeal, ord::MonomialOrdering; complete_reduction::Bool=false)

Return a pair `G, m` where `G` is a Groebner basis of the ideal `I` with respect to the
monomial ordering `ordering`, and `m` is a transformation matrix from `gens(I)` to `G`. If
Expand All @@ -197,7 +196,7 @@ true
```
"""
function groebner_basis_with_transformation_matrix(I::MPolyIdeal; ordering::Symbol = :degrevlex, complete_reduction::Bool=false)
G, m = Oscar.groebner_basis_with_transform(I, ordering=ordering, complete_reduction=complete_reduction)
G, m = Oscar.groebner_basis_with_transform(I; ordering=ordering, complete_reduction=complete_reduction)
return G, Array(m)
end

Expand Down Expand Up @@ -277,6 +276,7 @@ end

@doc Markdown.doc"""
leading_ideal(I::MPolyIdeal)
leading_ideal(I::MPolyIdeal, ord::MonomialOrdering)

Given a multivariate polynomial ideal `Ì` this function returns the
leading ideal for `I`. This is done w.r.t. the given monomial ordering
Expand All @@ -300,7 +300,14 @@ function leading_ideal(I::MPolyIdeal)
singular_assure(I.gb)
return MPolyIdeal(base_ring(I), Singular.Ideal(I.gb.Sx, [Singular.leading_monomial(g) for g in gens(I.gb.S)]))
end


function leading_ideal(I::MPolyIdeal, ord::MonomialOrdering)
singular_assure(I, ord)
groebner_assure(I, ord)
singular_assure(I.gb, ord)
return MPolyIdeal(base_ring(I), Singular.Ideal(I.gb.Sx, [Singular.leading_monomial(g) for g in gens(I.gb.S)]))
end

@doc Markdown.doc"""
leading_ideal(I::MPolyIdeal, ordering::Symbol)

Expand All @@ -320,7 +327,7 @@ ideal(y^7, x*y^2, x^3)
```
"""
function leading_ideal(I::MPolyIdeal, ordering::Symbol)
return leading_ideal(groebner_basis(I, ordering=ordering), ordering)
return leading_ideal(groebner_basis(I; ordering=ordering), ordering)
end

@doc Markdown.doc"""
Expand Down Expand Up @@ -454,17 +461,37 @@ function groebner_assure(I::MPolyIdeal, ord::MonomialOrdering; complete_reductio
end

function groebner_basis(B::BiPolyArray, ord::MonomialOrdering; complete_reduction::Bool = false)
R = singular_ring(B.Ox, ord.o)
i = Singular.Ideal(R, [R(x) for x = B])
i = Singular.std(i, complete_reduction = complete_reduction)
return BiPolyArray(B.Ox, i)
singular_assure(B, ord)
R = B.Sx
!Oscar.Singular.has_global_ordering(R) && error("The ordering has to be a global ordering.")
I = Singular.Ideal(R, gens(B.S)...)
i = Singular.std(I, complete_reduction = complete_reduction)
return BiPolyArray(B.Ox, i)
end

function groebner_basis(I::MPolyIdeal, ord::MonomialOrdering; complete_reduction::Bool=false)
R = singular_ring(base_ring(I), ord.o)
!Oscar.Singular.has_global_ordering(R) && error("The ordering has to be a global ordering.")
i = Singular.std(Singular.Ideal(R, [R(x) for x = gens(I)]), complete_reduction = complete_reduction)
return collect(BiPolyArray(base_ring(I), i))
return collect(groebner_basis(I.gens, ord))
end


function groebner_basis_with_transform(B::BiPolyArray, ord::MonomialOrdering; complete_reduction::Bool = false)
if !isdefined(B, :ord)
singular_assure(B, ord)
elseif ord != B.ord
R = singular_ring(B.Ox, ord)
i = Singular.Ideal(R, [R(x) for x = B])
i, m = Singular.lift_std(i, complete_reduction = complete_reduction)
return BiPolyArray(B.Ox, i), map_entries(x->B.Ox(x), m)
end

if !isdefined(B, :S)
B.S = Singular.Ideal(B.Sx, [B.Sx(x) for x = B.O])
end

i, m = Singular.lift_std(B.S, complete_reduction = complete_reduction)
return BiPolyArray(B.Ox, i), map_entries(x->B.Ox(x), m)
end

function groebner_basis_with_transformation_matrix(I::MPolyIdeal, ord::MonomialOrdering; complete_reduction::Bool=false)
G, m = Oscar.groebner_basis_with_transform(I, ord; complete_reduction=complete_reduction)
return G, Array(m)
end
Loading