Closed dlfivefifty closed 5 months ago
We could do:
setdiffdomain(d1::Interval, d2::AbstractVector) =
isempty(d2) ? d1 : setdiffdomain(d1 \ first(d2), d2[2:end])
But that is going to be horribly type-unsafe, and the complexity of the result depends on the length of the vector.
It would work though:
julia> (0.0..10.0) \ (2:6)
(0.0..2.0 (closed–open)) ∪ D₁
D₁ = (2.0..3.0 (open)) ∪ ((3.0..4.0 (open)) ∪ D₂)
D₂ = (4.0..5.0 (open)) ∪ ((5.0..6.0 (open)) ∪ (6.0..10.0 (open–closed)))
julia> typeof(ans)
UnionDomain{Float64, Tuple{Interval{:closed, :open, Float64}, UnionDomain{Float64, Tuple{OpenInterval{Float64}, UnionDomain{Float64, Tuple{OpenInterval{Float64}, UnionDomain{Float64, Tuple{OpenInterval{Float64}, UnionDomain{Float64, Tuple{OpenInterval{Float64}, Interval{:open, :closed, Float64}}}}}}}}}}}
But that type is not looking good. The result seems to be nested, that could probably be avoided.
In contrast currently:
julia> (0.0..10.0) \ (2:6)
(0.0..10.0) \ [2.0, 3.0, 4.0, 5.0, 6.0]
julia> typeof(ans)
SetdiffDomain{Float64, Tuple{ClosedInterval{Float64}, Vector{Float64}}}
It could make a UnionDomain{Float64,<:Vector}
though this won't be type-stable because of the mixed open-closed intervals (there is the possibility of making an AbstractInterval
whose clopenness is not part of the type). Though I agree leaving it as a SetdiffDomain
is arguably cleaner.
Though perhaps (1..2) \ 1.5
should also be left as a SetdiffDomain
?
I guess that would be more consistent. I think I'm using that elsewhere though, I'd have to check.
In the meantime I changed the example above so it becomes:
julia> (0.0..10.0) \ (2:6)
(0.0..10.0) \ 2.0:1.0:6.0
i.e., updating the eltype of a range now preserves the range (this is pending the resolution of https://github.com/JuliaLang/julia/issues/27138).
One year later and we still have:
julia> ((1..2) \ 1.5)
(1.0..1.5 (closed–open)) ∪ (1.5..2.0 (open–closed))
julia> ((1..2) \ [1.5])
(1.0..2.0) \ [1.5]
It is near impossible to avoid type instabilities when doing arithmetics with domains. I no longer worry about that, it just shouldn't be part of a time-critical code path. I do use the first kind of behaviour (subtracting a point). That means anybody can implement subtracting an array simply by iterating. So I'm inclined to leave it as is and close the issue.