IntervalArithmetic.jl icon indicating copy to clipboard operation
IntervalArithmetic.jl copied to clipboard

[RFC] rethink rational intervals

Open lucaferranti opened this issue 4 years ago • 2 comments

I was thinking about having rational intervals in the packaging and in this issue I am drafting a proposal I would very like to hear feedback/comments about

Idea

Remove Interval{Rational{T}} where T and update the constructor so that for example Interval(1//2) or Interval(1//2..2//3) would convert that interval to float (of course properly, that is rounding down the lower bound and rounding up the upper bound and for 1-input constructor ensuring that the interval contains the true rational number (see #405))

Grounds for the proposal

  1. Most elementary functions (sin, cos, exp) cannot return a rational interval, hence the use of rational intervals would be limited to arithmetic operations. I presume that has quite a limited application.
  2. Even for arithmetic operations, there are some issues (cft #470 ), here is the showcase
julia> a = 1//1..2//1
[1//1, 2//1]

julia> b = 0//1..2//1
[0//1, 2//1]

julia> a/b
ERROR: MethodError: no method matching Rational{Int64}(::Float64, ::RoundingMode{:Up})
Closest candidates are:
Rational{T}(::AbstractFloat) where T<:Integer at rational.jl:118
(::Type{T})(::T) where T<:Number at boot.jl:760
Stacktrace:
[1] /(a::Interval{Rational{Int64}}, b::Interval{Rational{Int64}})
 @ IntervalArithmetic C:\Users\lucaa\.julia\dev\IntervalArithmetic\src\intervals\arithmetic.jl:199
[2] top-level scope
 @ REPL[146]:1

julia> (-1//0..1//1) + (-1//0..1//1)
ERROR: DivideError: integer division error
Stacktrace:
[1] div
 @ .\int.jl:261 [inlined]
[2] divgcd
 @ .\rational.jl:44 [inlined]
[3] +(x::Rational{Int64}, y::Rational{Int64})
 @ Base .\rational.jl:284
[4] +
 @ C:\Users\lucaa\.julia\dev\IntervalArithmetic\src\intervals\rounding.jl:82 [inlined]
[5] +(a::Interval{Rational{Int64}}, b::Interval{Rational{Int64}})
 @ IntervalArithmetic C:\Users\lucaa\.julia\dev\IntervalArithmetic\src\intervals\arithmetic.jl:86
[6] top-level scope
 @ REPL[148]:1

The reason for this is that the use of 1//0 and -1//0 as Inf and -Inf in the floating point sense is kind of limited, e.g.

julia> (-1//0) + (-1//0)
ERROR: DivideError: integer division error
Stacktrace:
 [1] div
   @ .\int.jl:261 [inlined]
 [2] divgcd
   @ .\rational.jl:44 [inlined]
 [3] +(x::Rational{Int64}, y::Rational{Int64})
   @ Base .\rational.jl:284
 [4] top-level scope
   @ REPL[157]:1
  1. Currently, some operations return NaN (e.g. midpoint of emptyinterval, or inf and sup of NaI ), and there is no NaN equivalent for Rational. It is true that Rational type is not mentioned in the standard and we could do what we want, but it feels quite difficult to maintain a code that would have a different behavior for Interval{<:Rational} and Interval{<:AbstractFloat}. see #462

  2. Looking at subtypes(Real)

julia> subtypes(Real)
4-element Vector{Any}:
 AbstractFloat
 AbstractIrrational
 Integer
 Rational

the change could allow to change the definition of Interval to Interval{T<:AbstractFloat}, I think this could simplify some conversion rules and avoid method ambiguity that may arise from Interval <: Real that sometimes pops up. This I guess could come at the price of making Intervals with custom types (there was an issue about this) unusable.

That's just a few ideas to discuss. I am tagging people I presume may be interested in participating in the discussion, I apologize in advance if I bother despite you are not interested and I apologize even more to those that may be interested and I didn't think to tag.

cc: @dpsanders @Kolaru @lbenet

lucaferranti avatar Oct 01 '21 08:10 lucaferranti

Do we know of any usage for rational intervals?

Your proposition comes down to effectively dropping support them. So that would be quite breaking if anyone is using them.

Otherwise, I don't see much reason to keep them. And they indeed make the code base harder to maintain.

Kolaru avatar Oct 24 '21 20:10 Kolaru

Do we know of any usage for rational intervals?

I guess that's the main question here. The fact that nobody had reported #470 may be an indicator that not many people are using those? Alternatively there are people using rational intervals for application where they can assume they only need arithmetic operations and all intervals will always be bounded. I don't think we have a way to find out, except maybe asking in #intervals in slack

lucaferranti avatar Oct 25 '21 10:10 lucaferranti

I was looking into contributing to the 1.0-dev branch and was wondering about the restriction struct Interval{T} where {T<:AbstractFloat}. Glancing at the registered packages depending on IntervalArithmetic, it does not seem that anyone is using a different bound type, such as Interval{<:Rational}.

@lucaferranti what is the feeling here? In particular with respect to the 1.0-dev branch.

OlivierHnt avatar Jan 19 '23 16:01 OlivierHnt