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

nai() not working with rational intervals #462

Closed
lucaferranti opened this issue May 18, 2021 · 4 comments · Fixed by #590
Closed

nai() not working with rational intervals #462

lucaferranti opened this issue May 18, 2021 · 4 comments · Fixed by #590

Comments

@lucaferranti
Copy link
Member

At the moment nai(Rational) returns an error

julia> nai(Rational)
ERROR: InexactError: Int64(NaN)
Stacktrace:
 [1] Int64
   @ .\float.jl:723 [inlined]
 [2] rationalize(#unused#::Type{Int64}, x::Float64, tol::Int64)
   @ Base .\rational.jl:161
 [3] #rationalize#184
   @ .\rational.jl:216 [inlined]
 [4] Rational
   @ .\rational.jl:119 [inlined]
 [5] Rational
   @ .\rational.jl:123 [inlined]
 [6] convert(#unused#::Type{Rational}, x::Float64)
   @ Base .\number.jl:7
 [7] nai(#unused#::Type{Rational})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\decorations\functions.jl:14
 [8] top-level scope
   @ REPL[25]:1

as Luis proposed, one solution might be to define

nai(::Rational) = DecoratedInterval(Interval(1//0, -1//0), ill)

I think this would work because NaI is allowed only as decorated interval and not as bare, hence it would not be confused with [1//0, -1//0]_trv which is the empty interval. This might require manually adjusting a couple of functions (at least hardcoding the printing for NaI and possibly checking that the current definitions of isnai and isnan still work), but other than that I don't see why it would not work.

@lucaferranti
Copy link
Member Author

actually it seems decorated intervals with rationals do not work at all

julia> a = DecoratedInterval(1//2, 3//4)
ERROR: MethodError: no method matching atomic(::Type{Interval{Interval{Rational{Int64}}}}, ::Interval{Interval{Rational{Int64}}})
Closest candidates are:
  atomic(::Type{Interval{T}}, ::Interval) where T<:AbstractFloat at C:\Users\lucaa\.julia\dev\IntervalArithmetic\src\intervals\conversion.jl:122
  atomic(::Type{Interval{T}}, ::S) where {T<:AbstractFloat, S<:Real} at C:\Users\lucaa\.julia\dev\IntervalArithmetic\src\intervals\conversion.jl:79
Stacktrace:
 [1] convert(#unused#::Type{Interval{Interval{Rational{Int64}}}}, x::Interval{Interval{Rational{Int64}}})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\intervals\conversion.jl:20
 [2] Interval{Interval{Interval{Rational{Int64}}}}(a::Interval{Interval{Rational{Int64}}}, b::Interval{Interval{Rational{Int64}}})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\intervals\intervals.jl:33
 [3] Interval(a::Interval{Interval{Rational{Int64}}}, b::Interval{Interval{Rational{Int64}}})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\intervals\intervals.jl:42
 [4] DecoratedInterval(a::Interval{Interval{Rational{Int64}}}, d::IntervalArithmetic.DECORATION) (repeats 2 times)
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\decorations\intervals.jl:54
 [5] DecoratedInterval(I::Interval{Rational{Int64}})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\decorations\intervals.jl:63
 [6] DecoratedInterval(a::Rational{Int64}, b::Rational{Int64})
   @ IntervalArithmetic ~\.julia\dev\IntervalArithmetic\src\decorations\intervals.jl:67
 [7] top-level scope
   @ REPL[19]:1

@dpsanders
Copy link
Member

That's not quite true:

julia> DecoratedInterval{Rational{Int}}(Interval(1//1, 2//2), com)
[1//1, 1//1]

Rather, it's a constructor issue I believe.

@lucaferranti
Copy link
Member Author

lucaferranti commented May 30, 2021

found the problem with the constructor. At the moment we have

DecoratedInterval(I::Interval{T}, d::DECORATION) where T<:AbstractFloat =
    DecoratedInterval{T}(I, d)

since Rational is not AbstractFloat calling DecoratedInterval(Interval(1//2, 2//1), com) falls back to

DecoratedInterval(a::T, d::DECORATION) where T<:Real =
    DecoratedInterval(Interval(a,a), d)

and then it fails. Was there any particular reason for having AbstractFloat? Changing to Real all tests still pass?

@lucaferranti
Copy link
Member Author

there's still a small problem with nai(Rational) = [1//0, -1//0]_ill, namely that the standard says inf(NaI) and sup(NaI) should return NaN, from the end of section 12.12.8

Each bare interval operation in this subclause shall have a decorated version, where each input of bare interval
type is replaced by an input having the corresponding decorated interval type, and the result format is that
of the bare operation. Following 11.7, if any input is NaI, the result is NaN. Otherwise the result is obtained
by discarding the decoration and applying the corresponding bare interval operation.

The problem is that Rational does not have anything for NaN, what should those return in that case?

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