Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix thread-safe in rounding #615

Merged
merged 14 commits into from
Jan 21, 2024
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repo = "https://github.com/JuliaIntervals/IntervalArithmetic.jl.git"
version = "0.22.5"

[deps]
CRlibm = "96374032-68de-5a5b-8d9e-752f78720389"
CRlibm_jll = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0"
RoundingEmulator = "5eaf0fd0-dfba-4ccb-bf02-d820a40db705"

[weakdeps]
Expand All @@ -16,7 +16,7 @@ IntervalArithmeticDiffRulesExt = "DiffRules"
IntervalArithmeticRecipesBaseExt = "RecipesBase"

[compat]
CRlibm = "1"
CRlibm_jll = "1"
DiffRules = "1"
RecipesBase = "1"
RoundingEmulator = "0.2"
Expand Down
6 changes: 1 addition & 5 deletions src/IntervalArithmetic.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
module IntervalArithmetic

import CRlibm
import CRlibm_jll
import RoundingEmulator
import Base.MPFR

function __init__()
setrounding(BigFloat, RoundNearest)
end

#

include("intervals/intervals.jl")
Expand Down
4 changes: 3 additions & 1 deletion src/intervals/arithmetic/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,15 @@ end

Implement the `sqrt` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.sqrt(x::BareInterval{T}) where {T<:NumTypes}
function Base.sqrt(x::BareInterval{T}) where {T<:AbstractFloat}
domain = _unsafe_bareinterval(T, zero(T), typemax(T))
x = intersect_interval(x, domain)
isempty_interval(x) && return x
return @round(T, sqrt(inf(x)), sqrt(sup(x)))
end

Base.sqrt(x::BareInterval{<:Rational}) = sqrt(float(x))

function Base.sqrt(x::Interval{T}) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, zero(T), typemax(T))
bx = bareinterval(x)
Expand Down
32 changes: 24 additions & 8 deletions src/intervals/arithmetic/hyperbolic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ for f ∈ (:sinh, :tanh, :asinh)

