Skip to content

Commit

Permalink
Working n-dimensional setdiff
Browse files Browse the repository at this point in the history
  • Loading branch information
dpsanders committed May 29, 2016
1 parent bd9ae2f commit ab8cce9
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 17 deletions.
28 changes: 11 additions & 17 deletions src/multidim/setdiff.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@ function labelled_setdiff{T}(x::Interval{T}, y::Interval{T})

end

# doc"""
# setdiff(A::IntervalBox{N,T}, B::IntervalBox{N,T})
#
# 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: Iterate x direction, looking for the sub-interval in that direction
# that is non-trivial, i.e. that has an overlap. For that one, iterate down a "level"
# to the next variable and repeat.
# """
# function setdiff{N,T}(A::IntervalBox{N,T}, B::IntervalBox{N,T})
# X = [labelled_setdiff(a,b) for (a, b) in zip(A, B)]
# lengths = map(length, X)
Expand All @@ -43,26 +33,30 @@ end
#
# end
# end
doc"""
setdiff(A::IntervalBox{N,T}, B::IntervalBox{N,T})
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 setdiff{N,T}(A::IntervalBox{N,T}, B::IntervalBox{N,T})
X = [labelled_setdiff(a,b) for (a, b) in zip(A, B)]
# ordered such that the first in each is the excluded interval

first = [ i[1] for i in X ]
labels = [i[2] for i in first]

any(labels .== -1) && return A # no overlap
any(labels .== -1) && return [A] # no overlap

@assert all(labels .== 1)
# @assert all(labels .== 1)

excluded = [i[1] for i in first]

result_list = IntervalBox{N,T}[]

@show first
@show labels
@show excluded


for dimension in N:-1:1
for which in X[dimension][2:end]
excluded[dimension] = which[1]
Expand Down
48 changes: 48 additions & 0 deletions test/multidim_tests/multidim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,54 @@ facts("@intervalbox tests") do

@intervalbox g(x, y) = x - y
@fact isa(g(X), IntervalBox) --> true
end

facts("setdiff for IntervalBox") do
X = IntervalBox(2..4, 3..5)
Y = IntervalBox(3..5, 4..6)
@fact setdiff(X, Y) --> [ IntervalBox(3..4, 3..4),
IntervalBox(2..3, 3..5) ]


X = IntervalBox(2..5, 3..6)
Y = IntervalBox(-10..10, 4..5)
@fact setdiff(X, Y) --> [ IntervalBox(2..5, 3..4),
IntervalBox(2..5, 5..6) ]


X = IntervalBox(2..5, 3..6)
Y = IntervalBox(4..6, 4..5)
@fact setdiff(X, Y) --> [ IntervalBox(4..5, 3..4),
IntervalBox(4..5, 5..6),
IntervalBox(2..4, 3..6) ]


X = IntervalBox(2..5, 3..6)
Y = IntervalBox(3..4, 4..5)
@fact setdiff(X, Y) --> [ IntervalBox(3..4, 3..4),
IntervalBox(3..4, 5..6),
IntervalBox(2..3, 3..6),
IntervalBox(4..5, 3..6) ]


X = IntervalBox(2..5, 3..6)
Y = IntervalBox(2..4, 10..20)
@fact setdiff(X, Y) --> typeof(X)[X]


X = IntervalBox(2..5, 3..6)
Y = IntervalBox(-10..10, -10..10)
@fact setdiff(X, Y) --> typeof(X)[]


X = IntervalBox(1..4, 3..6, 7..10)
Y = IntervalBox(2..3, 4..5, 8..9)
@fact setdiff(X, Y) --> [ IntervalBox(2..3, 4..5, 7..8),
IntervalBox(2..3, 4..5, 9..10),
IntervalBox(2..3, 3..4, 7..10),
IntervalBox(2..3, 5..6, 7..10),
IntervalBox(1..2, 3..6, 7..10),
IntervalBox(3..4, 3..6, 7..10) ]


end

0 comments on commit ab8cce9

Please sign in to comment.