Skip to content

Commit

Permalink
Merge pull request #3797 from crisiumnih/numeric_bug
Browse files Browse the repository at this point in the history
Fix incorrect convex hull with -0.0
  • Loading branch information
schillic authored Feb 12, 2025
2 parents 3e335d9 + ab01a1a commit a6c4ec6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/ConcreteOperations/convex_hull.jl
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ function _convex_hull_2d!(points::Vector{VN};
end
end

_zero_abs(x::Number) = x

_zero_abs(x::AbstractFloat) = x == -0.0 ? zero(x) : x

"""
monotone_chain!(points::Vector{VN}; sort::Bool=true
) where {N, VN<:AbstractVector{N}}
Expand Down Expand Up @@ -457,8 +461,10 @@ function monotone_chain!(points::Vector{VN}; sort::Bool=true) where {N,VN<:Abstr
end

if sort
# _zero_abs is necessary because floating-point arithmetic distinguishes
# between 0.0 and -0.0, which leads to incorrect sorting (see #3455)
# sort the points lexicographically
sort!(points; by=x -> (x[1], x[2]))
sort!(points; by=x -> (_zero_abs(x[1]), _zero_abs(x[2])))
end

# build lower hull
Expand Down
5 changes: 5 additions & 0 deletions test/ConcreteOperations/convex_hull.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,9 @@ for N in [Float64, Rational{Int}]
# binary convex hull with an empty set is identical to unary
@test convex_hull(S, EmptySet{N}(1)) == convex_hull(EmptySet{N}(1), S) == S
@test convex_hull(P, EmptySet{N}(2)) == convex_hull(EmptySet{N}(2), P) == Pc

# see #3455
v = [N[-0.0, 2], N[2, 0], N[1, 0], N[0, 1], N[0, 3//2]]
v_ch = [N[0, 1], N[1, 0], N[2, 0], N[-0.0, 2]]
@test convex_hull(v) == v_ch
end

0 comments on commit a6c4ec6

Please sign in to comment.