Skip to content

Commit

Permalink
Rename :errorfree->:fast; :fast->:accurate; :correct->:tight
Browse files Browse the repository at this point in the history
  • Loading branch information
dpsanders committed Jun 7, 2017
1 parent 7feb9d3 commit 28fa625
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 30 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
- Julia v0.5 and higher are supported

### Breaking API changes
- **Only on Julia 0.6**, it is now possible to change the interval rounding type again, using `setrounding(Interval, :fast)`; #220
- **Only on Julia 0.6**, it is now possible to change the interval rounding type again, using `setrounding(Interval, :accurate)`; #220

- Changed `setdisplay` to `setformat`. Added `@format` macro to simplify interface, e.g.
`@format standard 5 true`; #251
Expand Down
4 changes: 2 additions & 2 deletions docs/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,13 @@ julia> @interval sin(1)
By default, the directed rounding used corresponds to using the `RoundDown` and `RoundUp` rounding modes when performing calculations; this gives the narrowest resulting intervals, and is set by

```jldoctest usage
julia> setrounding(Interval, :correct)
julia> setrounding(Interval, :tight)
```

An alternative rounding method is to perform calculations using the (standard) `RoundNearest` rounding mode, and then widen the result by one machine epsilon in each direction using `prevfloat` and `nextfloat`. This is achived by
```
julia> setrounding(Interval, :fast);
julia> setrounding(Interval, :accurate);
```
It generally results in wider intervals, but seems to be significantly faster.
Expand Down
46 changes: 23 additions & 23 deletions src/intervals/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ This is a so-called "traits-based" design, as follows.
The main body of the file defines versions of elementary functions with all allowed
interval rounding types, e.g.
+(IntervalRounding{:fast}, a, b, RoundDown)
+(IntervalRounding{:accurate}, a, b, RoundDown)
+(IntervalRounding{:tight}, a, b, RoundDown)
+(IntervalRounding{:accurate}, a, b, RoundDown)
+(IntervalRounding{:none}, a, b, RoundDown)
The current allowed rounding types are
- :fast # fast, tight (correct) rounding with errorfree arithmetic via FastRounding.jl
- :accurate # fast, tight (correct) rounding with errorfree arithmetic via FastRounding.jl
- :tight # tight (correct) rounding by changing rounding mode (slow)
- :accurate # fast "accurate" rounding using prevfloat and nextfloat (slightly wider than needed)
- :none # no rounding (for speed comparisons; no enclosure is guaranteed)
The function `setrounding(Interval, rounding_type)` then defines rounded
functions *without* an explicit rounding type, e.g.
sin(x, r::RoundingMode) = sin(IntervalRounding{:correct}, x, r)
sin(x, r::RoundingMode) = sin(IntervalRounding{:tight}, x, r)
These are overwritten when `setrounding(Interval, rounding_type)` is called again.
Expand Down Expand Up @@ -74,7 +74,7 @@ for (op, f) in ( (:+, :add), (:-, :sub), (:*, :mul), (:/, :div) )

mode2 = Symbol("Round", mode)