Implement the `$($f)` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.$f(x::BareInterval{T}) where {T<:NumTypes}
function Base.$f(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
return @round(T, $f(inf(x)), $f(sup(x)))
end

Base.$f(x::BareInterval{<:Rational}) = $f(float(x))

function Base.$f(x::Interval)
r = $f(bareinterval(x))
d = min(decoration(x), decoration(r))
Expand All @@ -29,11 +31,13 @@ end

Implement the `cosh` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.cosh(x::BareInterval{T}) where {T<:NumTypes}
function Base.cosh(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
return @round(T, cosh(mig(x)), cosh(mag(x)))
end

Base.cosh(x::BareInterval{<:Rational}) = cosh(float(x))

function Base.cosh(x::Interval)
r = cosh(bareinterval(x))
d = min(decoration(x), decoration(r))
Expand All @@ -46,7 +50,7 @@ end

Implement the `coth` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.coth(x::BareInterval{T}) where {T<:NumTypes}
function Base.coth(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
isthinzero(x) && return emptyinterval(BareInterval{T})
lo, hi = bounds(x)
Expand All @@ -61,6 +65,8 @@ function Base.coth(x::BareInterval{T}) where {T<:NumTypes}
end
end

Base.coth(x::BareInterval{<:Rational}) = coth(float(x))

function Base.coth(x::Interval)
bx = bareinterval(x)
r = coth(bx)
Expand All @@ -75,7 +81,7 @@ end

Implement the `sech` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.sech(x::BareInterval{T}) where {T<:NumTypes}
function Base.sech(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
lo, hi = bounds(x)
if lo ≥ 0 # decreasing function
Expand All @@ -87,6 +93,8 @@ function Base.sech(x::BareInterval{T}) where {T<:NumTypes}
end
end

Base.sech(x::BareInterval{<:Rational}) = sech(float(x))

function Base.sech(x::Interval)
r = sech(bareinterval(x))
d = min(decoration(x), decoration(r))
Expand All @@ -99,7 +107,7 @@ end

Implement the `csch` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.csch(x::BareInterval{T}) where {T<:NumTypes}
function Base.csch(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
isthinzero(x) && return emptyinterval(BareInterval{T})
lo, hi = bounds(x)
Expand All @@ -114,6 +122,8 @@ function Base.csch(x::BareInterval{T}) where {T<:NumTypes}
end
end

Base.csch(x::BareInterval{<:Rational}) = csch(float(x))

function Base.csch(x::Interval)
bx = bareinterval(x)
r = csch(bx)
Expand All @@ -128,13 +138,15 @@ end

Implement the `acosh` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.acosh(x::BareInterval{T}) where {T<:NumTypes}
function Base.acosh(x::BareInterval{T}) where {T<:AbstractFloat}
domain = _unsafe_bareinterval(T, one(T), typemax(T))
x = intersect_interval(x, domain)
isempty_interval(x) && return x
return @round(T, acosh(inf(x)), acosh(sup(x)))
end

Base.acosh(x::BareInterval{<:Rational}) = acosh(float(x))

function Base.acosh(x::Interval{T}) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, one(T), typemax(T))
bx = bareinterval(x)
Expand All @@ -150,7 +162,7 @@ end

Implement the `atanh` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.atanh(x::BareInterval{T}) where {T<:NumTypes}
function Base.atanh(x::BareInterval{T}) where {T<:AbstractFloat}
domain = _unsafe_bareinterval(T, -one(T), one(T))
x = intersect_interval(x, domain)
isempty_interval(x) && return x
Expand All @@ -159,6 +171,8 @@ function Base.atanh(x::BareInterval{T}) where {T<:NumTypes}
return bareinterval(T, res_lo, res_hi)
end

Base.atanh(x::BareInterval{<:Rational}) = atanh(float(x))

function Base.atanh(x::Interval{T}) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, -one(T), one(T))
bx = bareinterval(x)
Expand All @@ -174,7 +188,7 @@ end

Implement the `acoth` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function Base.acoth(x::BareInterval{T}) where {T<:NumTypes}
function Base.acoth(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
singular_domain = _unsafe_bareinterval(T, -one(T), one(T))
issubset_interval(x, singular_domain) && return emptyinterval(BareInterval{T})
Expand All @@ -192,6 +206,8 @@ function Base.acoth(x::BareInterval{T}) where {T<:NumTypes}
end
end

Base.acoth(x::BareInterval{<:Rational}) = acoth(float(x))

function Base.acoth(x::Interval{T}) where {T<:NumTypes}
singular_domain = _unsafe_bareinterval(T, -one(T), one(T))
bx = bareinterval(x)
Expand Down
16 changes: 12 additions & 4 deletions src/intervals/arithmetic/power.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ Compute the real `n`-th root of `x`.

Implement the `rootn` function of the IEEE Standard 1788-2015 (Table 9.1).
"""
function rootn(x::BareInterval{T}, n::Integer) where {T<:NumTypes}
function rootn(x::BareInterval{T}, n::Integer) where {T<:AbstractFloat}
isempty_interval(x) && return x
n == 0 && return emptyinterval(BareInterval{T})
n == 1 && return x
Expand All @@ -269,6 +269,8 @@ function rootn(x::BareInterval{T}, n::Integer) where {T<:NumTypes}
return @round(T, rootn(inf(x), n), rootn(sup(x), n))
end

rootn(x::BareInterval{<:Rational}) = rootn(float(x))

function rootn(x::Interval{T}, n::Integer) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, ifelse(iseven(n), zero(T), typemin(T)), typemax(T))
bx = bareinterval(x)
Expand Down Expand Up @@ -395,11 +397,13 @@ end

for f ∈ (:cbrt, :exp, :exp2, :exp10, :expm1)
@eval begin
function Base.$f(x::BareInterval{T}) where {T<:NumTypes}
function Base.$f(x::BareInterval{T}) where {T<:AbstractFloat}
isempty_interval(x) && return x
return @round(T, $f(inf(x)), $f(sup(x)))
end

Base.$f(x::BareInterval{<:Rational}) = $f(float(x))

function Base.$f(x::Interval)
bx = bareinterval(x)
r = $f(bx)
Expand All @@ -413,13 +417,15 @@ end

for f ∈ (:log, :log2, :log10)
@eval begin
function Base.$f(x::BareInterval{T}) where {T<:NumTypes}
function Base.$f(x::BareInterval{T}) where {T<:AbstractFloat}
domain = _unsafe_bareinterval(T, zero(T), typemax(T))
x = intersect_interval(x, domain)
isempty_interval(x) | (sup(x) == 0) && return emptyinterval(BareInterval{T})
return @round(T, $f(inf(x)), $f(sup(x)))
end

Base.$f(x::BareInterval{<:Rational}) = $f(float(x))

function Base.$f(x::Interval{T}) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, zero(T), typemax(T))
bx = bareinterval(x)
Expand All @@ -431,13 +437,15 @@ for f ∈ (:log, :log2, :log10)
end
end

function Base.log1p(x::BareInterval{T}) where {T<:NumTypes}
function Base.log1p(x::BareInterval{T}) where {T<:AbstractFloat}
domain = _unsafe_bareinterval(T, -one(T), typemax(T))
x = intersect_interval(x, domain)
isempty_interval(x) | (sup(x) == -1) && return emptyinterval(BareInterval{T})
return @round(T, log1p(inf(x)), log1p(sup(x)))
end

Base.log1p(x::BareInterval{<:Rational}) = log1p(float(x))

function Base.log1p(x::Interval{T}) where {T<:NumTypes}
domain = _unsafe_bareinterval(T, -one(T), typemax(T))
bx = bareinterval(x)
Expand Down
Loading
Loading