Skip to content

Commit

Permalink
Merge 4954d42 into cab2433
Browse files Browse the repository at this point in the history
  • Loading branch information
dpsanders committed Aug 17, 2018
2 parents cab2433 + 4954d42 commit a9f0a4d
Show file tree
Hide file tree
Showing 43 changed files with 710 additions and 808 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ os:
- osx

julia:
- 0.6
- 0.7
- nightly

matrix:
Expand All @@ -21,6 +21,6 @@ notifications:
email: false

after_success:
- julia -e 'Pkg.add("Documenter")'
- julia -e 'using Pkg; Pkg.add("Documenter")'
- julia -e 'cd(Pkg.dir("IntervalArithmetic")); include(joinpath("docs", "make.jl"))'
- julia -e 'cd(Pkg.dir("IntervalArithmetic")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder()); Codecov.submit(process_folder())'
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ setdisplay(:full)
- `bisect` function in `ValidatedNumerics.RootFinding` for bisecting `Interval`s and `IntervalBox`es #217

### Other
- Many tests use `Base.Test` instead of `FactCheck` #205
- Many tests use `Test` instead of `FactCheck` #205
- Miscellaneous bugfixes

## v0.6
Expand Down
6 changes: 2 additions & 4 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
julia 0.6
julia 0.7
CRlibm 0.6
StaticArrays 0.5
FastRounding 0.0.4
AdjacentFloats 0.0.5
FastRounding 0.1.1
RecipesBase
Compat 0.69.0
6 changes: 3 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

