Skip to content

Commit b439b5b

Browse files
committed
Simplify comparison
1 parent 3a244a9 commit b439b5b

File tree

4 files changed

+57
-36
lines changed

4 files changed

+57
-36
lines changed

src/comparison.jl

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,19 @@ struct Graded{O<:AbstractMonomialOrdering} <: AbstractMonomialOrdering
249249
same_degree_ordering::O
250250
end
251251

252-
_deg(exponents) = sum(exponents)
253-
_deg(mono::AbstractMonomial) = degree(mono)
252+
function compare(a::_TupleOrVector, b::_TupleOrVector, ::Type{Graded{O}}) where {O}
253+
deg_a = sum(a)
254+
deg_b = sum(b)
255+
if deg_a == deg_b
256+
return compare(a, b, O)
257+
else
258+
return deg_a - deg_b
259+
end
260+
end
254261

255-
function compare(a, b, ::Type{Graded{O}}) where {O}
256-
deg_a = _deg(a)
257-
deg_b = _deg(b)
262+
function compare(a::AbstractMonomial, b::AbstractMonomial, ::Type{Graded{O}}) where {O}
263+
deg_a = degree(a)
264+
deg_b = degree(b)
258265
if deg_a == deg_b
259266
return compare(a, b, O)
260267
else
@@ -293,6 +300,43 @@ Returns the [`AbstractMonomialOrdering`](@ref) used for the monomials of `p`.
293300
"""
294301
function ordering end
295302

303+
ordering(::Type{P}) where {P} = ordering(monomial_type(P))
304+
ordering(p::AbstractPolynomialLike) = ordering(typeof(p))
305+
306+
# We reverse the order of comparisons here so that the result
307+
# of x < y is equal to the result of Monomial(x) < Monomial(y)
308+
function compare(v1::AbstractVariable, v2::AbstractVariable, ::Type{<:AbstractMonomialOrdering})
309+
return -cmp(name(v1), name(v2))
310+
end
311+
312+
function compare(m1::AbstractMonomial, m2::AbstractMonomial, ::Type{O}) where {O<:AbstractMonomialOrdering}
313+
s1, s2 = promote_variables(m1, m2)
314+
return compare(exponents(s1), exponents(s2), O)
315+
end
316+
317+
# Implement this to make coefficients be compared with terms.
318+
function _cmp_coefficient(a::Real, b::Real)
319+
return cmp(a, b)
320+
end
321+
function _cmp_coefficient(a::Number, b::Number)
322+
return cmp(abs(a), abs(b))
323+
end
324+
# By default, coefficients are not comparable so `a` is not strictly
325+
# less than `b`, they are considered sort of equal.
326+
_cmp_coefficient(a, b) = 0
327+
328+
function compare(t1::AbstractTerm, t2::AbstractTerm, ::Type{O}) where {O<:AbstractMonomialOrdering}
329+
Δ = compare(monomial(t1), monomial(t2), O)
330+
if iszero(Δ)
331+
return _cmp_coefficient(coefficient(t1), coefficient(t2))
332+
end
333+
return Δ
334+
end
335+
336+
Base.cmp(t1::AbstractTermLike, t2::AbstractTermLike) = compare(t1, t2, ordering(t1))
337+
338+
Base.isless(t1::AbstractTermLike, t2::AbstractTermLike) = cmp(t1, t2) < 0
339+
296340
_last_lex_index(n, ::Type{LexOrder}) = n
297341
_prev_lex_index(i, ::Type{LexOrder}) = i - 1
298342
_not_first_indices(n, ::Type{LexOrder}) = n:-1:2

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) = compare(monomial(a), monomial(b))
96+
compare_monomials(a, b) = cmp(monomial(a), monomial(b))
9797

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

src/operators.jl

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,3 @@
1-
# We reverse the order of comparisons here so that the result
2-
# of x < y is equal to the result of Monomial(x) < Monomial(y)
3-
Base.@pure function Base.isless(v1::AbstractVariable, v2::AbstractVariable)
4-
return name(v1) > name(v2)
5-
end
6-
function Base.isless(m1::AbstractTermLike, m2::AbstractTermLike)
7-
return isless(promote(m1, m2)...)
8-
end
9-
10-
# Implement this to make coefficients be compared with terms.
11-
function isless_coefficient(a::Real, b::Real)
12-
return a < b
13-
end
14-
function isless_coefficient(a::Number, b::Number)
15-
return abs(a) < abs(b)
16-
end
17-
# By default, coefficients are not comparable so `a` is not strictly
18-
# less than `b`, they are considered sort of equal.
19-
isless_coefficient(a, b) = false
20-
21-
function Base.isless(t1::AbstractTerm, t2::AbstractTerm)
22-
if monomial(t1) < monomial(t2)
23-
return true
24-
elseif monomial(t1) == monomial(t2)
25-
return isless_coefficient(coefficient(t1), coefficient(t2))
26-
else
27-
return false
28-
end
29-
end
30-
311
# promoting multiplication is not a good idea
322
# For example a polynomial of Float64 * a polynomial of JuMP affine expression
333
# is a polynomial of JuMP affine expression but if we promote it would be a

src/promote.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
promote_variables(p::AbstractPolynomialLike, q::AbstractPolynomialLike)
3+
4+
Return two polynomials over the same variables.
5+
"""
6+
function promote_variables end
7+
18
# MonomialLike
29
Base.promote_rule(::Type{M}, ::Type{M}) where {M<:AbstractMonomialLike} = M
310
function Base.promote_rule(

0 commit comments

Comments
 (0)