Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierHnt committed Feb 3, 2024
1 parent 7c46049 commit 9049ca7
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 99 deletions.
3 changes: 2 additions & 1 deletion src/intervals/arithmetic/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ function Base.inv(x::BareInterval{T}) where {T<:NumTypes}
inf(x) < 0 == sup(x) && return @round(T, typemin(T), inv(inf(x)))
inf(x) == 0 < sup(x) && return @round(T, inv(sup(x)), typemax(T))
inf(x) < 0 < sup(x) && return entireinterval(BareInterval{T})
isthinzero(x) && return div_by_thin_zero(_unsafe_bareinterval(T, one(T), one(T)))
# isthinzero(x)
return div_by_thin_zero(_unsafe_bareinterval(T, one(T), one(T)))
end
return @round(T, inv(sup(x)), inv(inf(x)))
end
Expand Down
5 changes: 2 additions & 3 deletions src/intervals/arithmetic/power.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,8 @@ for f ∈ (:cbrt, :exp, :exp2, :exp10, :expm1)
Base.$f(x::BareInterval{<:Rational}) = $f(float(x))

function Base.$f(x::Interval)
bx = bareinterval(x)
r = $f(bx)
d = min(decoration(r), decoration(x))
r = $f(bareinterval(x))
d = min(decoration(x), decoration(r))
return _unsafe_interval(r, d, isguaranteed(x))
end
end
Expand Down
3 changes: 1 addition & 2 deletions src/intervals/interval_operations/bisect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ function bisect(x::BareInterval{T}, α::Real = 0.5) where {T<:NumTypes}
end

function bisect(x::Interval, α::Real = 0.5)
bx = bareinterval(x)
r₁, r₂ = bisect(bx, α)
r₁, r₂ = bisect(bareinterval(x), α)
d₁, d₂ = min(decoration(x), decoration(r₁)), min(decoration(x), decoration(r₂))
t = isguaranteed(x)
return (_unsafe_interval(r₁, d₁, t), _unsafe_interval(r₂, d₂, t))
Expand Down
165 changes: 86 additions & 79 deletions src/intervals/interval_operations/boolean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ function isequal_interval(x::Interval, y::Interval)
isnai(x) | isnai(y) && return false
return isequal_interval(bareinterval(x), bareinterval(y))
end
isequal_interval(x::Complex{<:Interval}, y::Complex{<:Interval}) = isequal_interval(real(x), real(y)) & isequal_interval(imag(x), imag(y))
isequal_interval(x::Complex{<:Interval}, y::Interval) = isequal_interval(real(x), y) & isthinzero(imag(x))
isequal_interval(x::Interval, y::Complex{<:Interval}) = isequal_interval(x, real(y)) & isthinzero(imag(y))

function isequal_interval(x::AbstractVector, y::AbstractVector)
n = length(x)
m = length(y)
n == m || return throw(DimensionMismatch("dimensions must match: x has length $n, y has length $m"))
return all(t -> isequal_interval(t[1], t[2]), zip(x, y))
end

isequal_interval(x, y, z, w...) = isequal_interval(x, y) & isequal_interval(y, z, w...)
isequal_interval(x::Complex, y::Complex) = isequal_interval(real(x), real(y)) & isequal_interval(imag(x), imag(y))
isequal_interval(x::Complex, y::Real) = isequal_interval(real(x), y) & isthinzero(imag(x))
isequal_interval(x::Real, y::Complex) = isequal_interval(x, real(y)) & isthinzero(imag(y))

isequal_interval(x) = Base.Fix2(isequal_interval, x)

Expand All @@ -41,16 +48,46 @@ function issubset_interval(x::Interval, y::Interval)
isnai(x) | isnai(y) && return false
return issubset_interval(bareinterval(x), bareinterval(y))
end
issubset_interval(x::Complex{<:Interval}, y::Complex{<:Interval}) = issubset_interval(real(x), real(y)) & issubset_interval(imag(x), imag(y))
issubset_interval(x::Complex{<:Interval}, y::Interval) = issubset_interval(real(x), y) & isthinzero(imag(x))
issubset_interval(x::Interval, y::Complex{<:Interval}) = issubset_interval(x, real(y)) & in_interval(0, imag(y))

function issubset_interval(x::AbstractVector, y::AbstractVector)
n = length(x)
m = length(y)
n == m || return throw(DimensionMismatch("dimensions must match: x has length $n, y has length $m"))
return all(t -> issubset_interval(t[1], t[2]), zip(x, y))
end

