Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] rethink rational intervals #495

Closed
lucaferranti opened this issue Oct 1, 2021 · 3 comments · Fixed by #567
Closed

[RFC] rethink rational intervals #495

lucaferranti opened this issue Oct 1, 2021 · 3 comments · Fixed by #567

Comments

@lucaferranti
Copy link
Member

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 Some arithmetic operations not working with Interval{Rational} #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 nai() not working with rational intervals #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

@Kolaru
Copy link
Collaborator

Kolaru commented Oct 24, 2021

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.

@lucaferranti
Copy link
Member Author

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

@OlivierHnt
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants