Skip to content

Commit

Permalink
Merge pull request #582 from OlivierHnt/remove-intervalbox2
Browse files Browse the repository at this point in the history
Remove `IntervalBox`
  • Loading branch information
Kolaru authored Sep 5, 2023
2 parents 1314740 + e0aae72 commit 5c2b0fc
Show file tree
Hide file tree
Showing 20 changed files with 217 additions and 865 deletions.
5 changes: 0 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,15 @@ version = "0.21.1"
CRlibm = "96374032-68de-5a5b-8d9e-752f78720389"
EnumX = "4e289a0a-7415-4d19-859d-a7e5c4648b56"
FastRounding = "fa42c844-2597-5d31-933b-ebd51ab2693f"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
RoundingEmulator = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705"
SetRounding = "3cc68bcd-71a2-5612-b932-767ffbe40ab0"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[compat]
CRlibm = "0.7, 0.8, 1"
EnumX = "1"
FastRounding = "0.2, 0.3"
RecipesBase = "1.0"
RoundingEmulator = "0.2"
SetRounding = "0.2"
StaticArrays = "1.0"
julia = "1.8"
46 changes: 4 additions & 42 deletions src/IntervalArithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@ import CRlibm
import FastRounding
import RoundingEmulator

using LinearAlgebra
using Markdown
using StaticArrays
using SetRounding
using EnumX

import LinearAlgebra: ×, dot, norm
export ×, dot

import Base:
+, -, *, /, //, muladd, fma,
^, sqrt, exp, log, exp2, exp10, log2, log10, inv, cbrt, hypot,
Expand All @@ -29,26 +24,18 @@ import Base:
isfinite, isinteger, isnan, isinf, iszero,
abs, abs2,
show,
setdiff,
parse, hash,
# for IntervalBox
broadcast, length,
getindex, setindex,
iterate, eltype
parse, hash

import Base.MPFR: MPFRRoundingMode
import Base.MPFR: MPFRRoundUp, MPFRRoundDown, MPFRRoundNearest, MPFRRoundToZero, MPFRRoundFromZero

import .Broadcast: broadcasted

export
Interval, BooleanInterval,
interval, ±, @I_str,
Interval, interval, ±, @I_str,
diam, radius, mid, scaled_mid, mag, mig, hull,
emptyinterval, isempty, isinterior,
precedes, strictprecedes, , , , contains_zero, isthinzero,
isweaklyless, isstrictless, overlap, Overlap,
,
, setdiffinterval,
entireinterval, isentire, nai, isnai, isthin, iscommon, isatomic,
inf, sup, bounds, bisect, mince,
dist,
Expand All @@ -59,28 +46,11 @@ export
pow, extended_div, nthroot,
setformat



export
setindex # re-export from StaticArrays for IntervalBox



## Multidimensional
export
IntervalBox, symmetric_box

## Decorations
export
decoration, DecoratedInterval,
com, dac, def, trv, ill

## Union type
export
Region



function __init__()
setrounding(BigFloat, RoundNearest)
end
Expand All @@ -94,7 +64,6 @@ end

include("intervals/intervals.jl")

include("multidim/multidim.jl")
include("bisect.jl")
include("decorations/decorations.jl")

Expand All @@ -103,11 +72,4 @@ include("parsing.jl")
include("display.jl")
include("symbols.jl")

include("plot_recipes/plot_recipes.jl")

"""
Region{T} = Union{Interval{T}, IntervalBox{T}}
"""
const Region{T} = Union{Interval{T}, IntervalBox{T}}

end # module IntervalArithmetic
end
50 changes: 0 additions & 50 deletions src/bisect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,6 @@ function bisect(X::Interval{T}, α=where_bisect) where {T<:NumTypes}
return (unsafe_interval(T, inf(X), m), unsafe_interval(T, m, sup(X)))
end

"""
bisect(X::IntervalBox, α=0.49609375)
Bisect the `IntervalBox` `X` at position α ∈ [0,1] along its longest side.
"""
function bisect(X::IntervalBox, α=where_bisect)
i = argmax(diam.(X)) # find longest side

return bisect(X, i, α)
end

"""
bisect(X::IntervalBox, i::Integer, α=0.49609375)
Bisect the `IntervalBox` in side number `i`.
"""
function bisect(X::IntervalBox, i::Integer, α=where_bisect)

x1, x2 = bisect(X[i], α)

X1 = setindex(X, x1, i)
X2 = setindex(X, x2, i)

return (X1, X2)
end

"""
mince(x::Interval, n)
Expand All @@ -50,27 +24,3 @@ function mince(x::Interval{T}, n) where {T<:NumTypes}
nodes = LinRange(inf(x), sup(x), n+1)
return [unsafe_interval(T, nodes[i], nodes[i+1]) for i in 1:n]
end

"""
mince(x::IntervalBox, n)
Split `x` in `n` intervals in each dimension of the same diameter. These
intervals are combined in all possible `IntervalBox`-es, which are returned
as a vector.
"""
@generated function mince(x::IntervalBox{N,T}, n) where {N,T<:NumTypes}
quote
nodes_matrix = Array{Interval{T},2}(undef, n, N)
for i in 1:N
nodes_matrix[1:n,i] .= mince(x[i], n)
end

nodes = IntervalBox{$N,T}[]
Base.Cartesian.@nloops $N i _->(1:n) begin
Base.Cartesian.@nextract $N ival d->nodes_matrix[i_d, d]
ibox = Base.Cartesian.@ncall $N IntervalBox ival
push!(nodes, ibox)
end
nodes
end
end
27 changes: 2 additions & 25 deletions src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ end

# Printing mechanism for various types of intervals

show(io::IO, ::MIME"text/plain", a::Union{Interval,Complex{<:Interval},DecoratedInterval,IntervalBox}) =
show(io::IO, ::MIME"text/plain", a::Union{Interval,Complex{<:Interval},DecoratedInterval}) =
print(io, representation(a, display_params.format))

function show(io::IO, a::Union{Interval,Complex{<:Interval},DecoratedInterval,IntervalBox})
function show(io::IO, a::Union{Interval,Complex{<:Interval},DecoratedInterval})
get(io, :compact, false) && return print(io, representation(a, display_params.format))
return print(io, representation(a, :full))
end
Expand Down Expand Up @@ -127,29 +127,6 @@ function representation(a::DecoratedInterval{BigFloat}, format::Symbol)
return var_interval
end

function representation(X::IntervalBox{N}, format::Symbol) where {N}
# `format` is either :standard, :midpoint or :full
if format === :full
isempty(X) && return string("IntervalBox(∅, ", N, ")")
x = first(X)
all(y -> x y, X) && return string("IntervalBox(", representation(x, format), ", ", N, ")")
str = representation.(X.v, format)
return string("IntervalBox(", join(str, ", "), ")")
elseif format === :midpoint
isempty(X) && return string("", supscriptify(N))
x = first(X)
all(y -> x y, X) && return string("(", representation(x, format), ")", supscriptify(N))
str = representation.(X.v, format)
return string("(", join(str, ") × ("), ")")
else # format === :standard
isempty(X) && return string("", supscriptify(N))
x = first(X)
all(y -> x y, X) && return string(representation(x, format), supscriptify(N))
str = representation.(X.v, format)
return join(str, " × ")
end
end

# `String` representation of an `Interval`

function basic_representation(a::Interval{T}, format::Symbol) where {T<:AbstractFloat}
Expand Down
14 changes: 7 additions & 7 deletions src/intervals/interval_operations/set_operations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ union(a::Union{Interval,Complex{<:Interval}}, b::Union{Interval,Complex{<:Interv
union(a::AbstractVector{<:Union{<:Interval,Complex{<:Interval}}}) = hull(a)

"""
setdiff(x::Interval, y::Interval)
setdiffinterval(x::Interval, y::Interval)
Calculate the set difference `x ∖ y`, i.e. the set of values
that are inside the interval `x` but not inside `y`.
Expand All @@ -84,14 +84,14 @@ The array may:
- contain a single interval, if `y` overlaps `x`
- contain two intervals, if `y` is strictly contained within `x`.
"""
function setdiff(x::Interval{T}, y::Interval{T}) where {T<:NumTypes}
intersection = x y
function setdiffinterval(x::Interval{T}, y::Interval{T}) where {T<:NumTypes}
inter = intersect(x, y)

isempty(intersection) && return [x]
intersection x && return Interval{T}[] # x is subset of y; setdiff is empty
isempty(inter) && return [x]
(inter x) && return Interval{T}[] # x is subset of y; setdiffinterval is empty

inf(x) == inf(intersection) && return [unsafe_interval(T, sup(intersection), sup(x))]
sup(x) == sup(intersection) && return [unsafe_interval(T, inf(x), inf(intersection))]
inf(x) == inf(inter) && return [unsafe_interval(T, sup(inter), sup(x))]
sup(x) == sup(inter) && return [unsafe_interval(T, inf(x), inf(inter))]

return [unsafe_interval(T, inf(x), inf(y)), unsafe_interval(T, sup(y), sup(x))]

Expand Down
3 changes: 3 additions & 0 deletions src/intervals/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ include("interval_operations/boolean.jl")
include("interval_operations/overlap.jl")
include("interval_operations/numeric.jl")
include("interval_operations/set_operations.jl")

# Multidimensional functions
include("multidim.jl")
91 changes: 91 additions & 0 deletions src/intervals/multidim.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""
bisect(x::AbstractVector, i::Integer, α=0.49609375)
Bisect the `IntervalBox` in side number `i`.
"""
function bisect(x::AbstractVector, i::Integer, α=0.49609375)
y1, y2 = bisect(x[i], α)
x1 = copy(x)
x1[i] = y1
x2 = copy(x)
x2[i] = y2
return (x1, x2)
end