issubset_interval(x, y, z, w...) = issubset_interval(x, y) & issubset_interval(y, z, w...)
issubset_interval(x::Complex, y::Complex) = issubset_interval(real(x), real(y)) & issubset_interval(imag(x), imag(y))
issubset_interval(x::Complex, y::Real) = issubset_interval(real(x), y) & isthinzero(imag(x))
issubset_interval(x::Real, y::Complex) = issubset_interval(x, real(y)) & in_interval(0, imag(y))

"""
isstrictsubset(x, y)
Test whether `x` is a strict subset of `y`. If `x` and `y` are intervals, this
is semantically equivalent to `isinterior(x, y)`. If `x` and `y` are vectors,
`x` must be a subset of `y` with at least one of their component being a strict
subset.
See also: [`isinterior`](@ref).
"""
isstrictsubset(x::BareInterval, y::BareInterval) = isinterior(x, y)

isstrictsubset(x::Interval, y::Interval) = isinterior(x, y)
isstrictsubset(x::Complex{<:Interval}, y::Complex{<:Interval}) =
(isstrictsubset(real(x), real(y)) & issubset_interval(imag(x), imag(y))) | (issubset_interval(real(x), real(y)) & isstrictsubset(imag(x), imag(y)))
isstrictsubset(x::Complex{<:Interval}, y::Interval) = isstrictsubset(real(x), y) & isthinzero(imag(x))
isstrictsubset(x::Interval, y::Complex{<:Interval}) = isstrictsubset(x, real(y)) & in_interval(0, imag(y))

isstrictsubset(x::AbstractVector, y::AbstractVector) = issubset_interval(x, y) & any(t -> isstrictsubset(t[1], t[2]), zip(x, y))

isstrictsubset(x, y, z, w...) = isstrictsubset(x, y) & isstrictsubset(y, z, w...)

"""
isinterior(x, y)
Test whether `x` is in the interior of `y`.
Test whether `x` is in the interior of `y`. If `x` and `y` are intervals, this
is semantically equivalent to `isstrictsubset(x, y)`.
Implement the `interior` function of the IEEE Standard 1788-2015 (Table 9.3).
Expand All @@ -63,6 +100,9 @@ function isinterior(x::Interval, y::Interval)
isnai(x) | isnai(y) && return false
return isinterior(bareinterval(x), bareinterval(y))
end
isinterior(x::Complex{<:Interval}, y::Complex{<:Interval}) = isinterior(real(x), real(y)) & isinterior(imag(x), imag(y))
isinterior(::Complex{<:Interval}, ::Interval) = false
isinterior(x::Interval, y::Complex{<:Interval}) = isinterior(x, real(y)) & isinterior(zero(x), imag(y))

function isinterior(x::AbstractVector, y::AbstractVector)
n = length(x)
Expand All @@ -72,33 +112,33 @@ function isinterior(x::AbstractVector, y::AbstractVector)
end

isinterior(x, y, z, w...) = isinterior(x, y) & isinterior(y, z, w...)
isinterior(x::Complex, y::Complex) =
(isinterior(real(x), real(y)) & issubset_interval(imag(x), imag(y))) |
(issubset_interval(real(x), real(y)) & isinterior(imag(x), imag(y)))
isinterior(x::Complex, y::Real) = isinterior(real(x), y) & isthinzero(imag(x))
isinterior(x::Real, y::Complex) = isinterior(x, real(y)) & in_interval(0, imag(y))

"""
isstrictsubset(x, y)
isdisjoint_interval(x, y)
Test whether `x` is a strict subset of `y`. If `x` and `y` are intervals, this
is semantically equivalent to `isinterior(x, y)`. If `x` and `y` are vectors, at
least one component of `x` must be in the interior of `y`.
Test whether `x` and `y` have no common elements.
See also: [`isinterior`](@ref).
Implement the `disjoint` function of the IEEE Standard 1788-2015 (Table 9.3).
"""
isstrictsubset(x::BareInterval, y::BareInterval) = isinterior(x, y)
isdisjoint_interval(x::BareInterval, y::BareInterval) =
isempty_interval(x) | isempty_interval(y) | _strictlessprime(sup(y), inf(x)) | _strictlessprime(sup(x), inf(y))

isstrictsubset(x::Interval, y::Interval) = isinterior(x, y)
function isdisjoint_interval(x::Interval, y::Interval)
isnai(x) | isnai(y) && return false
return isdisjoint_interval(bareinterval(x), bareinterval(y))
end
isdisjoint_interval(x::Complex{<:Interval}, y::Complex{<:Interval}) = isdisjoint_interval(real(x), real(y)) | isdisjoint_interval(imag(x), imag(y))
isdisjoint_interval(x::Complex{<:Interval}, y::Interval) = isdisjoint_interval(real(x), y) | !in_interval(0, imag(x))
isdisjoint_interval(x::Interval, y::Complex{<:Interval}) = isdisjoint_interval(x, real(y)) | !in_interval(0, imag(y))

isstrictsubset(x::AbstractVector, y::AbstractVector) = isinterior(x, y) & any(t -> isinterior(t[1], t[2]), zip(x, y))
function isdisjoint_interval(x::AbstractVector, y::AbstractVector)
n = length(x)
m = length(y)
n == m || return throw(DimensionMismatch("dimensions must match: x has length $n, y has length $m"))
return any(t -> isdisjoint_interval(t[1], t[2]), zip(x, y))
end

isstrictsubset(x, y, z, w...) = isstrictsubset(x, y) & isstrictsubset(y, z, w...)
isstrictsubset(x::Complex, y::Complex) =
(isstrictsubset(real(x), real(y)) & issubset_interval(imag(x), imag(y))) |
(issubset_interval(real(x), real(y)) & isstrictsubset(imag(x), imag(y)))
isstrictsubset(x::Complex, y::Real) = isstrictsubset(real(x), y) & isthinzero(imag(x))
isstrictsubset(x::Real, y::Complex) = isstrictsubset(x, real(y)) & in_interval(0, imag(y))
isdisjoint_interval(x, y, z, w...) = isdisjoint_interval(x, y) & isdisjoint_interval(y, z, w...)

"""
isweakless(x, y)
Expand Down Expand Up @@ -159,24 +199,6 @@ function strictprecedes(x::Interval, y::Interval)
return strictprecedes(bareinterval(x), bareinterval(y))
end

