Skip to content

Commit 32391ed

Browse files
authored
Deprecate compare (#317)
* Deprecate compare * Fix
1 parent b68fbcb commit 32391ed

File tree

4 files changed

+119
-83
lines changed

4 files changed

+119
-83
lines changed

src/comparison.jl

Lines changed: 96 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,31 @@ 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+
# We can't write this with a type instead of an instance so this motivates
192+
# why we work with instances and not types even if they don't have any data
193+
# that's not already in the type.
194+
# This is also to be consistent with `StarAlgebras.MultiplicativeStructure`
195+
(ordering::AbstractMonomialOrdering)(i, j) = cmp(ordering, i, j) < 0
189196

190197
"""
191198
struct LexOrder <: AbstractMonomialOrdering end
@@ -202,8 +209,8 @@ struct LexOrder <: AbstractMonomialOrdering end
202209

203210
const _TupleOrVector = Union{Tuple,AbstractVector}
204211

205-
function compare(exp1::_TupleOrVector, exp2::_TupleOrVector, ::Type{LexOrder})
206-
return Base.cmp(exp1, exp2)
212+
function Base.cmp(::LexOrder, exp1::_TupleOrVector, exp2::_TupleOrVector)
213+
return cmp(exp1, exp2)
207214
end
208215

209216
"""
@@ -228,12 +235,8 @@ struct InverseLexOrder <: AbstractMonomialOrdering end
228235
# so not `cmp` methods is defined for it.
229236
_rev(v::AbstractVector) = view(v, lastindex(v):-1:firstindex(v))
230237
_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)
238+
function Base.cmp(::InverseLexOrder, exp1::_TupleOrVector, exp2::_TupleOrVector)
239+
return cmp(_rev(exp1), _rev(exp2))
237240
end
238241

239242
"""
@@ -248,30 +251,13 @@ Monomial ordering defined by:
248251
struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
249252
same_degree_ordering::O
250253
end
254+
Graded{O}() where {O<:AbstractMonomialOrdering} = Graded{O}(O())
251255

252-
function compare(
253-
a::_TupleOrVector,
254-
b::_TupleOrVector,
255-
::Type{Graded{O}},
256-
) where {O}
256+
function Base.cmp(ordering::Graded, a::_TupleOrVector, b::_TupleOrVector)
257257
deg_a = sum(a)
258258
deg_b = sum(b)
259259
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)
260+
return cmp(ordering.same_degree_ordering, a, b)
275261
else
276262
return deg_a - deg_b
277263
end
@@ -283,7 +269,7 @@ end
283269
end
284270
285271
Monomial ordering defined by
286-
`compare(a, b, ::Type{Reverse{O}}) where {O} = compare(b, a, O)`.
272+
`cmp(o::Reverse, a, b) where {O} = cmp(o.reverse_order, b, a)`.
287273
288274
Reverse Lex Order defined in [CLO13, Exercise 2.2.9, p. 61] where it is abbreviated as *rinvlex*.
289275
can be obtained as `Reverse{InverseLexOrder}`.
@@ -298,27 +284,18 @@ Springer Science & Business Media, **2013**.
298284
struct Reverse{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
299285
reverse_ordering::O
300286
end
287+
Reverse{O}() where {O<:AbstractMonomialOrdering} = Reverse{O}(O())
301288

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)
289+
function Base.cmp(ordering::Reverse, a::_TupleOrVector, b::_TupleOrVector)
290+
return cmp(ordering.reverse_ordering, b, a)
316291
end
317292

293+
#TODO(breaking) Return an instance, not a type
318294
"""
319-
ordering(p::AbstractPolynomialLike)
295+
ordering(p::AbstractPolynomialLike)::Type{<:AbstractMonomialOrdering}
320296
321-
Returns the [`AbstractMonomialOrdering`](@ref) used for the monomials of `p`.
297+
Returns the [`AbstractMonomialOrdering`](@ref) type to be used to compare
298+
exponent vectors for the monomials of `p`.
322299
"""
323300
function ordering end
324301

@@ -330,10 +307,10 @@ ordering(p::AbstractPolynomialLike) = ordering(typeof(p))
330307
# of x < y is equal to the result of Monomial(x) < Monomial(y)
331308
# Without `Base.@pure`, TypedPolynomials allocates on Julia v1.6
332309
# with `promote(x * y, x)`
333-
Base.@pure function compare(
310+
Base.@pure function Base.cmp(
311+
::AbstractMonomialOrdering,
334312
v1::AbstractVariable,
335313
v2::AbstractVariable,
336-
::Type{<:AbstractMonomialOrdering},
337314
)
338315
return -cmp(name(v1), name(v2))
339316
end
@@ -344,7 +321,7 @@ function compare(
344321
::Type{O},
345322
) where {O<:AbstractMonomialOrdering}
346323
s1, s2 = promote_variables(m1, m2)
347-
return compare(exponents(s1), exponents(s2), O)
324+
return cmp(O(), exponents(s1), exponents(s2))
348325
end
349326

350327
# Implement this to make coefficients be compared with terms.
@@ -358,25 +335,23 @@ end
358335
# less than `b`, they are considered sort of equal.
359336
_cmp_coefficient(a, b) = 0
360337

361-
function compare(
338+
function Base.cmp(
339+
ordering::O,
362340
t1::AbstractTermLike,
363341
t2::AbstractTermLike,
364-
::Type{O},
365342
) where {O<:AbstractMonomialOrdering}
366-
Δ = compare(monomial(t1), monomial(t2), O)
343+
Δ = cmp(ordering, monomial(t1), monomial(t2))
367344
if iszero(Δ)
368345
return _cmp_coefficient(coefficient(t1), coefficient(t2))
369346
end
370347
return Δ
371348
end
372349

373350
function Base.cmp(t1::AbstractTermLike, t2::AbstractTermLike)
374-
return compare(t1, t2, ordering(t1))
351+
return cmp(ordering(t1)(), t1, t2)
375352
end
376-
# TODO for backward compat, remove in next breaking release
377-
compare(t1::AbstractTermLike, t2::AbstractTermLike) = cmp(t1, t2)
378353

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

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