Skip to content

Commit 2cecd59

Browse files
committed
Deprecate compare
1 parent b68fbcb commit 2cecd59

File tree

4 files changed

+115
-84
lines changed

4 files changed

+115
-84
lines changed

src/comparison.jl

Lines changed: 92 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,27 @@ function Base.isapprox(α, q::RationalPoly{C}; kwargs...) where {C}
168168
return isapprox(constant_term(α, q.den), q; kwargs...)
169169
end
170170

171+
# TODO refer to the parallel with `mstructure(p)(e1, e2)` which gives the result
172+
# of multiplying the monomials corresponding to the exponent vectors `e1`
173+
# and `e2`.
171174
"""
172175
abstract type AbstractMonomialOrdering end
173176
174177
Abstract type for monomial ordering as defined in [CLO13, Definition 2.2.1, p. 55]
175178
179+
Given an ordering `ordering::AbstractMonomialOrdering` and vector of exponents `e1`
180+
and `e2`, `cmp(ordering, e1, e2)` returns a negative number if `e1` is before `e2`
181+
in the ordering, a positive number if `e2` is before `e1` and 0 if they are equal.
182+
For convenience, `ordering(e1, e2)` returns a `Bool` indicating whether
183+
`cmp(ordering, e1, e2)` is negative.
184+
176185
[CLO13] Cox, D., Little, J., & OShea, D.
177186
*Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
178187
Springer Science & Business Media, **2013**.
179188
"""
180189
abstract type AbstractMonomialOrdering end
181190

182-
"""
183-
compare(a, b, order::Type{<:AbstractMonomialOrdering})
184-
185-
Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
186-
The comparison is done according to `order`.
187-
"""
188-
function compare end
191+
(ordering::AbstractMonomialOrdering)(i, j) = cmp(ordering, i, j) < 0
189192

190193
"""
191194
struct LexOrder <: AbstractMonomialOrdering end
@@ -202,8 +205,8 @@ struct LexOrder <: AbstractMonomialOrdering end
202205

203206
const _TupleOrVector = Union{Tuple,AbstractVector}
204207

205-
function compare(exp1::_TupleOrVector, exp2::_TupleOrVector, ::Type{LexOrder})
206-
return Base.cmp(exp1, exp2)
208+
function Base.cmp(::LexOrder, exp1::_TupleOrVector, exp2::_TupleOrVector)
209+
return cmp(exp1, exp2)
207210
end
208211

209212
"""
@@ -228,12 +231,8 @@ struct InverseLexOrder <: AbstractMonomialOrdering end
228231
# so not `cmp` methods is defined for it.
229232
_rev(v::AbstractVector) = view(v, lastindex(v):-1:firstindex(v))
230233
_rev(t::Tuple) = reverse(t)
231-
function compare(
232-
exp1::_TupleOrVector,
233-
exp2::_TupleOrVector,
234-
::Type{InverseLexOrder},
235-
)
236-
return compare(_rev(exp1), _rev(exp2), LexOrder)
234+
function Base.cmp(::InverseLexOrder, exp1::_TupleOrVector, exp2::_TupleOrVector)
235+
return cmp(_rev(exp1), _rev(exp2))
237236
end
238237

