Guaranteed intervals

A guaranteed interval is a concept distinct from decorations (see Decorations) and not specified in the IEEE 1788-2015 standard. It is introduced to accommodate Julia’s flexible system of type conversion and promotion, while retaining reliability in computations.

"NG" label

An interval x constructed via interval satisfies isguaranteed(x) == true. However, if a call to convert(::Type{<:Interval}, ::Real) occurs, then the resulting interval x satisfies isguaranteed(x) == false, receiving the "NG" (not guaranteed) label.

For instance, consider the following examples:

julia> using IntervalArithmetic
julia> setdisplay(; sigdigits = 6)Display options: - format: full - decorations: true (ignored) - NG flag: true (ignored) - significant digits: 6 (ignored)
julia> convert(Interval{Float64}, 1.) # considered "not guaranteed" as this call can be done implicitlyInterval{Float64}(1.0, 1.0, com, false)
julia> interval(1) # considered "guaranteed" as the user explicitly constructed the intervalInterval{Float64}(1.0, 1.0, com, true)

In contrast, a BareInterval can only be constructed via bareinterval, it is not a subtype of Real, and there are no allowed conversion with Number. Thus, this interval type is always guaranteed.

Danger

A user interested in validated numerics should always track down the source of an "NG" label.

Exact numbers

When typing Julia code, it is combersome to manually wrap all numerical numbers with interval. Also, we sometimes want to use the same function for both floating-point arithmetic (maybe to check have a fast quick checks) and interval arithmetic. Then, we would want the typed-in numerical numbers to convert automatically to the appropriate numerical type depending on the context. To this end, the ExactReal structure marks any Real number as a user exactly typed-in value.

For instance, consider the following examples:

julia> interval(1)Interval{Float64}(1.0, 1.0, com, true)
julia> interval(1) + ExactReal(1)Interval{Float64}(2.0, 2.0, com, true)
julia> @exact 2interval(1) + 1 + exp(im * interval(1))Interval{Float64}(3.5403023058681393, 3.5403023058681398, com, true) + im*Interval{Float64}(0.8414709848078965, 0.8414709848078966, com, true)
julia> @exact foo(x) = 2x + 1 + exp(im * x)foo (generic function with 1 method)
julia> foo(1.)3.5403023058681398 + 0.8414709848078965im
julia> foo(interval(1))Interval{Float64}(3.5403023058681393, 3.5403023058681398, com, true) + im*Interval{Float64}(0.8414709848078965, 0.8414709848078966, com, true)