Skip to content

Commit

Permalink
Add correctly rounded hyperbolic functions and their inverses
Browse files Browse the repository at this point in the history
Only sinh and cosh are covered in CRlibm
  • Loading branch information
Luis Benet committed Oct 14, 2015
1 parent 92ac0b3 commit 0e7713b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/ValidatedNumerics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Base:
in, zero, one, abs, real, show, min, max,
sqrt, exp, log, sin, cos, tan, inv,
asin, acos, atan,
sinh, cosh, tanh, asinh, acosh, atanh,
union, intersect, isempty,
convert, promote_rule, eltype,
BigFloat, float,
Expand Down
91 changes: 91 additions & 0 deletions src/intervals/hyperbolic_functions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# This file is part of the ValidatedNumerics.jl package; MIT licensed


function sinh(a::Interval{Float64})
isempty(a) && return a
return Interval(sinh(a.lo, RoundDown), sinh(a.hi, RoundUp))
end

function sinh(a::Interval{BigFloat})
isempty(a) && return a
return @controlled_round(BigFloat, sinh(a.lo), sinh(a.hi))
end


function cosh(a::Interval{Float64})
isempty(a) && return a
return Interval(cosh(mig(a), RoundDown), cosh(mag(a), RoundUp))
end

function cosh(a::Interval{BigFloat})
isempty(a) && return a
return @controlled_round(BigFloat, cosh(mig(a)), cosh(mag(a)))
end


function tanh(a::Interval{Float64})
isempty(a) && return a
res = with_bigfloat_precision(53) do
aa = Interval(big(a.lo), big(a.hi))
float( tanh(aa) )
end
return res
end

function tanh(a::Interval{BigFloat})
isempty(a) && return a
return @controlled_round(BigFloat, tanh(a.lo), tanh(a.hi))
end


function asinh(a::Interval{Float64})
isempty(a) && return a
res = with_bigfloat_precision(53) do
aa = Interval(big(a.lo), big(a.hi))
float( asinh(aa) )
end
return res
end

function asinh(a::Interval{BigFloat})
isempty(a) && return a
@controlled_round(BigFloat, asinh(a.lo), asinh(a.hi))
end


function acosh(a::Interval{Float64})
domain = Interval(one(eltype(a)), Inf)
a = a domain
isempty(a) && return a
res = with_bigfloat_precision(53) do
aa = Interval(big(a.lo), big(a.hi))
float( acosh(aa) )
end
return res
end

function acosh(a::Interval{BigFloat})
domain = Interval(one(eltype(a)), Inf)
a = a domain
isempty(a) && return a
@controlled_round(BigFloat, acosh(a.lo), acosh(a.hi))
end


function atanh(a::Interval{Float64})
domain = Interval(-one(eltype(a)), one(eltype(a)))
a = a domain
(isempty(a) || abs(a) == one(a)) && return emptyinterval(a)
res = with_bigfloat_precision(53) do
aa = Interval(big(a.lo), big(a.hi))
float( atanh(aa) )
end
return res
end

function atanh(a::Interval{BigFloat})
domain = Interval(-one(eltype(a)), one(eltype(a)))
a = a domain
isempty(a) && return a
@controlled_round(BigFloat, atanh(a.lo), atanh(a.hi))
end
3 changes: 2 additions & 1 deletion src/intervals/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ include("macro_definitions.jl")
include("conversion_promotion.jl")
include("arithmetic.jl")
include("precision.jl")
include("trigonometric_functions.jl")
include("functions.jl")
include("trigonometric_functions.jl")
include("hyperbolic_functions.jl")
55 changes: 55 additions & 0 deletions test/interval_tests/hyperb_tests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This file is part of the ValidatedNumerics.jl package; MIT licensed

using ValidatedNumerics
using FactCheck