Expand Down Expand Up @@ -39,7 +39,7 @@ install:
build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
- C:\projects\julia\bin\julia -e "versioninfo(); using Pkg;
Pkg.clone(pwd(), \"IntervalArithmetic\"); Pkg.build(\"IntervalArithmetic\")"

test_script:
Expand Down
2 changes: 1 addition & 1 deletion docs/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ to an `Interval{BigFloat}`, and then use routines from the `MPFR` library

- `^`
- `exp2`, `exp10`
- `atan2`, `atanh`
- `atan`, `atanh`

Note, in particular, that in order to obtain correct rounding for the power function (`^`),
intervals are converted to and from `BigFloat`; this implies a significant slow-down in this case.
Expand Down
27 changes: 12 additions & 15 deletions src/IntervalArithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ __precompile__(true)
module IntervalArithmetic

import CRlibm

using StaticArrays
using FastRounding
using AdjacentFloats
using Compat

if VERSION <= v"0.7.0-DEV.2004"
import Base: ×, dot
import Compat.Sys
export
else
using Markdown
import Base:
import LinearAlgebra: ×, dot
end

using Markdown

using LinearAlgebra
import LinearAlgebra: ×, dot
export ×, dot


import Base:
Expand All @@ -27,12 +22,12 @@ import Base:
in, zero, one, eps, typemin, typemax, abs, abs2, real, min, max,
sqrt, exp, log, sin, cos, tan, inv,
exp2, exp10, log2, log10,
asin, acos, atan, atan2,
asin, acos, atan,
sinh, cosh, tanh, asinh, acosh, atanh,
union, intersect, isempty,
convert, promote_rule, eltype, size,
BigFloat, float, widen, big,
, , , eps,
, , , , eps,
floor, ceil, trunc, sign, round,
expm1, log1p,
precision,
Expand All @@ -44,7 +39,9 @@ import Base:
import Base: # for IntervalBox
broadcast, length,
getindex, setindex,
start, next, done, eltype
iterate, eltype

import .Broadcast: broadcasted

export
AbstractInterval, Interval,
Expand Down
2 changes: 1 addition & 1 deletion src/bisect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end
Bisect the `IntervalBox` `X` at position α ∈ [0,1] along its longest side.
"""
function bisect(X::IntervalBox, α=where_bisect)
i = indmax(diam.(X)) # find longest side
i = argmax(diam.(X)) # find longest side

return bisect(X, i, α)
end
Expand Down
9 changes: 6 additions & 3 deletions src/decorations/functions.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# This file is part of the IntervalArithmetic.jl package; MIT licensed

Base.literal_pow(::typeof(^), x::DecoratedInterval{T}, ::Val{p}) where {T,p} = x^p


# zero, one
zero(a::DecoratedInterval{T}) where T<:Real = DecoratedInterval(zero(T))
zero(::Type{DecoratedInterval{T}}) where T<:Real = DecoratedInterval(zero(T))
Expand Down Expand Up @@ -255,7 +258,7 @@ following the IEEE-1788 Standard (see Sect. 11.7.1, pp 47).
""" union


## Functions on unrestricted domains; tan and atan2 are treated separately
## Functions on unrestricted domains; tan and atan are treated separately
unrestricted_functions =(
:exp, :exp2, :exp10,
:sin, :cos,
Expand Down Expand Up @@ -290,10 +293,10 @@ function decay(a::DECORATION)
ill
end

function atan2(yy::DecoratedInterval{T}, xx::DecoratedInterval{T}) where T
function atan(yy::DecoratedInterval{T}, xx::DecoratedInterval{T}) where T
x = interval_part(xx)
y = interval_part(yy)
r = atan2(y, x)
r = atan(y, x)
d = decoration(r)
d = min(d, decoration(xx), decoration(yy))
# Check cases when decoration is trv and decays (from com or dac)
Expand Down
8 changes: 4 additions & 4 deletions src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ end
function round_string(x::BigFloat, digits::Int, r::RoundingMode)

lng = digits + Int32(8)
@compat buf = Array{UInt8}(undef, lng + 1)
buf = Array{UInt8}(undef, lng + 1)

lng = ccall((:mpfr_snprintf,:libmpfr), Int32,
(Ptr{UInt8}, Culong, Ptr{UInt8}, Int32, Ref{BigFloat}...),
buf, lng + 1, "%.$(digits)R*g", Base.MPFR.to_mpfr(r), x)

repr = unsafe_string(pointer(buf))

@compat repr = replace(repr, "nan" => "NaN")
repr = replace(repr, "nan" => "NaN")

return repr
end
Expand All @@ -144,8 +144,8 @@ function basic_representation(a::Interval, format=nothing)
bb = round_string(a.hi, sigfigs, RoundUp)

output = "[$aa, $bb]"
@compat output = replace(output, "inf" => "")
@compat output = replace(output, "Inf" => "")
output = replace(output, "inf" => "")
output = replace(output, "Inf" => "")

elseif format == :full
output = "Interval($(a.lo), $(a.hi))"
Expand Down
1 change: 1 addition & 0 deletions src/intervals/conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ promote_rule(::Type{BigFloat}, ::Type{Interval{T}}) where T<:Real =


# convert methods:
convert(::Type{Interval{T}}, x::Bool) where {T} = convert(Interval{T}, Int(x))
convert(::Type{Interval{T}}, x::Real) where {T} = atomic(Interval{T}, x)
convert(::Type{Interval{T}}, x::T) where {T<:Real} = Interval{T}(x)
convert(::Type{Interval{T}}, x::Interval{T}) where {T} = x
Expand Down
8 changes: 4 additions & 4 deletions src/intervals/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ for mode in (:Down, :Up)
mode2 = Symbol("Round", mode)

if mode == :Down
directed = :prev_float
directed = :prevfloat
else
directed = :next_float
directed = :nextfloat
end

# binary functions:
for f in (:+, :-, :*, :/, :atan2)
for f in (:+, :-, :*, :/, :atan)

@eval function $f(::IntervalRounding{:slow},
a::T, b::T, $mode1) where T<:AbstractFloat
Expand Down Expand Up @@ -233,7 +233,7 @@ function _setrounding(::Type{Interval}, rounding_type::Symbol)
roundtype = IntervalRounding{:slow}()
end

for f in (:^, :atan2)
for f in (:^, :atan)

@eval $f(a::T, b::T, r::RoundingMode) where {T<:AbstractFloat} = $f($roundtype, a, b, r)
end
Expand Down
47 changes: 23 additions & 24 deletions src/intervals/trigonometric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ half_pi(x::T) where {T<:AbstractFloat} = half_pi(T)
two_pi(::Type{Float64}) = multiply_by_positive_constant(2.0, pi_interval(Float64))
two_pi(::Type{T}) where {T} = 2 * pi_interval(T)

range_atan2(::Type{T}) where {T<:Real} = Interval(-(pi_interval(T).hi), pi_interval(T).hi)
half_range_atan2(::Type{T}) where {T} = (temp = half_pi(T); Interval(-(temp.hi), temp.hi) )
pos_range_atan2(::Type{T}) where {T<:Real} = Interval(zero(T), pi_interval(T).hi)
range_atan(::Type{T}) where {T<:Real} = Interval(-(pi_interval(T).hi), pi_interval(T).hi)
half_range_atan(::Type{T}) where {T} = (temp = half_pi(T); Interval(-(temp.hi), temp.hi) )
pos_range_atan(::Type{T}) where {T<:Real} = Interval(zero(T), pi_interval(T).hi)


"""Finds the quadrant(s) corresponding to a given floating-point
Expand Down Expand Up @@ -194,17 +194,16 @@ function atan(a::Interval{T}) where T
end


#atan2{T<:Real, S<:Real}(y::Interval{T}, x::Interval{S}) = atan2(promote(y, x)...)
#atan{T<:Real, S<:Real}(y::Interval{T}, x::Interval{S}) = atan(promote(y, x)...)

function atan2(y::Interval{Float64}, x::Interval{Float64})
function atan(y::Interval{Float64}, x::Interval{Float64})
(isempty(y) || isempty(x)) && return emptyinterval(Float64)

atomic(Interval{Float64}, atan2(big53(y), big53(x)))
atomic(Interval{Float64}, atan(big53(y), big53(x)))
end



function atan2(y::Interval{BigFloat}, x::Interval{BigFloat})
function atan(y::Interval{BigFloat}, x::Interval{BigFloat})
(isempty(y) || isempty(x)) && return emptyinterval(BigFloat)

T = BigFloat
Expand All @@ -223,47 +222,47 @@ function atan2(y::Interval{BigFloat}, x::Interval{BigFloat})
y == zero(y) && return emptyinterval(T)
y.lo zero(T) && return half_pi(T)
y.hi zero(T) && return -half_pi(T)
return half_range_atan2(T)
return half_range_atan(T)

elseif x.lo > zero(T)

y == zero(y) && return y
y.lo zero(T) &&
return @round(atan2(y.lo, x.hi), atan2(y.hi, x.lo)) # refinement lo bound
return @round(atan(y.lo, x.hi), atan(y.hi, x.lo)) # refinement lo bound
y.hi zero(T) &&
return @round(atan2(y.lo, x.lo), atan2(y.hi, x.hi))
return @round(atan2(y.lo, x.lo), atan2(y.hi, x.lo))
return @round(atan(y.lo, x.lo), atan(y.hi, x.hi))
return @round(atan(y.lo, x.lo), atan(y.hi, x.lo))

elseif x.hi < zero(T)

y == zero(y) && return pi_interval(T)
y.lo zero(T) &&
return @round(atan2(y.hi, x.hi), atan2(y.lo, x.lo))
return @round(atan(y.hi, x.hi), atan(y.lo, x.lo))
y.hi < zero(T) &&
return @round(atan2(y.hi, x.lo), atan2(y.lo, x.hi))
return range_atan2(T)
return @round(atan(y.hi, x.lo), atan(y.lo, x.hi))
return range_atan(T)

else # zero(T) ∈ x

if x.lo == zero(T)
y == zero(y) && return y

y.lo zero(T) && return @round(atan2(y.lo, x.hi), half_range_atan2(BigFloat).hi)
y.lo zero(T) && return @round(atan(y.lo, x.hi), half_range_atan(BigFloat).hi)

y.hi zero(T) && return @round(half_range_atan2(BigFloat).lo, atan2(y.hi, x.hi))
return half_range_atan2(T)
y.hi zero(T) && return @round(half_range_atan(BigFloat).lo, atan(y.hi, x.hi))
return half_range_atan(T)

elseif x.hi == zero(T)
y == zero(y) && return pi_interval(T)
y.lo zero(T) && return @round(half_pi(BigFloat).lo, atan2(y.lo, x.lo))
y.hi < zero(T) && return @round(atan2(y.hi, x.lo), -(half_pi(BigFloat).lo))
return range_atan2(T)
y.lo zero(T) && return @round(half_pi(BigFloat).lo, atan(y.lo, x.lo))
y.hi < zero(T) && return @round(atan(y.hi, x.lo), -(half_pi(BigFloat).lo))
return range_atan(T)
else
y.lo zero(T) &&
return @round(atan2(y.lo, x.hi), atan2(y.lo, x.lo))
return @round(atan(y.lo, x.hi), atan(y.lo, x.lo))
y.hi < zero(T) &&
return @round(atan2(y.hi, x.lo), atan2(y.hi, x.hi))
return range_atan2(T)
return @round(atan(y.hi, x.lo), atan(y.hi, x.hi))
return range_atan(T)
end

end
Expand Down
14 changes: 11 additions & 3 deletions src/multidim/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@
wrap(v::SVector{N,T} where {N,T<:Interval}) = IntervalBox(v)
wrap(v) = v

@inline Base.broadcast(f, X::IntervalBox) = wrap(f.(X.v))
@inline Base.broadcast(f, X::IntervalBox, Y::IntervalBox) = wrap(f.(X.v, Y.v))
@inline Base.broadcast(f, X::IntervalBox, y) = wrap(f.(X.v, y))
#Base.size(X::IntervalBox{2,Float64}) = (2,)
#
@inline broadcasted(f, X::IntervalBox) = wrap(f.(X.v))
@inline broadcasted(f, X::IntervalBox, Y::IntervalBox) = wrap(f.(X.v, Y.v))
@inline broadcasted(f, X::IntervalBox, y) = wrap(f.(X.v, y))
@inline broadcasted(f, x, Y::IntervalBox) = wrap(f.(x, Y.v))

# for literal_pow:
@inline broadcasted(f, x, y, Z::IntervalBox) = wrap(f.(x, y, Z.v))
@inline broadcasted(f, x, Y::IntervalBox, z) = wrap(f.(x, Y.v, z))


for op in (:+, :-, :, :, :, :isinterior, :dot, :setdiff, :×)
@eval $(op)(a::SVector, b::IntervalBox) = $(op)(IntervalBox(a), b)
Expand Down
13 changes: 7 additions & 6 deletions src/multidim/intervalbox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ setindex(X::IntervalBox, y, i) = IntervalBox( setindex(X.v, y, i) )

# iteration:

iterate(X::IntervalBox{N,T}) where {N, T} = (X[1], 1)

start(X::IntervalBox{N,T}) where {N,T} = 1
function iterate(X::IntervalBox{N,T}, state) where {N,T}
(state == N) && return nothing

next(X::IntervalBox{N,T}, state) where {N,T} = (X[state], state+1)

done(X::IntervalBox{N,T}, state) where {N,T} = state > N
return X[state+1], state+1
end

eltype(::Type{IntervalBox{N,T}}) where {N,T} = Interval{T} # Note that this is defined for the type

Expand Down Expand Up @@ -90,8 +91,8 @@ contains_zero(X::IntervalBox) = all(contains_zero.(X))
×(a::IntervalBox, b::Interval) = IntervalBox(a.v..., b)
×(a::IntervalBox, b::IntervalBox) = IntervalBox(a.v..., b.v...)

IntervalBox(x::Interval, ::Type{Val{n}}) where {n} = IntervalBox(SVector(ntuple(i->x, Val{n})))
IntervalBox(x::Interval, ::Val{n}) where {n} = IntervalBox(SVector(ntuple( _ -> x, Val(n) )))

IntervalBox(x::Interval, n::Int) = IntervalBox(x, Val{n})
IntervalBox(x::Interval, n::Int) = IntervalBox(x, Val(n))

dot(x::IntervalBox, y::IntervalBox) = dot(x.v, y.v)
6 changes: 3 additions & 3 deletions src/parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Parse a string as an interval. Formats allowed include:
function parse(::Type{Interval{T}}, s::AbstractString) where T

# Check version!
if !(@compat occursin("[", s)) # string like "3.1"
if !(occursin("[", s)) # string like "3.1"

m = match(r"(.*)±(.*)", s)
if m != nothing
Expand Down Expand Up @@ -81,8 +81,8 @@ function parse(::Type{Interval{T}}, s::AbstractString) where T

end

@compat expr1 = Meta.parse(lo)
@compat expr2 = Meta.parse(hi)
expr1 = Meta.parse(lo)
expr2 = Meta.parse(hi)

interval = eval(make_interval(T, expr1, [expr2]))

Expand Down

0 comments on commit a9f0a4d

Please sign in to comment.