Skip to content

Commit

Permalink
Temporarily change the default ordering (#3660)
Browse files Browse the repository at this point in the history
* Add `with_ordering`

* Add `try ... finally`
  • Loading branch information
joschmitt authored May 22, 2024
1 parent 62b7f82 commit a087170
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
9 changes: 9 additions & 0 deletions docs/src/CommutativeAlgebra/GroebnerBases/groebner_bases.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ The *leading monomial* $\text{LM}_>(f)$, the *leading exponent* $\text{LE}_>(f)$
positive weights. Then the corresponding `wdegrevlex` ordering is used. Given a free $R$-module $F$, the
`default_ordering` is `default_ordering(R)*lex(gens(F))`.

```@docs
default_ordering(::MPolyRing)
```

Here are some illustrating OSCAR examples:

##### Examples
Expand All @@ -77,6 +81,11 @@ julia> default_ordering(S)
wdegrevlex([x, y, z], [1, 2, 3])
```

Expert users may temporarily choose a different default ordering for a given ring.
```@docs
with_ordering
```

## [Monomials, Terms, and More](@id monomials_terms_more)

Here are examples which indicate how to recover monomials, terms, and
Expand Down
66 changes: 61 additions & 5 deletions src/Rings/mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,70 @@ using .Orderings
#type for orderings, use this...
#in general: all algos here needs revision: do they benefit from gb or not?

@doc raw"""
default_ordering(R::MPolyRing)
Return the monomial ordering that is used for computations with ideals in `R`
if no other ordering is specified -- either directly by the user or by
requirements of a specific algorithm.
"""
@attr MonomialOrdering{T} function default_ordering(R::T) where {T<:MPolyRing}
return degrevlex(R)
end

# Only for internal use
function set_default_ordering!(R::MPolyRing, o::MonomialOrdering)
@assert R === base_ring(o)
set_attribute!(R, :default_ordering, o)
return nothing
end

@doc raw"""
with_ordering(f, R::MPolyRing, o::MonomialOrdering)
Use the monomial ordering `o` for computations in `R` during the execution of
`f`.
This may be used with `do` block syntax, see the example.
This functionality is meant for advanced users. In general it should not be
necessary to explicitly set a monomial ordering.
Further, there is no guarantee that `o` is actually used. For example, if an
algorithm requires an elimination ordering, `o` might be ignored.
# Example
```jldoctest withordering
julia> R, (x, y, z) = QQ["x", "y", "z"];
julia> f = x + y^2;
julia> I = ideal(R, [y^2 - z, x - z^2]);
julia> normal_form(f, I) # this uses degrevlex
x + z
julia> with_ordering(R, lex(R)) do
# this uses lex
normal_form(f, I)
end
z^2 + z
```
Notice that in this small example we could have achieved the same by using the
keyword argument `ordering`:
```jldoctest withordering
julia> normal_form(f, I, ordering = lex(R))
z^2 + z
```
"""
function with_ordering(f, R::MPolyRing, o::MonomialOrdering)
old = default_ordering(R)
set_default_ordering!(R, o)
x = try
f()
finally
set_default_ordering!(R, old)
end
return x
end

mutable struct BiPolyArray{S}
Ox::NCRing #Oscar Poly Ring or Algebra
Expand Down Expand Up @@ -301,7 +361,7 @@ function singular_generators(B::IdealGens, monorder::MonomialOrdering=default_or
end

@doc raw"""
set_ordering(I::IdealGens, monord::MonomialOrdering)
set_ordering(I::IdealGens, monord::MonomialOrdering)
Return an ideal generating system with an associated monomial ordering.
Expand Down Expand Up @@ -1216,7 +1276,3 @@ function hessian_matrix(f::MPolyRingElem)
end

hessian(f::MPolyRingElem) = det(hessian_matrix(f))

function set_default_ordering!(S::MPolyRing, ord::MonomialOrdering)
set_attribute!(S, :default_ordering, ord)
end
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,7 @@ export weight_ordering
export weighted_projective_space
export weyl_algebra
export weyl_vector
export with_ordering
export witt_index
export wreath_product
export write_as_full
Expand Down
21 changes: 18 additions & 3 deletions test/Rings/mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,22 @@ end
@testset "default ordering" begin
R, _ = QQ["x", "y", "z"]
S, _ = grade(R, [2, 1, 2])
# test type stability
@inferred default_ordering(R)
@inferred default_ordering(S)
for T in [R, S]
x, y, z = gens(T)
f = x + y^2
I = ideal(T, [y^2 - z, x - z])
old_default = @inferred default_ordering(T)
f = with_ordering(T, invlex(T)) do
normal_form(f, I)
end
@test f == normal_form(f, I, ordering = invlex(T))
@test default_ordering(T) == old_default

# Make sure the ordering is reset in case of an error
# The `@test_throws` is just here to catch the error
@test_throws ErrorException with_ordering(T, invlex(T)) do
error()
end
@test default_ordering(T) == old_default
end
end

0 comments on commit a087170

Please sign in to comment.