AnderGray / IntervalUnionArithmetic.jl

An implementation of interval union arithmetic in Julia
MIT License
11 stars 4 forks source link

intervals actively being (wrongfully) joined #20

Closed abraunst closed 2 years ago

abraunst commented 2 years ago
julia> x = intervalUnion([Interval(i,i+0.5) for i=1:200])
[1, 101.5] ∪ [102, 102.5] ∪ [103, 103.5] ∪ [104, 104.5] ∪ [105, 105.5] ∪ [106, 106.5] ∪ [107, 107.5] ∪ [108, 108.5] ∪ [109, 109.5] ∪ [110, 110.5] ∪ [111, 111.5] ∪ [112, 112.5] ∪ [113, 113.5] ∪ [114, 114.5] ∪ [115, 115.5] ∪ [116, 116.5] ∪ [117, 117.5] ∪ [118, 118.5] ∪ [119, 119.5] ∪ [120, 120.5] ∪ [121, 121.5] ∪ [122, 122.5] ∪ [123, 123.5] ∪ [124, 124.5] ∪ [125, 125.5] ∪ [126, 126.5] ∪ [127, 127.5] ∪ [128, 128.5] ∪ [129, 129.5] ∪ [130, 130.5] ∪ [131, 131.5] ∪ [132, 132.5] ∪ [133, 133.5] ∪ [134, 134.5] ∪ [135, 135.5] ∪ [136, 136.5] ∪ [137, 137.5] ∪ [138, 138.5] ∪ [139, 139.5] ∪ [140, 140.5] ∪ [141, 141.5] ∪ [142, 142.5] ∪ [143, 143.5] ∪ [144, 144.5] ∪ [145, 145.5] ∪ [146, 146.5] ∪ [147, 147.5] ∪ [148, 148.5] ∪ [149, 149.5] ∪ [150, 150.5] ∪ [151, 151.5] ∪ [152, 152.5] ∪ [153, 153.5] ∪ [154, 154.5] ∪ [155, 155.5] ∪ [156, 156.5] ∪ [157, 157.5] ∪ [158, 158.5] ∪ [159, 159.5] ∪ [160, 160.5] ∪ [161, 161.5] ∪ [162, 162.5] ∪ [163, 163.5] ∪ [164, 164.5] ∪ [165, 165.5] ∪ [166, 166.5] ∪ [167, 167.5] ∪ [168, 168.5] ∪ [169, 169.5] ∪ [170, 170.5] ∪ [171, 171.5] ∪ [172, 172.5] ∪ [173, 173.5] ∪ [174, 174.5] ∪ [175, 175.5] ∪ [176, 176.5] ∪ [177, 177.5] ∪ [178, 178.5] ∪ [179, 179.5] ∪ [180, 180.5] ∪ [181, 181.5] ∪ [182, 182.5] ∪ [183, 183.5] ∪ [184, 184.5] ∪ [185, 185.5] ∪ [186, 186.5] ∪ [187, 187.5] ∪ [188, 188.5] ∪ [189, 189.5] ∪ [190, 190.5] ∪ [191, 191.5] ∪ [192, 192.5] ∪ [193, 193.5] ∪ [194, 194.5] ∪ [195, 195.5] ∪ [196, 196.5] ∪ [197, 197.5] ∪ [198, 198.5] ∪ [199, 199.5] ∪ [200, 200.5]

This is done on purpose in the function closeGaps! ... why is this needed?

AnderGray commented 2 years ago

The purpose of closeGaps! is so that the number of intervals in the union doesn't get exponentially large. Sometimes after a binary operation more intervals are created than went in, eg:

julia> a = Interval(1,2) ∪ interval(20,24);

julia> a*a
[1, 4] ∪ [20, 48] ∪ [400, 576]

So it is possible for the number of unions to explode. closeGaps! prevents this.

If the number of unions exceeds the global variable IntervalUnionArithmetic.MAXINTS[1], which is default 100, closeGaps! will reduce to this number by taking interval hulls. It does it in such a way that the smallest gaps between intervals is closed, so that the smallest amount information is lost.

You can change this variable however, if you want to have more intervals in the union, eg:

julia> IntervalUnionArithmetic.MAXINTS[1] = 200

julia> length( intervalUnion([Interval(i,i+0.5) for i=1:200]).v )
200
abraunst commented 2 years ago

Yes, I understand that the number of intervals can grow large. But I feel that it should not do this by default, it feels wrong to me. The number of intervals in a*a is no larger than n^2... a simple function like f(v::Vector,w::Vector)=[x+y for x in v for y in w] has the same behavior, and I think that you'll agree that it would be really strange if some elements were arbitrary elided!. If it were by me, I would let the user call the closeGaps! function on their own. But I understand that there are other use cases in which it may be preferable to keep it under control. In any case, thanks for the explanation, I'll close the issue!

AnderGray commented 2 years ago

Ahh - sorry was unsure. You of course have a good point. It likely depends on the particular use case. In my application, I only ever wanted 20 maybe 50 max interval unions, so this made sense when it was first implemented.

I would prefer to keep some check internally just incase - but the default number can definitely be increased - since it might cause some confusion to people, and 100 is low.

Also a good point about calling the function externally. You could get this functionality by setting IntervalUnionArithmetic.MAXINTS[1] = inf. A bit hard to know what the best default is for the different use cases.

abraunst commented 2 years ago

Given that the maximum will be very much application dependent, wouldn't it be better to use typemax(Int) by default (and explain the parameter clearly in README.md)?