Skip to content

Commit e31f28a

Browse files
authored
Compare with type (#257)
* Compare with type * Fixes * Fix format
1 parent 8767e3e commit e31f28a

File tree

5 files changed

+181
-106
lines changed

5 files changed

+181
-106
lines changed

src/comparison.jl

+144
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export isapproxzero
22

3+
export LexOrder, InverseLexOrder, Reverse, Graded
4+
35
Base.iszero(v::AbstractVariable) = false
46
Base.iszero(m::AbstractMonomial) = false
57
Base.iszero(t::AbstractTerm) = iszero(coefficient(t))
@@ -169,3 +171,145 @@ end
169171
function Base.isapprox(α, q::RationalPoly{C}; kwargs...) where {C}
170172
return isapprox(constant_term(α, q.den), q; kwargs...)
171173
end
174+
175+
"""
176+
abstract type AbstractMonomialOrdering end
177+
178+
Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55]
179+
180+
[CLO13] Cox, D., Little, J., & OShea, D.
181+
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
182+
Springer Science & Business Media, **2013**.
183+
"""
184+
abstract type AbstractMonomialOrdering end
185+
186+
"""
187+
compare(a, b, order::Type{<:AbstractMonomialOrdering})
188+
189+
Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
190+
The comparison is done according to `order`.
191+
"""
192+
function compare end
193+
194+
"""
195+
struct LexOrder <: AbstractMonomialOrdering end
196+
197+
Lexicographic (Lex for short) Order often abbreviated as *lex* order as defined in [CLO13, Definition 2.2.3, p. 56]
198+
199+
The [`Graded`](@ref) version is often abbreviated as *grlex* order and is defined in [CLO13, Definition 2.2.5, p. 58]
200+
201+
[CLO13] Cox, D., Little, J., & OShea, D.
202+
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
203+
Springer Science & Business Media, **2013**.
204+
"""
205+
struct LexOrder <: AbstractMonomialOrdering end
206+
207+
function compare(
208+
exp1::AbstractVector{T},
209+
exp2::AbstractVector{T},
210+
::Type{LexOrder},
211+
) where {T}
212+
if eachindex(exp1) != eachindex(exp2)
213+
throw(
214+
ArgumentError(
215+
"Cannot compare exponent vectors `$exp1` and `$exp2` of different indices.",
216+
),
217+
)
218+
end
219+
@inbounds for i in eachindex(exp1)
220+
Δ = exp1[i] - exp2[i]
221+
if !iszero(Δ)
222+
return Δ
223+
end
224+
end
225+
return zero(T)
226+
end
227+
228+
"""
229+
struct InverseLexOrder <: AbstractMonomialOrdering end
230+
231+
Inverse Lex Order defined in [CLO13, Exercise 2.2.6, p. 61] where it is abbreviated as *invlex*.
232+
It corresponds to [`LexOrder`](@ref) but with the variables in reverse order.
233+
234+
The [`Graded`](@ref) version can be abbreviated as *grinvlex* order.
235+
It is defined in [BDD13, Definition 2.1] where it is called *Graded xel order*.
236+
237+
[CLO13] Cox, D., Little, J., & OShea, D.
238+
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
239+
Springer Science & Business Media, **2013**.
240+
[BDD13] Batselier, K., Dreesen, P., & De Moor, B.
241+
*The geometry of multivariate polynomial division and elimination*.
242+
SIAM Journal on Matrix Analysis and Applications, 34(1), 102-125, *2013*.
243+
"""
244+
struct InverseLexOrder <: AbstractMonomialOrdering end
245+
246+
function compare(
247+
exp1::AbstractVector{T},
248+
exp2::AbstractVector{T},
249+
::Type{InverseLexOrder},
250+
) where {T}
251+
if eachindex(exp1) != eachindex(exp2)
252+
throw(
253+
ArgumentError(
254+
"Cannot compare exponent vectors `$exp1` and `$exp2` of different indices.",
255+
),
256+
)
257+
end
258+
@inbounds for i in Iterators.Reverse(eachindex(exp1))
259+
Δ = exp1[i] - exp2[i]
260+
if !iszero(Δ)
261+
return Δ
262+
end
263+
end
264+
return zero(T)
265+
end
266+
267+
"""
268+
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
269+
same_degree_ordering::O
270+
end
271+
272+
Monomial ordering defined by:
273+
* `degree(a) == degree(b)` then the ordering is determined by `same_degree_ordering`,
274+
* otherwise, it is the ordering between the integers `degree(a)` and `degree(b)`.
275+
"""
276+
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
277+
same_degree_ordering::O
278+
end
279+
280+
_deg(exponents) = sum(exponents)
281+
_deg(mono::AbstractMonomial) = degree(mono)
282+
283+
function compare(a, b, ::Type{Graded{O}}) where {O}
284+
deg_a = _deg(a)
285+
deg_b = _deg(b)
286+
if deg_a == deg_b
287+
return compare(a, b, O)
288+
else
289+
return deg_a - deg_b
290+
end
291+
end
292+
293+
"""
294+
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
295+
reverse_order::O
296+
end
297+
298+
Monomial ordering defined by
299+
`compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O)`.
300+
301+
Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
302+
can be obtained as `Reverse(InverseLexOrder())`.
303+
304+
The Graded Reverse Lex Order often abbreviated as *grevlex* order defined in [CLO13, Definition 2.2.6, p. 58]
305+
can be obtained as `Graded(Reverse(InverseLexOrder()))`.
306+
307+
[CLO13] Cox, D., Little, J., & OShea, D.
308+
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
309+
Springer Science & Business Media, **2013**.
310+
"""
311+
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
312+
reverse_ordering::O
313+
end
314+
315+
compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O)