facts("Hyperb tests") do
@fact sinh(emptyinterval()) --> emptyinterval()
@fact sinh(Interval(0.5)) --> Interval(0.5210953054937473, 0.5210953054937474)
@fact sinh(Interval(0.5, 1.67)) --> Interval(0.5210953054937473, 2.5619603657712102)
@fact sinh(Interval(-4.5, 0.1)) --> Interval(-45.00301115199179, 0.10016675001984404)
@fact sinh(@biginterval(0.5)) sinh(@interval(0.5)) --> true
@fact sinh(@biginterval(0.5, 1.67)) sinh(@interval(0.5, 1.67)) --> true
@fact sinh(@biginterval(1.67, 3.2)) sinh(@interval(1.67, 3.2)) --> true
@fact sinh(@biginterval(2.1, 5.6)) sinh(@interval(2.1, 5.6)) --> true
@fact sinh(@biginterval(0.5, 8.5)) sinh(@interval(0.5, 8.5)) --> true
@fact sinh(@biginterval(-4.5, 0.1)) sinh(@interval(-4.5, 0.1)) --> true
@fact sinh(@biginterval(1.3, 6.3)) sinh(@interval(1.3, 6.3)) --> true

@fact cosh(emptyinterval()) --> emptyinterval()
@fact cosh(Interval(0.5)) --> Interval(1.1276259652063807, 1.127625965206381)
@fact cosh(Interval(0.5, 1.67)) --> Interval(1.1276259652063807, 2.750207431409957)
@fact cosh(Interval(-4.5, 0.1)) --> Interval(1.0, 45.01412014853003)
@fact cosh(@biginterval(0.5)) cosh(@interval(0.5)) --> true
@fact cosh(@biginterval(0.5, 1.67)) cosh(@interval(0.5, 1.67)) --> true
@fact cosh(@biginterval(1.67, 3.2)) cosh(@interval(1.67, 3.2)) --> true
@fact cosh(@biginterval(2.1, 5.6)) cosh(@interval(2.1, 5.6)) --> true
@fact cosh(@biginterval(0.5, 8.5)) cosh(@interval(0.5, 8.5)) --> true
@fact cosh(@biginterval(-4.5, 0.1)) cosh(@interval(-4.5, 0.1)) --> true
@fact cosh(@biginterval(1.3, 6.3)) cosh(@interval(1.3, 6.3)) --> true

@fact tanh(emptyinterval()) --> emptyinterval()
@fact tanh(Interval(0.5)) --> Interval(0.46211715726000974, 0.4621171572600098)
@fact tanh(Interval(0.5, 1.67)) --> Interval(0.46211715726000974, 0.9315516846152083)
@fact tanh(Interval(-4.5, 0.1)) --> Interval(-0.9997532108480276, 0.09966799462495583)
@fact tanh(@biginterval(0.5)) tanh(@interval(0.5)) --> true
@fact tanh(@biginterval(0.5, 1.67)) tanh(@interval(0.5, 1.67)) --> true
@fact tanh(@biginterval(1.67, 3.2)) tanh(@interval(1.67, 3.2)) --> true
@fact tanh(@biginterval(2.1, 5.6)) tanh(@interval(2.1, 5.6)) --> true
@fact tanh(@biginterval(0.5, 8.5)) tanh(@interval(0.5, 8.5)) --> true
@fact tanh(@biginterval(-4.5, 0.1)) tanh(@interval(-4.5, 0.1)) --> true
@fact tanh(@biginterval(1.3, 6.3)) tanh(@interval(1.3, 6.3)) --> true

@fact asinh(@biginterval(1)) asinh(@interval(1)) --> true
@fact asinh(@biginterval(0.9, 2)) asinh(@interval(0.9, 2)) --> true
@fact asinh(@biginterval(3, 4)) asinh(@interval(3, 4)) --> true

@fact acosh(@biginterval(1)) acosh(@interval(1)) --> true
@fact acosh(@biginterval(-2, -0.9)) acosh(@interval(-2, -0.9)) --> true
@fact acosh(@biginterval(3, 4)) acosh(@interval(3, 4)) --> true

for a in ( Interval(17, 19), Interval(0.5, 1.2) )
@fact tanh(a) sinh(a)/cosh(a) --> true
end

end
1 change: 1 addition & 0 deletions test/interval_tests/interval_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include("construct_tests.jl")
include("consistency_tests.jl")
include("numeric_tests.jl")
include("trig_tests.jl")
include("hyperb_tests.jl")
include("non_BigFloat_tests.jl")
include("lin_alg_tests.jl")
include("loop_tests.jl")

0 comments on commit 0e7713b

Please sign in to comment.