JuliaMath / JuliaMath/IntervalSets.jl

Rethink unions and intersections

Open
#41 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
109
Forks
29
PR merge metrics
No merged PRs in 30d

Description

The following inconsistency feels "wrong":
```julia
julia> union(1,2)
2-element Array{Int64,1}:
1
2

julia> union(1:1 , 2:2)
2-element Array{Int64,1}:
1
2

julia> union(1..1, 2..2)
ERROR: ArgumentError: Cannot construct union of disjoint sets.
Stacktrace:
[1] _leq_union at /Users/solver/Projects/IntervalSets.jl/src/interval.jl:148 [inlined]
[2] union(::Interval{:closed,:closed,Int64}, ::Interval{:closed,:closed,Int64}) at /Users/solver/Projects/IntervalSets.jl/src/interval.jl:125
[3] top-level scope at none:0
```

Following the success of the lazy `Broadcasted` approach, I'd propose that
```julia
union(a::AbstractInterval, b::AbstractInterval) = UnionDomain(a,b)
```
where `UnionDomain` (and `IntersectDomain`) are lazy:
```julia
struct UnionDomain{T, D} <: Domain{T}
domains::D
end
UnionDomain(a...) = UnionDomain{mapreduce(eltype,promote_type,a),typeof(a)}(a)
in(x, d::UnionDomain) = any(in.(x, d.domains))
```
as in https://github.com/JuliaApproximation/Domains.jl. This works as follows:
```julia
julia> UnionDomain(1..1, 2..2)
a union of 2 domains:
1. : 1..1
2. : 2..2

julia> 1 ∈ UnionDomain(1..1, 2..2)
true

julia> 2 ∈ UnionDomain(1..1, 2..2)
true

julia> 1.5 ∈ UnionDomain(1..1, 2..2)
false
```
The current behaviour would be recovered via
```julia
julia> Interval(union(1..2, 1.5..3))
1.0..3.0

julia> Interval(union(1..2, 1.5..3))
1.0..3.0

julia> Interval(union(1..1, 2..2))
ERROR: ArgumentError: Cannot construct interval from disjoint union of intervals.
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.