Skip to content

Commit 9a38d80

Browse files
authored
Merge pull request #258 from JuliaIntervals/type_stability
Type stability for some functions
2 parents e21de86 + eac7652 commit 9a38d80

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

src/intervals/arithmetic.jl

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ function inv(a::Interval{T}) where T<:Real
162162
isempty(a) && return emptyinterval(a)
163163

164164
if zero(T) a
165-
a.lo < zero(T) == a.hi && return @round(-Inf, inv(a.lo))
166-
a.lo == zero(T) < a.hi && return @round(inv(a.hi), Inf)
165+
a.lo < zero(T) == a.hi && return @round(T(-Inf), inv(a.lo))
166+
a.lo == zero(T) < a.hi && return @round(inv(a.hi), T(Inf))
167167
a.lo < zero(T) < a.hi && return entireinterval(T)
168168
a == zero(a) && return emptyinterval(T)
169169
end
@@ -195,14 +195,14 @@ function /(a::Interval{T}, b::Interval{T}) where T<:Real
195195

196196
if iszero(b.lo)
197197

198-
a.lo >= zero(T) && return @round(a.lo/b.hi, Inf)
199-
a.hi <= zero(T) && return @round(-Inf, a.hi/b.hi)
198+
a.lo >= zero(T) && return @round(a.lo/b.hi, T(Inf))
199+
a.hi <= zero(T) && return @round(T(-Inf), a.hi/b.hi)
200200
return entireinterval(S)
201201

202202
elseif iszero(b.hi)
203203

204-
a.lo >= zero(T) && return @round(-Inf, a.lo/b.lo)
205-
a.hi <= zero(T) && return @round(a.hi/b.lo, Inf)
204+
a.lo >= zero(T) && return @round(T(-Inf), a.lo/b.lo)
205+
a.hi <= zero(T) && return @round(a.hi/b.lo, T(Inf))
206206
return entireinterval(S)
207207

208208
else
@@ -218,10 +218,10 @@ function extended_div(a::Interval{T}, b::Interval{T}) where T<:Real
218218
S = typeof(a.lo / b.lo)
219219
if 0 < b.hi && 0 > b.lo && 0 a
220220
if a.hi < 0
221-
return (Interval(-Inf, a.hi / b.hi), Interval(a.hi / b.lo, Inf))
221+
return (Interval(T(-Inf), a.hi / b.hi), Interval(a.hi / b.lo, T(Inf)))
222222

223223
elseif a.lo > 0
224-
return (Interval(-Inf, a.lo / b.lo), Interval(a.lo / b.hi, Inf))
224+
return (Interval(T(-Inf), a.lo / b.lo), Interval(a.lo / b.hi, T(Inf)))
225225

226226
end
227227
elseif 0 a && 0 b
@@ -394,7 +394,7 @@ The default is the true midpoint at `α = 0.5`.
394394
395395
Assumes 0 ≤ α ≤ 1.
396396
397-
Warning: if the parameter `α = 0.5` is explicitely set, the behavior differs
397+
Warning: if the parameter `α = 0.5` is explicitly set, the behavior differs
398398
from the default case if the provided `Interval` is not finite, since when
399399
`α` is provided `mid` simply replaces `+∞` (respectively `-∞`) by `prevfloat(+∞)`
400400
(respecively `nextfloat(-∞)`) for the computation of the intermediate point.
@@ -403,16 +403,18 @@ function mid(a::Interval{T}, α) where T
403403

404404
isempty(a) && return convert(T, NaN)
405405

406-
lo = (a.lo == -? nextfloat(-) : a.lo)
407-
hi = (a.hi == +? prevfloat(+) : a.hi)
406+
lo = (a.lo == -? nextfloat(T(-∞)) : a.lo)
407+
hi = (a.hi == +? prevfloat(T(+∞)) : a.hi)
408408

409-
midpoint = α * (hi - lo) + lo
409+
β = convert(T, α)
410+
411+
midpoint = β * (hi - lo) + lo
410412
isfinite(midpoint) && return midpoint
411413
#= Fallback in case of overflow: hi - lo == +∞.
412414
This case can not be the default one as it does not pass several
413415
IEEE1788-2015 tests for small floats.
414416
=#
415-
return (1-α) * lo + α * hi
417+
return (1 - β) * lo + β * hi
416418
end
417419

418420
"""
@@ -432,13 +434,13 @@ function mid(a::Interval{T}) where T
432434
a.lo == -&& return nextfloat(a.lo)
433435
a.hi == +&& return prevfloat(a.hi)
434436

435-
midpoint = 0.5 * (a.lo + a.hi)
437+
midpoint = (a.lo + a.hi) / 2
436438
isfinite(midpoint) && return midpoint
437439
#= Fallback in case of overflow: a.hi + a.lo == +∞ or a.hi + a.lo == -∞.
438440
This case can not be the default one as it does not pass several
439441
IEEE1788-2015 tests for small floats.
440442
=#
441-
return 0.5 * a.lo + 0.5 * a.hi
443+
return a.lo / 2 + a.hi / 2
442444
end
443445

444446
mid(a::Interval{Rational{T}}) where T = (1//2) * (a.lo + a.hi)

src/intervals/rounding_macros.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function round_expr(ex::Expr, rounding_mode::RoundingMode)
2222
return :( $(esc(op))( $(esc(ex.args[2])), $(esc(ex.args[3])), $rounding_mode) )
2323

2424
else # unary operator
25-
return :( $op($(esc(ex.args[2])), $rounding_mode ) )
25+
return :( $(esc(op))($(esc(ex.args[2])), $rounding_mode ) )
2626
end
2727
else
2828
return ex

test/interval_tests/consistency.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,26 @@ setprecision(Interval, Float64)
388388

389389
end
390390

391+
@testset "Type stability" begin
392+
for T in (Float32, Float64, BigFloat)
393+
394+
xs = [3..4, 0..4, 0..0, -4..0, -4..4, -Inf..4, 4..Inf, -Inf..Inf]
395+
396+
for x in xs
397+
for y in xs
398+
xx = Interval{T}(x)
399+
yy = Interval{T}(y)
400+
401+
for op in (+, -, *, /, atan)
402+
@inferred op(x, y)
403+
end
404+
end
405+
406+
for op in (sin, cos, exp, log, tan, abs, mid, diam)
407+
@inferred op(x)
408+
end
409+
end
410+
end
411+
end
412+
391413
end

0 commit comments

Comments
 (0)