Skip to content

Commit 2ba7253

Browse files
committed
Merge pull request #72 from tlycken/teh/typestability_fillvalue
Allow manual override of return type for fillvalue
2 parents 1c9ebfb + 67fd8f0 commit 2ba7253

File tree

5 files changed

+23
-12
lines changed

5 files changed

+23
-12
lines changed

src/b-splines/indexing.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ function gradient_impl{T,N,TCoefs,IT<:DimSpec{BSpline},GT<:DimSpec{GridType},Pad
6969
end
7070
end
7171

72+
function getindex_return_type{T,N,TCoefs,IT<:DimSpec{BSpline},GT<:DimSpec{GridType},Pad}(::Type{BSplineInterpolation{T,N,TCoefs,IT,GT,Pad}}, argtypes)
73+
Tret = TCoefs
74+
for a in argtypes
75+
Tret = Base.promote_op(Base.MulFun, Tret, a)
76+
end
77+
Tret
78+
end
79+
80+
7281
@generated function gradient!{T,N}(g::AbstractVector, itp::BSplineInterpolation{T,N}, xs::Number...)
7382
length(xs) == N || error("Can only be called with $N indexes")
7483
gradient_impl(itp)

src/extrapolation/extrapolation.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
export Throw,
2-
FilledExtrapolation # for direct control over typeof(fillvalue)
1+
export Throw
32

43
type Extrapolation{T,N,ITPT,IT,GT,ET} <: AbstractInterpolationWrapper{T,N,ITPT,IT,GT}
54
itp::ITPT

src/extrapolation/filled.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ type FilledExtrapolation{T,N,ITP<:AbstractInterpolation,IT,GT,FT} <: AbstractExt
55
itp::ITP
66
fillvalue::FT
77
end
8-
"""
9-
`FilledExtrapolation(itp, fillvalue)` creates an extrapolation object that returns the `fillvalue` any time the indexes in `itp[x1,x2,...]` are out-of-bounds.
108

11-
By comparison with `extrapolate`, this version lets you control the `fillvalue`'s type directly. It's important for the `fillvalue` to be of the same type as returned by `itp[x1,x2,...]` for in-bounds regions for the index types you are using; otherwise, indexing will be type-unstable (and slow).
12-
"""
139
function FilledExtrapolation{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, fillvalue)
1410
FilledExtrapolation{T,N,typeof(itp),IT,GT,typeof(fillvalue)}(itp, fillvalue)
1511
end
@@ -19,15 +15,16 @@ end
1915
"""
2016
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, fillvalue) = FilledExtrapolation(itp, convert(eltype(itp), fillvalue))
2117

22-
@generated function getindex{T,N}(fitp::FilledExtrapolation{T,N}, args::Number...)
18+
@generated function getindex{T,N,ITP,IT,GT,FT}(fitp::FilledExtrapolation{T,N,ITP,IT,GT,FT}, args::Number...)
2319
n = length(args)
2420
n == N || return error("Must index $(N)-dimensional interpolation objects with $(nindexes(N))")
21+
Tret = FT<:Number ? getindex_return_type(ITP, args) : FT
2522
meta = Expr(:meta, :inline)
2623
quote
2724
$meta
2825
# Check to see if we're in the extrapolation region, i.e.,
2926
# out-of-bounds in an index
30-
@nexprs $N d->((args[d] < lbound(fitp,d) || args[d] > ubound(fitp, d)) && return fitp.fillvalue)
27+
@nexprs $N d->((args[d] < lbound(fitp,d) || args[d] > ubound(fitp, d)) && return convert($Tret, fitp.fillvalue))
3128
# In the interpolation region
3229
return getindex(fitp.itp,args...)
3330
end

src/gridded/indexing.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,11 @@ function getindex{T,N,TCoefs,IT<:DimSpec{Gridded},K,P}(itp::GriddedInterpolation
8686
dest = Array(T, map(length, x))::Array{T,N}
8787
getindex!(dest, itp, x...)
8888
end
89+
90+
function getindex_return_type{T,N,TCoefs,IT<:DimSpec{Gridded},K,P}(::Type{GriddedInterpolation{T,N,TCoefs,IT,K,P}}, argtypes)
91+
Tret = TCoefs
92+
for a in argtypes
93+
Tret = Base.promote_op(Base.MulFun, Tret, a)
94+
end
95+
Tret
96+
end

test/extrapolation/runtests.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ etpf = @inferred(extrapolate(itpg, NaN))
2727
@test_throws BoundsError etpf[2.5,2]
2828
@test_throws ErrorException etpf[2.5,2,1] # this will probably become a BoundsError someday
2929

30-
etpf = @inferred(FilledExtrapolation(itpg, 'x'))
31-
@test_approx_eq etpf[2] f(2)
32-
@test etpf[-1.5] == 'x'
30+
@test isa(@inferred(getindex(etpf, dual(-2.5,1))), Dual)
3331

3432
etpl = extrapolate(itpg, Linear)
3533
k_lo = A[2] - A[1]
@@ -61,4 +59,4 @@ etp2ll = extrapolate(itp2g, Linear)
6159

6260
end
6361

64-
include("type-stability.jl")
62+
include("type-stability.jl")

0 commit comments

Comments
 (0)