"""
isdisjoint_interval(x, y)
Test whether `x` and `y` have no common elements.
Implement the `disjoint` function of the IEEE Standard 1788-2015 (Table 9.3).
"""
isdisjoint_interval(a::BareInterval, b::BareInterval) =
isempty_interval(a) | isempty_interval(b) | _strictlessprime(sup(b), inf(a)) | _strictlessprime(sup(a), inf(b))

function isdisjoint_interval(x::Interval, y::Interval)
isnai(x) | isnai(y) && return false
return isdisjoint_interval(bareinterval(x), bareinterval(y))
end

isdisjoint_interval(x::Complex, y::Complex) =
isdisjoint_interval(real(x), real(y)) | isdisjoint_interval(imag(x), imag(y))

"""
in_interval(x, y)
Expand All @@ -189,22 +211,19 @@ function in_interval(x::Number, y::BareInterval)
return inf(y) x sup(y)
end
in_interval(x::Complex, y::BareInterval) = in_interval(real(x), y) & iszero(imag(x))
in_interval(x::Interval, y::BareInterval) = throw(MethodError(in_interval, (x, y)))
in_interval(::BareInterval, ::BareInterval) =
throw(ArgumentError("`in_interval` is purposely not supported for two interval arguments. See instead `issubset_interval`"))

function in_interval(x::Number, y::Interval)
isnai(y) && return false
return in_interval(x, bareinterval(y))
end

in_interval(::BareInterval, ::BareInterval) =
throw(ArgumentError("`in_interval` is purposely not supported for two interval arguments. See instead `issubset_interval`"))

in_interval(x::Number, y::Complex{<:Interval}) = in_interval(x, real(y)) & in_interval(0, imag(y))
in_interval(x::Complex, y::Complex{<:Interval}) = in_interval(real(x), real(y)) & in_interval(imag(x), imag(y))
in_interval(::Interval, ::Interval) =
throw(ArgumentError("`in_interval` is purposely not supported for two interval arguments. See instead `issubset_interval`"))

in_interval(x::Complex, y::Complex) = in_interval(real(x), real(y)) & in_interval(imag(x), imag(y))
in_interval(x::Complex, y::Number) = in_interval(real(x), y) & iszero(imag(x))
in_interval(x::Number, y::Complex) = in_interval(x, real(y)) & in_interval(0, imag(y))

in_interval(x) = Base.Fix2(in_interval, x)

"""
Expand All @@ -220,8 +239,9 @@ function isempty_interval(x::Interval)
isnai(x) && return false
return isempty_interval(bareinterval(x))
end
isempty_interval(x::Complex{<:Interval}) = isempty_interval(real(x)) | isempty_interval(imag(x))