@eval $op(::IntervalRounding{:errorfree},
@eval $op(::IntervalRounding{:fast},
a::$T, b::$T, $mode1) = $ff(a, b, $mode2)
end
end
Expand All @@ -88,10 +88,10 @@ for T in (Float32, Float64)

mode2 = Symbol("Round", mode)

@eval inv(::IntervalRounding{:errorfree},
@eval inv(::IntervalRounding{:fast},
a::$T, $mode1) = inv_round(a, $mode2)

@eval sqrt(::IntervalRounding{:errorfree},
@eval sqrt(::IntervalRounding{:fast},
a::$T, $mode1) = sqrt_round(a, $mode2)
end
end
Expand All @@ -114,21 +114,21 @@ for mode in (:Down, :Up)
# binary functions:
for f in (:+, :-, :*, :/, :atan2)

@eval function $f{T<:AbstractFloat}(::IntervalRounding{:correct},
@eval function $f{T<:AbstractFloat}(::IntervalRounding{:tight},
a::T, b::T, $mode1)
setrounding(T, $mode2) do
$f(a, b)
end
end

@eval function $f{T<:AbstractFloat}(::IntervalRounding{:errorfree},
@eval function $f{T<:AbstractFloat}(::IntervalRounding{:fast},
a::T, b::T, $mode1)
setrounding(T, $mode2) do
$f(a, b)
end
end

@eval $f{T<:AbstractFloat}(::IntervalRounding{:fast},
@eval $f{T<:AbstractFloat}(::IntervalRounding{:accurate},
a::T, b::T, $mode1) = $directed($f(a, b))

@eval $f{T<:AbstractFloat}(::IntervalRounding{:none},
Expand All @@ -139,21 +139,21 @@ for mode in (:Down, :Up)

# power:

@eval function ^{S<:Real}(::IntervalRounding{:correct},
@eval function ^{S<:Real}(::IntervalRounding{:tight},
a::BigFloat, b::S, $mode1)
setrounding(BigFloat, $mode2) do
^(a, b)
end
end

# for correct rounding for Float64, must pass through BigFloat:
@eval function ^{S<:Real}(::IntervalRounding{:correct}, a::Float64, b::S, $mode1)
@eval function ^{S<:Real}(::IntervalRounding{:tight}, a::Float64, b::S, $mode1)
setprecision(BigFloat, 53) do
Float64(^(IntervalRounding{:correct}, BigFloat(a), b, $mode2))
Float64(^(IntervalRounding{:tight}, BigFloat(a), b, $mode2))
end
end

@eval ^{T<:AbstractFloat,S<:Real}(::IntervalRounding{:fast},
@eval ^{T<:AbstractFloat,S<:Real}(::IntervalRounding{:accurate},
a::T, b::S, $mode1) = $directed(a^b)

@eval ^{T<:AbstractFloat,S<:Real}(::IntervalRounding{:none},
Expand All @@ -163,15 +163,15 @@ for mode in (:Down, :Up)
# functions not in CRlibm:
for f in (:sqrt, :inv, :tanh, :asinh, :acosh, :atanh)

@eval function $f{T<:AbstractFloat}(::IntervalRounding{:correct},
@eval function $f{T<:AbstractFloat}(::IntervalRounding{:tight},
a::T, $mode1)
setrounding(T, $mode2) do
$f(a)
end
end


@eval $f{T<:AbstractFloat}(::IntervalRounding{:fast},
@eval $f{T<:AbstractFloat}(::IntervalRounding{:accurate},
a::T, $mode1) = $directed($f(a))

@eval $f{T<:AbstractFloat}(::IntervalRounding{:none},
Expand All @@ -184,10 +184,10 @@ for mode in (:Down, :Up)
# Functions defined in CRlibm

for f in CRlibm.functions
@eval $f{T<:AbstractFloat}(::IntervalRounding{:correct},
@eval $f{T<:AbstractFloat}(::IntervalRounding{:tight},
a::T, $mode1) = CRlibm.$f(a, $mode2)

@eval $f{T<:AbstractFloat}(::IntervalRounding{:fast},
@eval $f{T<:AbstractFloat}(::IntervalRounding{:accurate},
a::T, $mode1) = $directed($f(a))

@eval $f{T<:AbstractFloat}(::IntervalRounding{:none},
Expand All @@ -203,8 +203,8 @@ function _setrounding(::Type{Interval}, rounding_type::Symbol)
return # no need to redefine anything
end

if rounding_type (:errorfree, :correct, :fast, :none)
throw(ArgumentError("Rounding type must be one of `:errorfree`, `:correct`, `:fast`, `:none`"))
if rounding_type (:fast, :tight, :accurate, :none)
throw(ArgumentError("Rounding type must be one of `:fast`, `:tight`, `:accurate`, `:none`"))
end

roundtype = IntervalRounding{rounding_type}()
Expand All @@ -215,8 +215,8 @@ function _setrounding(::Type{Interval}, rounding_type::Symbol)
@eval $f{T<:AbstractFloat}(a::T, b::T, r::RoundingMode) = $f($roundtype, a, b, r)
end

if rounding_type == :errorfree # for remaining functions, use CRlibm
roundtype = IntervalRounding{:correct}()
if rounding_type == :fast # for remaining functions, use CRlibm
roundtype = IntervalRounding{:tight}()
end

for f in (:^, :atan2)
Expand All @@ -243,7 +243,7 @@ doc"""
setrounding(Interval, rounding_type::Symbol)
Set the rounding type used for all interval calculations on Julia v0.6 and above.
Valid `rounding_type`s are `:correct`, `:fast` and `:none`, `:errorfree`.
Valid `rounding_type`s are `:tight`, `:accurate` and `:none`, `:fast`.
"""
function setrounding(::Type{Interval}, rounding_type::Symbol)

Expand Down Expand Up @@ -279,4 +279,4 @@ end

# default: correct rounding
const current_rounding_type = Symbol[:undefined]
setrounding(Interval, :errorfree)
setrounding(Interval, :fast)
8 changes: 4 additions & 4 deletions test/interval_tests/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ setformat(:full)

# NB: Due to "world age" problems, the following is not a @testset

setrounding(Interval, :correct)
setrounding(Interval, :tight)
x = Interval(0.5)
@testset "Correct rounding" begin
@test sin(x) == Interval(0.47942553860420295, 0.479425538604203)
end

setrounding(Interval, :fast)
setrounding(Interval, :accurate)
@testset "Fast rounding" begin
@test sin(x) == Interval(0.47942553860420295, 0.47942553860420306)
end
Expand All @@ -27,12 +27,12 @@ setrounding(Interval, :none)
@test sin(x) == Interval(0.479425538604203, 0.479425538604203)
end

setrounding(Interval, :correct)
setrounding(Interval, :tight)
@testset "Back to correct rounding" begin
@test sin(x) == Interval(0.47942553860420295, 0.479425538604203)
end

setrounding(Interval, :errorfree)
setrounding(Interval, :fast)
@testset "Back to error-free rounding" begin
@test sin(x) == Interval(0.47942553860420295, 0.479425538604203)
end
Expand Down

0 comments on commit 28fa625

Please sign in to comment.