239238
"""
@@ -248,30 +247,13 @@ Monomial ordering defined by:
248247
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
249248
same_degree_ordering::O
250249
end
250+
Graded{O}() where {O<:AbstractMonomialOrdering} = Graded{O}(O())
251251

252-
function compare(
253-
a::_TupleOrVector,
254-
b::_TupleOrVector,
255-
::Type{Graded{O}},
256-
) where {O}
252+
function Base.cmp(ordering::Graded, a::_TupleOrVector, b::_TupleOrVector)
257253
deg_a = sum(a)
258254
deg_b = sum(b)
259255
if deg_a == deg_b
260-
return compare(a, b, O)
261-
else
262-
return deg_a - deg_b
263-
end
264-
end
265-
# TODO Backward compat, remove
266-
function compare(
267-
a::AbstractMonomial,
268-
b::AbstractMonomial,
269-
::Type{Graded{O}},
270-
) where {O}
271-
deg_a = degree(a)
272-
deg_b = degree(b)
273-
if deg_a == deg_b
274-
return compare(a, b, O)
256+
return cmp(ordering.same_degree_ordering, a, b)
275257
else
276258
return deg_a - deg_b
277259
end
@@ -283,7 +265,7 @@ end
283265
end
284266
285267
Monomial ordering defined by
286-
`compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O)`.
268+
`cmp(o::Reverse, a, b) where {O} = cmp(o.reverse_order, b, a)`.
287269
288270
Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
289271
can be obtained as `Reverse{InverseLexOrder}`.
@@ -298,27 +280,17 @@ Springer Science & Business Media, **2013**.
298280
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
299281
reverse_ordering::O
300282
end
283+
Reverse{O}() where {O<:AbstractMonomialOrdering} = Reverse{O}(O())
301284

302-
function compare(
303-
a::_TupleOrVector,
304-
b::_TupleOrVector,
305-
::Type{Reverse{O}},
306-
) where {O}
307-
return compare(b, a, O)
308-
end
309-
# TODO Backward compat, remove
310-
function compare(
311-
a::AbstractMonomial,
312-
b::AbstractMonomial,
313-
::Type{Reverse{O}},
314-
) where {O}
315-
return compare(b, a, O)
285+
function Base.cmp(ordering::Reverse, a::_TupleOrVector, b::_TupleOrVector)
286+
return cmp(ordering.reverse_ordering, b, a)
316287
end
317288

318289
"""
319-
ordering(p::AbstractPolynomialLike)
290+
ordering(p::AbstractPolynomialLike)::Type{<:AbstractMonomialOrdering}
320291
321-
Returns the [`AbstractMonomialOrdering`](@ref) used for the monomials of `p`.
292+
Returns the [`AbstractMonomialOrdering`](@ref) type to be used to compare
293+
exponent vectors for the monomials of `p`.
322294
"""
323295
function ordering end
324296

@@ -330,18 +302,18 @@ ordering(p::AbstractPolynomialLike) = ordering(typeof(p))
330302
# of x < y is equal to the result of Monomial(x) < Monomial(y)
331303
# Without `Base.@pure`, TypedPolynomials allocates on Julia v1.6
332304
# with `promote(x * y, x)`
333-
Base.@pure function compare(
305+
Base.@pure function Base.cmp(
306+
::AbstractMonomialOrdering,
334307
v1::AbstractVariable,
335308
v2::AbstractVariable,
336-
::Type{<:AbstractMonomialOrdering},
337309
)
338310
return -cmp(name(v1), name(v2))
339311
end
340312

341-
function compare(
313+
function Base.cmp(
314+
::Type{O},
342315
m1::AbstractMonomial,
343316
m2::AbstractMonomial,
344-
::Type{O},
345317
) where {O<:AbstractMonomialOrdering}
346318
s1, s2 = promote_variables(m1, m2)
347319
return compare(exponents(s1), exponents(s2), O)
@@ -358,25 +330,23 @@ end
358330
# less than `b`, they are considered sort of equal.
359331
_cmp_coefficient(a, b) = 0
360332

361-
function compare(
333+
function Base.cmp(
334+
ordering::O,
362335
t1::AbstractTermLike,
363336
t2::AbstractTermLike,
364-
::Type{O},
365337
) where {O<:AbstractMonomialOrdering}
366-
Δ = compare(monomial(t1), monomial(t2), O)
338+
Δ = cmp(ordering, monomial(t1), monomial(t2))
367339
if iszero(Δ)
368340
return _cmp_coefficient(coefficient(t1), coefficient(t2))
369341
end
370342
return Δ
371343
end
372344

373345
function Base.cmp(t1::AbstractTermLike, t2::AbstractTermLike)
374-
return compare(t1, t2, ordering(t1))
346+
return cmp(ordering(t1)(), t1, t2)
375347
end
376-
# TODO for backward compat, remove in next breaking release
377-
compare(t1::AbstractTermLike, t2::AbstractTermLike) = cmp(t1, t2)
378348

379-
Base.isless(t1::AbstractTermLike, t2::AbstractTermLike) = cmp(t1, t2) < 0
349+
Base.isless(t1::AbstractTermLike, t2::AbstractTermLike) = compare(t1, t2) < 0
380350

381351
_last_lex_index(n, ::Type{LexOrder}) = n
382352
_prev_lex_index(i, ::Type{LexOrder}) = i - 1
@@ -573,3 +543,62 @@ function Base.iterate(it::ExponentsIterator, state)
573543
end
574544
return state[1], state
575545
end
546+
547+
# TODO Backward compat, remove the following in next breaking release
548+
"""
549+
compare(a, b, order::Type{<:AbstractMonomialOrdering})
550+
551+
Returns a negative number if `a < b`, a positive number if `a > b` and zero if `a == b`.
552+
The comparison is done according to `order`.
553+
554+
**Warning** This is deprecated, use `cmp(order(), a, b)` instead.
555+
"""
556+
function compare end
557+
558+
function compare(t1::AbstractTermLike, t2::AbstractTermLike)
559+
return compare(t1, t2, ordering(t1))
560+
end
561+
562+
function compare(
563+
e1::_TupleOrVector,
564+
e2::_TupleOrVector,
565+
::Type{O},
566+
) where {O<:AbstractMonomialOrdering}
567+
return cmp(O(), e1, e2)
568+
end
569+
570+
function compare(
571+
t1::AbstractTermLike,
572+
t2::AbstractTermLike,
573+
::Type{O},
574+
) where {O<:AbstractMonomialOrdering}
575+
Δ = compare(monomial(t1), monomial(t2), O)
576+
if iszero(Δ)
577+
return _cmp_coefficient(coefficient(t1), coefficient(t2))
578+
end
579+
return Δ
580+
end
581+
582+
function compare(
583+
a::AbstractMonomial,
584+
b::AbstractMonomial,
585+
::Type{Graded{O}},
586+
) where {O}
587+
deg_a = degree(a)
588+
deg_b = degree(b)
589+
if deg_a == deg_b
590+
return compare(a, b, O)
591+
else
592+
return deg_a - deg_b
593+
end
594+
end
595+
596+
function compare(
597+
a::AbstractMonomial,
598+
b::AbstractMonomial,
599+
::Type{Reverse{O}},
600+
) where {O}
601+
return compare(b, a, O)
602+
end
603+
604+
Base.isless(v1::AbstractVariable, v2::AbstractVariable) = cmp(v1, v2) < 0

src/default_polynomial.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Base.one(p::Polynomial) = one(typeof(p))
9393
Base.zero(::Type{Polynomial{C,T,A}}) where {C,T,A} = Polynomial{C,T,A}(A())
9494
Base.zero(t::Polynomial) = zero(typeof(t))
9595

96-
compare_monomials(a, b) = cmp(monomial(a), monomial(b))
96+
compare_monomials(a, b) = compare(monomial(a), monomial(b))
9797

9898
function join_terms(
9999
terms1::AbstractArray{<:Term},

test/commutativetests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@ for file in readdir(joinpath(@__DIR__, "commutative"))
22
if file == "complex.jl" && !isdefined(Mod, Symbol("@complex_polyvar"))
33
continue
44
end
5+
if file == "mutable_arithmetics.jl"
6+
continue
7+
end
58
include(joinpath(@__DIR__, "commutative", file))
69
end

test/comparison.jl

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ using MultivariatePolynomials
66
function _test(object, M; kws...)
77
it = ExponentsIterator{M}(object; kws...)
88
v = collect(Iterators.take(it, 20))
9-
@test issorted(v, lt = (a, b) -> compare(a, b, M) < 0)
9+
@test issorted(v, lt = (a, b) -> cmp(M(), a, b) < 0)
1010
end
1111

1212
function _test(nvars::Int, M; kws...)
@@ -32,30 +32,29 @@ function test_exponents_iterator()
3232
end
3333

3434
function test_compare()
35-
lex = LexOrder
36-
grlex = Graded{lex}
37-
rinvlex = Reverse{InverseLexOrder}
38-
grevlex = Graded{rinvlex}
39-
@test compare([1, 0, 1], [1, 1, 0], grlex) == -1
40-
@test compare([1, 1, 0], [1, 0, 1], grlex) == 1
35+
lex = LexOrder()
36+
grlex = Graded{LexOrder}()
37+
rinvlex = Reverse{InverseLexOrder}()
38+
grevlex = Graded{Reverse{InverseLexOrder}}()
39+
@test cmp(grlex, [1, 0, 1], [1, 1, 0]) == -1
40+
@test cmp(grlex, [1, 1, 0], [1, 0, 1]) == 1
4141
# [CLO13, p. 58]
42-
@test compare(1:3, [3, 2, 0], lex) < 0
43-
@test compare(1:3, [3, 2, 0], grlex) > 0
44-
@test compare(1:3, [3, 2, 0], rinvlex) < 0
45-
@test compare(1:3, [3, 2, 0], grevlex) > 0
46-
@test compare([1, 2, 4], [1, 1, 5], lex) > 0
47-
@test compare([1, 2, 4], [1, 1, 5], grlex) > 0
48-
@test compare([1, 2, 4], [1, 1, 5], rinvlex) > 0
49-
@test compare([1, 2, 4], [1, 1, 5], grevlex) > 0
42+
@test cmp(lex, 1:3, [3, 2, 0]) < 0
43+
@test cmp(grlex, 1:3, [3, 2, 0]) > 0
44+
@test cmp(rinvlex, 1:3, [3, 2, 0]) < 0
45+
@test cmp(grevlex, 1:3, [3, 2, 0]) > 0
46+
@test cmp(lex, [1, 2, 4], [1, 1, 5]) > 0
47+
@test cmp(grlex, [1, 2, 4], [1, 1, 5]) > 0
48+
@test cmp(rinvlex, [1, 2, 4], [1, 1, 5]) > 0
49+
@test cmp(grevlex, [1, 2, 4], [1, 1, 5]) > 0
5050
# [CLO13, p. 59]
51-
@test compare((5, 1, 1), (4, 1, 2), lex) > 0
52-
@test compare((5, 1, 1), (4, 1, 2), grlex) > 0
53-
@test compare((5, 1, 1), (4, 1, 2), rinvlex) > 0
54-
@test compare((5, 1, 1), (4, 1, 2), grevlex) > 0
51+
@test cmp(lex, (5, 1, 1), (4, 1, 2)) > 0
52+
@test cmp(grlex, (5, 1, 1), (4, 1, 2)) > 0
53+
@test cmp(rinvlex, (5, 1, 1), (4, 1, 2)) > 0
54+
@test cmp(grevlex, (5, 1, 1), (4, 1, 2)) > 0
5555
# [CLO13] Cox, D., Little, J., & OShea, D.
5656
# *Ideals, varieties, and algorithms: an introduction to computational algebraic geometry and commutative algebra*.
5757
# Springer Science & Business Media, **2013**.
58-
5958
end
6059

6160
function runtests()

0 commit comments

Comments
 (0)