-
Notifications
You must be signed in to change notification settings - Fork 27
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
Add support for setdiff(1..3, 2..4)
#106
Comments
|
I'm just pointing out that DomainSets does this: julia> using DomainSets
julia> setdiff(1..3, 2..4)
1..2 However, DomainSets also does the following: julia> setdiff(1..4, 2..3)
(1..2) ∪ (3..4) which IntervalSets can't do (and won't do because it is not type-stable). Instead, IntervalSets must throw an error in that case, like it does for unions of non-overlapping intervals. In DomainSets we don't want to change the behaviour of IntervalSets. For unions we resorted to a new function called julia> using DomainSets
julia> (1..2) ∪ (3..4)
ERROR: ArgumentError: Cannot construct union of disjoint sets.
julia> uniondomain(1..2, 3..4)
(1..2) ∪ (3..4) Once the setdiff feature gets implemented in IntervalSets and throws an error, we'll change DomainSets accordingly to keep the error, while I think similar compatibility concerns arise when subtracting points or vectors of points: julia> using DomainSets
julia> setdiff(1..5, 2)
(1..2 (closed–open)) ∪ (2..5 (open–closed))
julia> setdiff(1..5, [2,3,4])
(1..5) \ [2, 3, 4]
julia> 2 ∈ ans
false Again, just pointing this out. There is no more elegant solution than this, IntervalSets should just be the most useful package for intervals it can be and we'll adapt by using |
In fact starting from v0.6 we'll have: julia> using DomainSets
julia> setdiff(1..3, 2..4)
1..2 (closed–open)
julia> 2 ∈ ans
false which will probably just be annoying in most instances, but it is more accurate to remove the point 2. The closed interval would be julia> closure(setdiff(1..3, 2..4))
1..2 |
This original issue with |
I don't see how as it is two disjoint intervals |
I was thinking that the |
But that intersection will still error |
Yes, what I was trying to say is, after introducing the julia> using IntervalSets
julia> struct ComplementInterval{L,R,T}
left::T
right::T
end
julia> complement(i::Interval{:closed,:closed,T}) where T = ComplementInterval{:open,:open,T}(i.left, i.right)
complement (generic function with 1 method)
julia> Base.setdiff(i1::Interval, i2::Interval) = intersect(i1, complement(i2))
julia> function Base.intersect(i1::Interval{:closed, :closed}, i2::ComplementInterval{:open,:open})
isempty(i1) && return i1
i2.right < i2.left && return i1
i1.left ≤ i2.left ≤ i2.right ≤ i1.right && error("The returned value cannot be disjoint sets.")
i1.left ≤ i2.left ≤ i1.right ≤ i2.right && return Interval{:closed,:open}(i1.left,i2.left)
i2.left ≤ i1.left ≤ i2.right ≤ i1.right && return Interval{:open,:closed}(i2.right,i1.right)
end
julia> setdiff(1..3, 2..4)
1..2 (closed–open)
julia> setdiff(1..3, 2..1)
1..3
julia> setdiff(1..3, 0..2)
2..3 (open–closed)
julia> setdiff(1..3, 2..2)
ERROR: The returned value cannot be disjoint sets. |
Personally I think |
How should we implement the lazy version of |
I'm not seriously proposing we do this (now)... just a more hypothetical thought that this might be the best approach. But probably the best would be to properly support unions of multiple disjoint intervals. The only challenge there is how to handle open/closed. Probably something like this would work: struct IntervalUnion{T} <: Domain{T}
endoints::Vector{T} # @assert issorted(endpoints).
isopen::Vector{Bool}
end
function in(x, d::IntervalDomain)
for k = 1:2:length(d.endpoints)-1
if d.isopen[k] && d.isopen[k+1]
if d.endpoints[k] < x < d.endpoints[k+1]
return true
end
elseif d.isopen[k]
…
else …
end
end
return false
end |
That implementation seems great! One of my concerns is how to deal with the unbounded intervals, but that can be solved by adding more types such as: struct LeftUnboundedIntervalUnion{T} <: Domain{T}
endoints::Vector{T} # @assert issorted(endpoints) && isodd(length(endpoints))
isopen::Vector{Bool}
end I still think the Btw, I think the name of the type """
OrderedDomain{T}
An abstract type that represents totally ordered sets such as ``\mathbb{R}`` and ``(1,2] \cup (3,\infty)``.
Where the type parameter `T` represents the type of endpoints (or boundaries) of the set.
Note that the `T` is different from `eltype`.
"""
OrderedDomain{T} This definition resolves the confusion as commented in #115 (comment).
|
Touché.
This is not the case in DomainSets.jl |
Sorry for the late reply.
I was concerned that the name of |
No description provided.
The text was updated successfully, but these errors were encountered: