Skip to content

Commit 839c1d3

Browse files
authored
Merge pull request #190 from JuliaMath/teh/heisenbug
Don't use generated function for FilledExtrapolation
2 parents 0c72079 + 181d191 commit 839c1d3

File tree

3 files changed

+20
-20
lines changed

3 files changed

+20
-20
lines changed

src/extrapolation/filled.jl

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,18 @@ Base.parent(A::FilledExtrapolation) = A.itp
1717
"""
1818
extrapolate(itp::AbstractInterpolation{T,N,IT,GT}, fillvalue) where {T,N,IT,GT} = FilledExtrapolation(itp, fillvalue)
1919

20-
function getindex_impl(fitp::Type{FilledExtrapolation{T,N,ITP,IT,GT,FT}}, args) where {T,N,ITP,IT,GT,FT}
21-
n = length(args)
22-
n == N || return error("Must index $(N)-dimensional interpolation objects with $(nindexes(N))")
23-
24-
Tret = FT<:Number ? getindex_return_type(ITP, (T, args...)) : FT
25-
meta = Expr(:meta, :inline)
26-
quote
27-
$meta
28-
# Check to see if we're in the extrapolation region, i.e.,
29-
# out-of-bounds in an index
30-
inds_etp = indices(fitp)
31-
@nexprs $N d->((args[d] < lbound(fitp, d, inds_etp[d]) || args[d] > ubound(fitp, d, inds_etp[d]))) && return convert($Tret, fitp.fillvalue)::$Tret
32-
# In the interpolation region
33-
return convert($Tret, getindex(fitp.itp,args...))::$Tret
34-
end
20+
@inline function getindex(fitp::FilledExtrapolation{T,N,ITP,IT,GT,FT}, args::Vararg{Number,M}) where {T,N,ITP,IT,GT,FT,M}
21+
inds, trailing = Base.IteratorsMD.split(args, Val{N})
22+
@boundscheck all(x->x==1, trailing) || Base.throw_boundserror(fitp, args)
23+
Tret = typeof(prod(inds) * zero(T))
24+
checkbounds(Bool, fitp, inds...) && return convert(Tret, fitp.itp[inds...])
25+
convert(Tret, fitp.fillvalue)
3526
end
3627

37-
38-
@generated function getindex(fitp::FilledExtrapolation{T,N,ITP,IT,GT,FT}, args::Number...) where {T,N,ITP,IT,GT,FT}
39-
getindex_impl(fitp, args)
40-
end
28+
@inline Base.checkbounds(::Type{Bool}, A::FilledExtrapolation, I...) = _checkbounds(A, 1, indices(A), I)
29+
@inline _checkbounds(A, d::Int, IA::TT1, I::TT2) where {TT1,TT2} =
30+
(I[1] >= lbound(A, d, IA[1])) & (I[1] <= ubound(A, d, IA[1])) & _checkbounds(A, d+1, Base.tail(IA), Base.tail(I))
31+
_checkbounds(A, d::Int, ::Tuple{}, ::Tuple{}) = true
4132

4233
getindex(fitp::FilledExtrapolation{T,1}, x::Number, y::Int) where {T} = y == 1 ? fitp[x] : throw(BoundsError())
4334

test/extrapolation/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ etpf = @inferred(extrapolate(itpg, NaN))
2929

3030
@test etpf[2.5,1] == etpf[2.5] # for show method
3131
@test_throws BoundsError etpf[2.5,2]
32-
@test_throws ErrorException etpf[2.5,2,1] # this will probably become a BoundsError someday
32+
@test_throws BoundsError etpf[2.5,2,1]
3333

3434
x = @inferred(getindex(etpf, dual(-2.5,1)))
3535
@test isa(x, Dual)

test/extrapolation/type-stability.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,13 @@ for (etp2,E) in map(E -> (extrapolate(itp2, E()), E), schemes),
5050
@inferred(getindex(etp2, x, y))
5151
end
5252

53+
A = [1 2; 3 4]
54+
Af = Float64.(A)
55+
for B in (A, Af)
56+
itpg = interpolate(B, BSpline(Linear()), OnGrid())
57+
etp = extrapolate(itpg, NaN)
58+
@test typeof(@inferred(getindex(etp, dual(1.5,1), dual(1.5,1)))) ==
59+
typeof(@inferred(getindex(etp, dual(6.5,1), dual(3.5,1))))
60+
end
61+
5362
end

0 commit comments

Comments
 (0)