nai() not working with rational intervals
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.
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
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.
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?
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?