JuliaIntervals / IntervalArithmetic.jl

Library for validated numerics using interval arithmetic
https://juliaintervals.github.io/IntervalArithmetic.jl/
Other
298 stars 71 forks source link

Union with more than 2 arguments #528

Closed petvana closed 1 year ago

petvana commented 2 years ago

I've just found that union with more than 2 arguments fallbacks to the implemetation from Base (Julia v1.7.2), and returns an array. Is it intentional?

julia> union(1..2, 3..4)
[1, 4]

julia> union(1..2, 3..4, 5..6)
3-element Vector{Interval{Float64}}:
 [1, 2]
 [3, 4]
 [5, 6]

julia> @which union(1..2, 3..4)
union(a::Interval, b::Interval) in IntervalArithmetic at /home/petr/repos/IntervalArithmetic.jl/src/intervals/set_operations.jl:137

julia> @which union(1..2, 3..4, 5..6)
union(s, sets...) in Base at abstractset.jl:50

This also happens for union with number

julia> union(1..2, 1)
2-element Vector{Interval{Float64}}:
 [1, 2]
 [1, 1]

julia> union(1, 1..2)
2-element Vector{Interval{Float64}}:
 [1, 1]
 [1, 2]
lucaferranti commented 2 years ago

probably this line

should be changed to

union(a::Interval...) = reduce(∪, a)

or just remove that and use only hull (which is clearer and shorter to type)

julia> (1..2) ∪ (3..4) ∪ (5..6)
[1, 6]

julia> hull(1..2, 3..4, 5..6)
[1, 6]
lucaferranti commented 2 years ago

technically the current definition union(a...) = reduce(union, a) is type pyracy

petvana commented 2 years ago

Using hull seems better because it would be complicated to solve mixed cases, like union(1..2, 3, 4, 5..6). However, hull seems to have its own issues (Julia 1.7.2, IntervalArithmetic v0.20.6)

julia> hull(1, 2..3)
ERROR: StackOverflowError:
Stacktrace:
     [1] mapfoldl(f::Function, op::Function, itr::Tuple{Int64, Interval{Float64}}; init::Base._InitialValue)
       @ Base ./reduce.jl:162
     [2] mapfoldl
       @ ./reduce.jl:162 [inlined]
     [3] #mapreduce#248
       @ ./reduce.jl:289 [inlined]
     [4] mapreduce
       @ ./reduce.jl:289 [inlined]
     [5] #reduce#250
       @ ./reduce.jl:458 [inlined]
     [6] reduce(op::Function, itr::Tuple{Int64, Interval{Float64}})
       @ Base ./reduce.jl:458
     [7] hull(::Int64, ::Interval{Float64})
       @ IntervalArithmetic ~/.julia/packages/IntervalArithmetic/LgwfS/src/intervals/set_operations.jl:127
     [8] (::Base.BottomRF{typeof(hull)})(acc::Int64, x::Interval{Float64})
       @ Base ./reduce.jl:81
     [9] afoldl(::Base.BottomRF{typeof(hull)}, ::Base._InitialValue, ::Int64, ::Interval{Float64})
       @ Base ./operators.jl:613
    [10] _foldl_impl(op::Base.BottomRF{typeof(hull)}, init::Base._InitialValue, itr::Tuple{Int64, Interval{Float64}})
       @ Base ./tuple.jl:277
    [11] foldl_impl(op::Base.BottomRF{typeof(hull)}, nt::Base._InitialValue, itr::Tuple{Int64, Interval{Float64}})
       @ Base ./reduce.jl:48
    [12] mapfoldl_impl(f::typeof(identity), op::typeof(hull), nt::Base._InitialValue, itr::Tuple{Int64, Interval{Float64}})
       @ Base ./reduce.jl:44
--- the last 12 lines are repeated 6664 more times ---
 [79981] mapfoldl(f::Function, op::Function, itr::Tuple{Int64, Interval{Float64}}; init::Base._InitialValue)
       @ Base ./reduce.jl:162
 [79982] mapfoldl
       @ ./reduce.jl:162 [inlined]
 [79983] #mapreduce#248
       @ ./reduce.jl:289 [inlined]
 [79984] mapreduce
       @ ./reduce.jl:289 [inlined]
 [79985] #reduce#250
       @ ./reduce.jl:458 [inlined]
lucaferranti commented 2 years ago

oh my... 😅

the problem is again from this line or more precisely from the lack of neighbor lines. A quick and dirty fix would be

hull(a::Real, b::Interval) = hull(Interval(a), b)
hull(a::Interval, b::Real) = hull(a, Interval(b))
lucaferranti commented 2 years ago

btw we have JuliaIntervals dev meetings on Saturdays at 13:00 UTC convert to your time zone. I'm mentioning this because you seem pretty interested in the package.

Please don't take this as an expectation to do more work (we all do this on our free time, no one is expected to do more than they want to), but as an informal invite that the door is open if you want to 😄 If you want, I can send you a calendar invitation, feel free to drop by if / when you want :D

petvana commented 2 years ago

btw we have JuliaIntervals dev meetings on Saturdays at 13:00 UTC convert to your time zone. I'm mentioning this because you seem pretty interested in the package.

Why not. I was just trying to use the package for bounding a gradient of a non-linear piecewise continuous function containing trigonometric functions. So I was expecting to find some edge cases. :-D (...@gmail.com)

OlivierHnt commented 1 year ago

Fixed on master.