src/default_polynomial.jl

+3-5
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,6 @@ function MA.mutable_copy(p::VectorPolynomial{C,TT}) where {C,TT}
272272
end
273273
Base.copy(p::VectorPolynomial) = MA.mutable_copy(p)
274274

275-
function grlex end
276-
277275
function __polynomial_merge!(
278276
op::MA.AddSubMul,
279277
p::Polynomial{T,TT},
@@ -290,7 +288,7 @@ function __polynomial_merge!(
290288
if tp isa Int && j isa Int
291289
tp = get1(tp)
292290
end
293-
grlex(monomial(*(monomials(q)[j], monomial.(t)...)), monomial(tp))
291+
compare(monomial(*(monomials(q)[j], monomial.(t)...)), monomial(tp))
294292
end
295293
end
296294
get2 = let t = t, q = q
@@ -381,7 +379,7 @@ function __polynomial_merge!(
381379
if tp isa Int && j isa Int
382380
tp = get1(tp)
383381
end
384-
grlex(monomial(monomial(t) * monomials(q)[j]), monomial(tp))
382+
compare(monomial(monomial(t) * monomials(q)[j]), monomial(tp))
385383
end
386384
end
387385
get2 = let t = t, q = q
@@ -456,7 +454,7 @@ function __polynomial_merge!(
456454
if t isa Int && j isa Int
457455
t = get1(t)
458456
end
459-
grlex(monomials(q)[j], monomial(t))
457+
compare(monomials(q)[j], monomial(t))
460458
end
461459
end
462460
get2 = let q = q

src/default_term.jl

-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ combine(t1::Term, t2::Term) = combine(promote(t1, t2)...)
7070
function combine(t1::T, t2::T) where {T<:Term}
7171
return Term(t1.coefficient + t2.coefficient, t1.monomial)
7272
end
73-
compare(t1::Term, t2::Term) = monomial(t1) < monomial(t2)
7473
function MA.promote_operation(
7574
::typeof(combine),
7675
::Type{Term{S,M1}},

src/monomial_vector.jl

-100
Original file line numberDiff line numberDiff line change
@@ -4,106 +4,6 @@ export monomial_vector,
44
sort_monomial_vector,
55
merge_monomial_vectors
66

7-
export LexOrder, InverseLexOrder, Reverse, Graded
8-
9-
"""
10-
abstract type AbstractMonomialOrdering end
11-
12-
Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55]
13-
14-
[CLO13] Cox, D., Little, J., & OShea, D.
15-
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
16-
Springer Science & Business Media, **2013**.
17-
"""
18-
abstract type AbstractMonomialOrdering end
19-
20-
"""
21-
compare(a, b, order::AbstractMonomialOrdering)
22-
23-
Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
24-
"""
25-
function compare end
26-
27-
"""
28-
struct LexOrder <: AbstractMonomialOrdering end
29-
30-
Lexicographic (Lex for short) Order often abbreviated as *lex* order as defined in [CLO13, Definition 2.2.3, p. 56]
31-
32-
The [`Graded`](@ref) version is often abbreviated as *grlex* order and is defined in [CLO13, Definition 2.2.5, p. 58]
33-
34-
[CLO13] Cox, D., Little, J., & OShea, D.
35-
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
36-
Springer Science & Business Media, **2013**.
37-
"""
38-
struct LexOrder <: AbstractMonomialOrdering end
39-
40-
"""
41-
struct InverseLexOrder <: AbstractMonomialOrdering end
42-
43-
Inverse Lex Order defined in [CLO13, Exercise 2.2.6, p. 61] where it is abbreviated as *invlex*.
44-
It corresponds to [`LexOrder`](@ref) but with the variables in reverse order.
45-
46-
The [`Graded`](@ref) version can be abbreviated as *grinvlex* order.
47-
It is defined in [BDD13, Definition 2.1] where it is called *Graded xel order*.
48-
49-
[CLO13] Cox, D., Little, J., & OShea, D.
50-
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
51-
Springer Science & Business Media, **2013**.
52-
[BDD13] Batselier, K., Dreesen, P., & De Moor, B.
53-
*The geometry of multivariate polynomial division and elimination*.
54-
SIAM Journal on Matrix Analysis and Applications, 34(1), 102-125, *2013*.
55-
"""
56-
struct InverseLexOrder <: AbstractMonomialOrdering end
57-
58-
"""
59-
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
60-
same_degree_ordering::O
61-
end
62-
63-
Monomial ordering defined by:
64-
* `degree(a) == degree(b)` then the ordering is determined by `same_degree_ordering`,
65-
* otherwise, it is the ordering between the integers `degree(a)` and `degree(b)`.
66-
"""
67-
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
68-
same_degree_ordering::O
69-
end
70-
71-
_deg(exponents) = sum(exponents)
72-
_deg(mono::AbstractMonomial) = degree(mono)
73-
74-
function compare(a, b, ordering::Graded)
75-
deg_a = _deg(a)
76-
deg_b = _deg(b)
77-
if deg_a == deg_b
78-
return compare(a, b, ordering.same_degree_ordering)
79-
else
80-
return deg_a - deg_b
81-
end
82-
end
83-
84-
"""
85-
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
86-
reverse_order::O
87-
end
88-
89-
Monomial ordering defined by `compare(a, b, order) = compare(b, a, order.reverse_order)`..
90-
91-
Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
92-
can be obtained as `Reverse(InverseLexOrder())`.
93-
94-
The Graded Reverse Lex Order often abbreviated as *grevlex* order defined in [CLO13, Definition 2.2.6, p. 58]
95-
can be obtained as `Graded(Reverse(InverseLexOrder()))`.
96-
97-
[CLO13] Cox, D., Little, J., & OShea, D.
98-
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
99-
Springer Science & Business Media, **2013**.
100-
"""
101-
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
102-
reverse_ordering::O
103-
end
104-
105-
compare(a, b, ordering::Reverse) = compare(b, a, ordering.reverse_ordering)
106-
1077
function monomials(v::AbstractVariable, degree, args...)
1088
return monomials((v,), degree, args...)
1099
end

test/comparison.jl

+34
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,38 @@
141141
@test p !== nothing
142142
@test p !== Dict{Int,Int}()
143143
end
144+
@testset "compare" begin
145+
lex = LexOrder
146+
grlex = Graded{lex}
147+
rinvlex = Reverse{InverseLexOrder}
148+
grevlex = Graded{rinvlex}
149+
@test MP.compare([1, 0, 1], [1, 1, 0], grlex) == -1
150+
@test MP.compare([1, 1, 0], [1, 0, 1], grlex) == 1
151+
Mod.@polyvar x y z
152+
# [CLO13, p. 58]
153+
@test MP.compare(1:3, [3, 2, 0], lex) < 0
154+
@test MP.compare(1:3, [3, 2, 0], grlex) > 0
155+
@test MP.compare(1:3, [3, 2, 0], rinvlex) < 0
156+
@test MP.compare(1:3, [3, 2, 0], grevlex) > 0
157+
@test MP.compare([1, 2, 4], [1, 1, 5], lex) > 0
158+
@test MP.compare([1, 2, 4], [1, 1, 5], grlex) > 0
159+
@test MP.compare([1, 2, 4], [1, 1, 5], rinvlex) > 0
160+
@test MP.compare([1, 2, 4], [1, 1, 5], grevlex) > 0
161+
@test MP.compare(x * y^2 * z^3, x^3 * y^2, lex) < 0
162+
@test MP.compare(x * y^2 * z^3, x^3 * y^2, grlex) > 0
163+
@test MP.compare(x * y^2 * z^3, x^3 * y^2, rinvlex) < 0
164+
@test MP.compare(x * y^2 * z^3, x^3 * y^2, grevlex) > 0
165+
@test MP.compare(x * y^2 * z^4, x * y * z^5, lex) > 0
166+
@test MP.compare(x * y^2 * z^4, x * y * z^5, grlex) > 0
167+
@test MP.compare(x * y^2 * z^4, x * y * z^5, rinvlex) > 0
168+
@test MP.compare(x * y^2 * z^4, x * y * z^5, grevlex) > 0
169+
# [CLO13, p. 59]
170+
@test MP.compare(x^5 * y * z, x^4 * y * z^2, lex) > 0
171+
@test MP.compare(x^5 * y * z, x^4 * y * z^2, grlex) > 0
172+
@test MP.compare(x^5 * y * z, x^4 * y * z^2, rinvlex) > 0
173+
@test MP.compare(x^5 * y * z, x^4 * y * z^2, grevlex) > 0
174+
# [CLO13] Cox, D., Little, J., & OShea, D.
175+
# *Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
176+
# Springer Science & Business Media, **2013**.
177+
end
144178
end

0 commit comments

Comments
 (0)