isempty_interval(x::Complex) = isempty_interval(real(x)) & isempty_interval(imag(x))
isempty_interval(x::AbstractVector) = any(isempty_interval, x)

"""
isentire_interval(x)
Expand All @@ -236,8 +256,7 @@ function isentire_interval(x::Interval)
isnai(x) && return false
return isentire_interval(bareinterval(x))
end

isentire_interval(x::Complex) = isentire_interval(real(x)) & isentire_interval(imag(x))
isentire_interval(x::Complex{<:Interval}) = isentire_interval(real(x)) & isentire_interval(imag(x))

"""
isnai(x)
Expand All @@ -247,8 +266,7 @@ Test whether `x` is an NaI (Not an Interval).
isnai(::BareInterval) = false

isnai(x::Interval) = decoration(x) == ill

isnai(x::Complex) = isnai(real(x)) & isnai(imag(x))
isnai(x::Complex{<:Interval}) = isnai(real(x)) & isnai(imag(x))

"""
isbounded(x)
Expand All @@ -261,8 +279,7 @@ function isbounded(x::Interval)
isnai(x) && return false
return isbounded(bareinterval(x))
end

isbounded(x::Complex) = isbounded(real(x)) & isbounded(imag(x))
isbounded(x::Complex{<:Interval}) = isbounded(real(x)) & isbounded(imag(x))

"""
isunbounded(x)
Expand All @@ -275,8 +292,7 @@ function isunbounded(x::Interval)
isnai(x) && return false
return isunbounded(bareinterval(x))
end

isunbounded(x::Complex) = isunbounded(real(x)) | isunbounded(imag(x))
isunbounded(x::Complex{<:Interval}) = isunbounded(real(x)) | isunbounded(imag(x))

"""
iscommon(x)
Expand All @@ -292,8 +308,7 @@ function iscommon(x::Interval)
isnai(x) && return false
return iscommon(bareinterval(x))
end

iscommon(x::Complex) = iscommon(real(x)) & iscommon(imag(x))
iscommon(x::Complex{<:Interval}) = iscommon(real(x)) & iscommon(imag(x))

"""
isatomic(x)
Expand All @@ -309,8 +324,7 @@ function isatomic(x::Interval)
isnai(x) && return false
return isatomic(bareinterval(x))
end

isatomic(x::Complex) = isatomic(real(x)) & isatomic(imag(x))
isatomic(x::Complex{<:Interval}) = isatomic(real(x)) & isatomic(imag(x))

"""
isthin(x)
Expand All @@ -325,8 +339,7 @@ function isthin(x::Interval)
isnai(x) && return false
return isthin(bareinterval(x))
end

isthin(x::Complex) = isthin(real(x)) & isthin(imag(x))
isthin(x::Complex{<:Interval}) = isthin(real(x)) & isthin(imag(x))

"""
isthin(x, y)
Expand All @@ -335,17 +348,14 @@ Test whether `x` contains only `y`.
"""
isthin(x::BareInterval, y::Number) = inf(x) == sup(x) == y
isthin(x::BareInterval, y::Complex) = isthin(x, real(y)) & iszero(imag(y))
isthin(x::BareInterval, y::Interval) = throw(MethodError(isthin, (x, y)))

function isthin(x::Interval, y::Number)
isnai(x) && return false
return isthin(bareinterval(x), y)
end

isthin(x::Complex, y::Complex) = isthin(real(x), real(y)) & isthin(imag(x), imag(y))
isthin(x::Complex, y::Number) = isthin(real(x), real(y)) & isthinzero(imag(x))
isthin(x::Number, y::Complex) = isthin(real(x), real(y)) & iszero(imag(y))

isthin(x::BareInterval, y::Interval) = throw(MethodError(isthin, (x, y)))
isthin(x::Complex{<:Interval}, y::Number) = isthin(real(x), y) & isthinzero(imag(x))
isthin(x::Complex{<:Interval}, y::Complex) = isthin(real(x), real(y)) & isthin(imag(x), imag(y))

"""
isthinzero(x)
Expand All @@ -358,8 +368,7 @@ function isthinzero(x::Interval)
isnai(x) && return false
return isthinzero(bareinterval(x))
end