"""
mince(x::AbstractVector, n::Integer)
Splits `x` in `n` intervals in each dimension of the same diameter. These
intervals are combined in all possible intervals, which are returned
as a vector.
"""
mince(x::AbstractVector, n::Integer) = mince(x, ntuple(_ -> n, length(x)))

"""
mince(x::AbstractVector, n::NTuple{N,Integer})
Splits `x[i]` in `n[i]` intervals . These intervals are
combined in all possible intervals, which are returned
as a vector.
"""
function mince(x::AbstractVector, n::NTuple{N,Integer}) where {N}
length(x) == N || return throw(DimensionMismatch("x and n must have the same length"))
minced_intervals = [mince(x[i], n[i]) for i 1:N]
minced_boxes = Vector{typeof(x)}(undef, prod(n))
for (k, cut_indices) enumerate(CartesianIndices(n))
y = similar(x, N)
for (i, j) zip(1:N, eachindex(y))
y[j] = minced_intervals[i][cut_indices[i]]
end
minced_boxes[k] = y
end
return minced_boxes
end

"""
setdiffinterval(A::AbstractVector, B::AbstractVector)
Returns a vector of `IntervalBox`es that are in the set difference `A ∖ B`,
i.e. the set of `x` that are in `A` but not in `B`.
Algorithm: Start from the total overlap (in all directions);
expand each direction in turn.
"""
function setdiffinterval(A::T, B::T) where {T<:AbstractVector}
N = length(A)
(length(B) == N) || return throw(DimensionMismatch("A and B must have the same length"))
inter = intersect.(A, B)
any(isempty, inter) && return [A]
result_list = Vector{T}(undef, 2*N)
offset = 0
x = copy(A)
@inbounds for i 1:N
h1, h2 = _setdiffinterval(A[i], B[i])
y = similar(T, N)
z = similar(T, N)
for (j, k) enumerate(eachindex(y))
y[k] = ifelse(j == i, h1, x[k])
z[k] = ifelse(j == i, h2, x[k])
end
result_list[offset+1] = y
result_list[offset+2] = z
offset += 2
x[i] = inter[i]
end
return filter!(x -> !any(isempty, x), result_list)
end

# Computes the set difference x\\y and always returns a tuple of two intervals.
# If the set difference is only one interval or is empty, then the returned tuple contains 1
# or 2 empty intervals.
function _setdiffinterval(x::Interval{T}, y::Interval{T}) where {T<:NumTypes}
inter = intersect(x, y)
isempty(inter) && return (x, emptyinterval(T))
(inter x) && return (emptyinterval(T), emptyinterval(T)) # x is subset of y; setdiffinterval is empty
xlo, xhi = bounds(x)
ylo, yhi = bounds(y)
interlo, interhi = bounds(inter)
xlo == interlo && return (unsafe_interval(T, interhi, xhi), emptyinterval(T))
xhi == interhi && return (unsafe_interval(T, xlo, interlo), emptyinterval(T))
return (unsafe_interval(T, xlo, ylo), unsafe_interval(T, yhi, xhi))
end
48 changes: 0 additions & 48 deletions src/multidim/arithmetic.jl

This file was deleted.

Loading

0 comments on commit 5c2b0fc

Please sign in to comment.