Skip to content

Use cmp instead of compare #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,18 @@ jobs:
os: ubuntu-latest
arch: x64
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
with:
depwarn: error
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
- uses: codecov/codecov-action@v4
with:
file: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
MultivariatePolynomials = "0.5.6"
MultivariatePolynomials = "0.5.9"
MutableArithmetics = "1"
Reexport = "1"
julia = "1"
Expand Down
117 changes: 9 additions & 108 deletions src/comp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Base.==

# TODO This should be in Base with T instead of Variable{V,M}.
# See https://github.com/blegat/MultivariatePolynomials.jl/issues/3
function (==)(x::Vector{Variable{V,M}}, y::Vector{Variable{V,M}}) where {V,M}
function Base.:(==)(x::Vector{Variable{V,M}}, y::Vector{Variable{V,M}}) where {V,M}
if length(x) != length(y)
false
else
Expand All @@ -20,119 +20,20 @@ end

const AnyCommutative{O} = Union{Commutative{O},NonCommutative{O}}

function (==)(
x::Variable{<:AnyCommutative{CreationOrder}},
y::Variable{<:AnyCommutative{CreationOrder}},
)
return x.variable_order.order.id == y.variable_order.order.id &&
x.kind == y.kind
end

function Base.isless(
function Base.cmp(
x::Variable{<:AnyCommutative{CreationOrder}},
y::Variable{<:AnyCommutative{CreationOrder}},
)
if x.variable_order.order.id == y.variable_order.order.id
return isless(y.kind, x.kind)
return cmp(y.kind, x.kind)
else
return isless(y.variable_order.order.id, x.variable_order.order.id)
end
end

# Comparison of Monomial

function MP.compare(x::Monomial{V,M}, y::Monomial{V,M}) where {V,M}
return MP.compare(x, y, M)
end

function MP.compare(
x::Monomial{V},
y::Monomial{V},
::Type{MP.InverseLexOrder},
) where {V}
i = MP.nvariables(x)
j = MP.nvariables(y)
@inbounds while i >= 1 && j >= 1
if x.vars[i] < y.vars[j]
if x.z[i] == 0
i -= 1
else
return 1
end
elseif x.vars[i] > y.vars[j]
if y.z[j] == 0
j -= 1
else
return -1
end
elseif x.z[i] != y.z[j]
return x.z[i] - y.z[j]
else
i -= 1
j -= 1
end
return cmp(y.variable_order.order.id, x.variable_order.order.id)
end
return 0
end

function MP.compare(
x::Monomial{V},
y::Monomial{V},
::Type{MP.LexOrder},
) where {V}
i = j = 1
@inbounds while i <= nvariables(x) && j <= nvariables(y)
if x.vars[i] > y.vars[j]
if x.z[i] == 0
i += 1
else
return 1
end
elseif x.vars[i] < y.vars[j]
if y.z[j] == 0
j += 1
else
return -1
end
elseif x.z[i] != y.z[j]
return x.z[i] - y.z[j]
else
i += 1
j += 1
end
end
@inbounds while i <= nvariables(x)
if x.z[i] > 0
return 1
end
i += 1
end
@inbounds while j <= nvariables(y)
if y.z[j] > 0
return -1
end
j += 1
end
return 0
end

function (==)(x::Monomial{V,M}, y::Monomial{V,M}) where {V,M}
return MP.compare(x, y) == 0
end
function (==)(x::Variable{V,M}, y::Monomial{V,M}) where {V,M}
return convert(Monomial{V,M}, x) == y
end

# graded lex ordering
function Base.isless(x::Monomial{V,M}, y::Monomial{V,M}) where {V,M}
return MP.compare(x, y) < 0
end
function Base.isless(x::Monomial{V,M}, y::Variable{V,M}) where {V,M}
return isless(x, convert(Monomial{V,M}, y))
end
function Base.isless(x::Variable{V,M}, y::Monomial{V,M}) where {V,M}
return isless(convert(Monomial{V,M}, x), y)
end
# TODO remove
Base.:(==)(x::Variable, y::Variable) = iszero(cmp(x, y))
Base.:(==)(x::Monomial, y::Monomial) = iszero(cmp(x, y))

# Comparison of MonomialVector
function (==)(x::MonomialVector{V,M}, y::MonomialVector{V,M}) where {V,M}
Expand All @@ -143,8 +44,8 @@ function (==)(x::MonomialVector{V,M}, y::MonomialVector{V,M}) where {V,M}
# Should be sorted in the same order since the non-common
# polyvar should have exponent 0
for (a, b) in zip(x.Z, y.Z)
A = zeros(length(allvars))
B = zeros(length(allvars))
A = zeros(Int, length(allvars))
B = zeros(Int, length(allvars))
A[maps[1]] = a
B[maps[2]] = b
if A != B
Expand Down
112 changes: 29 additions & 83 deletions src/monomial_vector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -148,62 +148,6 @@ function _error_for_negative_degree(deg)
end
end

const _Lex = Union{MP.LexOrder,MP.InverseLexOrder}

_last_lex_index(n, ::Type{MP.LexOrder}) = n
_prev_lex_index(i, ::Type{MP.LexOrder}) = i - 1
_not_first_indices(n, ::Type{MP.LexOrder}) = n:-1:2
_last_lex_index(_, ::Type{MP.InverseLexOrder}) = 1
_prev_lex_index(i, ::Type{MP.InverseLexOrder}) = i + 1
_not_first_indices(n, ::Type{MP.InverseLexOrder}) = 1:(n-1)

function _fill_exponents!(Z, n, degs, ::Type{Commutative}, M::Type{<:_Lex}, filter::Function)
_error_for_negative_degree.(degs)
maxdeg = maximum(degs, init = 0)
I = _not_first_indices(n, M)
z = zeros(Int, n)
while true
deg = sum(z)
if deg in degs && filter(z)
push!(Z, z)
z = copy(z)
end
if deg == maxdeg
i = findfirst(i -> !iszero(z[i]), I)
if isnothing(i)
break
end
j = I[i]
z[j] = 0
z[_prev_lex_index(j, M)] += 1
else
z[_last_lex_index(n, M)] += 1
end
end
end

function _fill_exponents!(Z, n, deg, ::Type{Commutative}, M::Type{<:_Lex}, filter::Function, ::Int)
_error_for_negative_degree(deg)
I = _not_first_indices(n, M)
z = zeros(Int, n)
z[_last_lex_index(n, M)] = deg
while true
if filter(z)
push!(Z, z)
z = copy(z)
end
i = findfirst(i -> !iszero(z[i]), I)
if isnothing(i)
break
end
j = I[i]
p = z[j]
z[j] = 0
z[_last_lex_index(n, M)] = p - 1
z[_prev_lex_index(j, M)] += 1
end
end

function _fill_noncomm_exponents_rec!(Z, z, i, n, deg, ::Type{MP.LexOrder}, filter::Function)
if deg == 0
if filter(z)
Expand Down Expand Up @@ -235,13 +179,6 @@ function _fill_exponents!(
return reverse!(view(Z, start:length(Z)))
end

function _fill_exponents!(Z, n, deg, ::Type{V}, ::Type{MP.Reverse{M}}, args...) where {V,M}
prev = lastindex(Z)
_fill_exponents!(Z, n, deg, V, M, args...)
reverse!(view(Z, (prev + 1):lastindex(Z)))
return
end

function _fill_exponents!(
Z::Vector{Vector{Int}},
n,
Expand All @@ -266,7 +203,7 @@ function _all_exponents(
::Type{M},
filter::Function,
) where {V,M}
Z = Vector{Vector{Int}}()
Z = Vector{Int}[]
_fill_exponents!(Z, n, degs, V, M, filter)
_isless = let M = M
(a, b) -> MP.compare(a, b, M) < 0
Expand All @@ -275,28 +212,11 @@ function _all_exponents(
return Z
end

function MonomialVector(
vars::Vector{<:Variable{<:Commutative,M}},
degs::AbstractVector{Int},
filter::Function = x -> true,
) where {M}
vars = unique!(sort(vars, rev = true))
return MonomialVector(
vars,
_all_exponents(
length(vars),
degs,
Commutative,
M,
z -> filter(Monomial(vars, z)),
),
)
end

function getvarsforlength(vars::Vector{<:Variable{<:NonCommutative}}, len::Int)
n = length(vars)
return map(i -> vars[((i-1)%n)+1], 1:len)
end

function MonomialVector(
vars::Vector{<:Variable{<:NonCommutative,M}},
degs::AbstractVector{Int},
Expand All @@ -313,6 +233,31 @@ function MonomialVector(
v = isempty(Z) ? vars : getvarsforlength(vars, length(first(Z)))
return MonomialVector(v, Z)
end

function MonomialVector(
vars::Vector{<:Variable{<:Commutative,M}},
degs::AbstractVector{Int},
filter::Function = x -> true,
) where {M}
vars = unique!(sort(vars, rev = true))
if isempty(degs)
mindegree = 0
maxdegree = -1
else
mindegree = minimum(degs)
maxdegree = maximum(degs)
end
Z = Iterators.Filter(MP.ExponentsIterator{M}(
zeros(Int, length(vars));
mindegree,
maxdegree,
)) do z
mono = Monomial(vars, z)
MP.degree(mono) in degs && filter(mono)
end
return MonomialVector(vars, collect(Z))
end

function MonomialVector(
vars::Vector{<:Variable},
degs::Int,
Expand All @@ -324,6 +269,7 @@ end
function MP.monomials(vars::AbstractVector{<:Variable}, args...)
return MonomialVector(vars, args...)
end

function MP.monomials(vars::Tuple{Vararg{Variable}}, args...)
return monomials([vars...], args...)
end
Expand Down Expand Up @@ -390,7 +336,7 @@ end
function MonomialVector{V,M}(X::DMonoVec{V,M}) where {V,M}
allvars, Z = buildZvarsvec(Variable{V,M}, X)
_isless = let M = M
(a, b) -> MP.compare(a, b, M) < 0
(a, b) -> cmp(M(), a, b) < 0
end
sort!(Z, lt = _isless)
dups = findall(i -> Z[i] == Z[i-1], 2:length(Z))
Expand Down
2 changes: 1 addition & 1 deletion src/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function MA.operate!(
end

function _exponents_compare(q::Polynomial{V,M}, j, e) where {V,M}
return MP.compare(q.x.Z[j], e, M)
return cmp(M(), q.x.Z[j], e)
end

# TODO need to check that this also works for non-commutative
Expand Down
2 changes: 1 addition & 1 deletion src/poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function removedups_to!(
::Type{M},
) where {T,M}
_isless = let M = M
(a, b) -> MP.compare(a, b, M) < 0
(a, b) -> cmp(M(), a, b) < 0
end
σ = sortperm(Zdup, lt = _isless)
i = 0
Expand Down
12 changes: 12 additions & 0 deletions src/promote.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
function MP.promote_variables(m1::Monomial, m2::Monomial)
if MP.variables(m1) == MP.variables(m2)
return m1, m2
end
allvars, maps = mergevars([MP.variables(m1), MP.variables(m2)])
z1 = zeros(Int, length(allvars))
z1[maps[1]] = m1.z
z2 = zeros(Int, length(allvars))
z2[maps[2]] = m2.z
return Monomial(allvars, z1), Monomial(allvars, z2)
end

function MP.promote_rule_constant(
::Type{T},
::Type{<:DMonomialLike{V,M}},
Expand Down
Loading
Loading