isthinzero(x::Complex) = isthinzero(real(x)) & isthinzero(imag(x))
isthinzero(x::Complex{<:Interval}) = isthinzero(real(x)) & isthinzero(imag(x))

"""
isthinone(x)
Expand All @@ -372,8 +381,7 @@ function isthinone(x::Interval)
isnai(x) && return false
return isthinone(bareinterval(x))
end

isthinone(x::Complex) = isthinone(real(x)) & isthinzero(imag(x))
isthinone(x::Complex{<:Interval}) = isthinone(real(x)) & isthinzero(imag(x))

"""
isthininteger(x)
Expand All @@ -386,5 +394,4 @@ function isthininteger(x::Interval)
isnai(x) && return false
return isthininteger(bareinterval(x))
end

isthininteger(x::Complex) = isthininteger(real(x)) & isthinzero(imag(x))
isthininteger(x::Complex{<:Interval}) = isthininteger(real(x)) & isthinzero(imag(x))
18 changes: 8 additions & 10 deletions src/intervals/interval_operations/extended_div.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ Implement the `mulRevToPair` function of the IEEE Standard 1788-2015 (Section 10
"""
function extended_div(x::BareInterval{T}, y::BareInterval{T}) where {T<:NumTypes}
ylo, yhi = bounds(y)
if 0 < yhi && 0 > ylo && !in_interval(0, x)
if sup(x) < 0
return (x / _unsafe_bareinterval(T, zero(T), yhi), x / _unsafe_bareinterval(T, ylo, zero(T)))
elseif inf(x) > 0
return (x / _unsafe_bareinterval(T, ylo, zero(T)), x / _unsafe_bareinterval(T, zero(T), yhi))
end
if ylo < 0 < yhi && !in_interval(0, x)
sup(x) < 0 && return (x / _unsafe_bareinterval(T, zero(T), yhi), x / _unsafe_bareinterval(T, ylo, zero(T)))
# inf(x) > 0
return (x / _unsafe_bareinterval(T, ylo, zero(T)), x / _unsafe_bareinterval(T, zero(T), yhi))
elseif in_interval(0, x) && in_interval(0, y)
return (entireinterval(BareInterval{T}), emptyinterval(BareInterval{T}))
else
Expand All @@ -26,10 +24,10 @@ end
function extended_div(x::Interval, y::Interval)
bx = bareinterval(x)
by = bareinterval(y)
r1, r2 = extended_div(bx, by)
r₁, r₂ = extended_div(bx, by)
d = min(decoration(x), decoration(y))
d1 = min(d, decoration(r1), ifelse(!isempty_interval(bx) & !isempty_interval(by) & !in_interval(0, x), d, trv))
d2 = min(d, decoration(r2), trv)
d₁ = min(d, decoration(r₁), ifelse(!isempty_interval(bx) & !isempty_interval(by) & !in_interval(0, bx), d, trv))
d₂ = min(d, decoration(r₂), trv)
t = isguaranteed(x) & isguaranteed(y)
return _unsafe_interval(r1, d1, t), _unsafe_interval(r2, d2, t)
return _unsafe_interval(r₁, d₁, t), _unsafe_interval(r₂, d₂, t)
end
10 changes: 6 additions & 4 deletions src/intervals/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ include("interval_operations/constants.jl")
include("interval_operations/extended_div.jl")
export extended_div
include("interval_operations/boolean.jl")
export isempty_interval, isentire_interval, isequal_interval, in_interval,
issubset_interval, isinterior, precedes, strictprecedes,
isdisjoint_interval, isweakless, isstrictless, isthin, isthinzero, isthinone,
isbounded, isunbounded, isnai, iscommon, isatomic
export isequal_interval, issubset_interval, isstrictsubset, isinterior,
isdisjoint_interval, isweakless, isstrictless, precedes, strictprecedes,
in_interval, isempty_interval, isentire_interval, isnai, isbounded,
isunbounded, iscommon, isatomic, isthin, isthinzero, isthinone,
isthininteger

include("interval_operations/overlap.jl")
export Overlap, overlap
include("interval_operations/numeric.jl")
Expand Down

0 comments on commit 9049ca7

Please sign in to comment.