Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/src/manual/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ CurrentModule = IntervalArithmetic
The IntervalArithmetic.jl package provides a [`configure`](@ref) function (not exported) that allows users to fine-tune certain aspects of the package’s behavior. This is particularly useful for controlling trade-offs between computational speed and rigor.

!!! warning
The [`configure`](@ref) function redefines methods that alter the internal behavior of IntervalArithmetic. This persists across the current Julia session and affect all subsequent interval arithmetic computations.
The [`configure`](@ref) function redefines methods that alter the internal behavior of IntervalArithmetic. This persists across the current Julia session and affects all subsequent interval arithmetic computations.

A new configuration takes effect in code that starts running after `configure` returns to the Julia prompt. Code that is already running keeps using the previous configuration (see the section on world age in the Julia manual).
In particular, calling `configure` from a function leaves the old behavior intact while the rest of the function runs. Use `Base.invokelatest` to call into the new configuration from the same function.

Each change invalidates every compiled method that depends on the modified option, so configuration changes may trigger recompilation delays before using the new configuration.

Each keyword argument sets a specific configuration option:
- `numtype`: control the default numerical type used to represent the bounds of the intervals.
Expand Down
21 changes: 12 additions & 9 deletions src/intervals/construction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,18 @@ for irr ∈ (:(:π), :(:γ), :(:catalan)) # irrationals supported by MPFR
@eval _round(::Type{T}, a::Irrational{$irr}, r::RoundingMode) where {T<:NumTypes} =
__round(T, BigFloat(a, r), r)
end
# irrationals not supported by MPFR, use their exact formula ℯ = exp(1), φ = (1+sqrt(5))/2
_round(::Type{T}, ::Irrational{:ℯ}, r::RoundingMode{:Down}) where {T<:NumTypes} =
__round(T, inf(exp(bareinterval(BigFloat, 1))), r)
_round(::Type{T}, ::Irrational{:ℯ}, r::RoundingMode{:Up}) where {T<:NumTypes} =
__round(T, sup(exp(bareinterval(BigFloat, 1))), r)
_round(::Type{T}, ::Irrational{:φ}, r::RoundingMode{:Down}) where {T<:NumTypes} =
__round(T, inf((bareinterval(BigFloat, 1) + sqrt(bareinterval(BigFloat, 5))) / bareinterval(BigFloat, 2)), r)
_round(::Type{T}, ::Irrational{:φ}, r::RoundingMode{:Up}) where {T<:NumTypes} =
__round(T, sup((bareinterval(BigFloat, 1) + sqrt(bareinterval(BigFloat, 5))) / bareinterval(BigFloat, 2)), r)
# irrationals not supported by MPFR, use their exact formula ℯ = exp(1), φ = (1+sqrt(5))/2.
# The rounding mode is fixed to `:correct` rather than taken from `default_rounding()`:
# the enclosure of a constant must be rigorous whatever the configuration, and the
# generated `bareinterval(::Type{T}, ::AbstractIrrational)` bakes the result in at its
# first generation, which method invalidation does not track.
_round(::Type{T}, ::Irrational{:ℯ}, r::RoundingMode) where {T<:NumTypes} =
__round(T, _fround(exp, IntervalRounding{:correct}(), one(BigFloat), r), r)
function _round(::Type{T}, ::Irrational{:φ}, r::RoundingMode) where {T<:NumTypes}
ir = IntervalRounding{:correct}()
sqrt5 = _fround(sqrt, ir, BigFloat(5), r)
return __round(T, _fround(/, ir, _fround(+, ir, one(BigFloat), sqrt5, r), BigFloat(2), r), r)
end
# floats
__round(::Type{T}, a, r::RoundingMode) where {T<:AbstractFloat} = T(a, r)
# rationals
Expand Down
12 changes: 12 additions & 0 deletions test/IntervalArithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -309,5 +309,17 @@ end
@test nextfloat(inf(z128)) == sup(z128)
end

# irrational enclosures are rigorous whatever the configured rounding mode
try
IntervalArithmetic.configure(rounding = :none)
for irr ∈ (MathConstants.ℯ, MathConstants.golden), T ∈ (Float64, BigFloat)
y = Base.invokelatest(bareinterval, T, irr)
@test in_interval(irr, y)
@test inf(y) < sup(y)
end
finally
IntervalArithmetic.configure(rounding = :correct)
end

@test_throws ArgumentError("only irrationals from MathConstants or IrrationalConstants.jl are supported") bareinterval(Float64, Base.Irrational{:foo}())
end
Loading