@@ -51,26 +51,34 @@ abstract InterpolationType{D<:Degree,BC<:BoundaryCondition,GR<:GridRepresentatio
5151include (" extrapolation.jl" )
5252
5353abstract AbstractInterpolation{T,N,IT<: InterpolationType ,EB<: ExtrapolationBehavior } <: AbstractArray{T,N}
54- type Interpolation{T ,N,IT<: InterpolationType ,EB<: ExtrapolationBehavior } <: AbstractInterpolation{T ,N,IT,EB}
55- coefs:: Array{T ,N}
54+ type Interpolation{TEl ,N,TCoefs <: Real , IT<: InterpolationType ,EB<: ExtrapolationBehavior } <: AbstractInterpolation{TEl ,N,IT,EB}
55+ coefs:: Array{TCoefs ,N}
5656end
57- function Interpolation {T ,N,IT<:InterpolationType,EB<:ExtrapolationBehavior} (A:: Array{T ,N} , it:: IT , :: EB )
57+ function Interpolation {TIn ,N,TCoefs, IT<:InterpolationType,EB<:ExtrapolationBehavior} (:: Type{TCoefs} , A:: AbstractArray{TIn ,N} , it:: IT , :: EB )
5858 isleaftype (IT) || error (" The interpolation type must be a leaf type (was $IT )" )
5959
60- isleaftype (T ) || warn (" For performance reasons, consider using an array of a concrete type T (eltype(A) == $(eltype (A)) )" )
60+ isleaftype (TIn ) || warn (" For performance reasons, consider using an array of a concrete type T (eltype(A) == $(eltype (A)) )" )
6161
62- Interpolation {T,N,IT,EB} (prefilter (A,it))
62+ c = one (TCoefs)
63+ for _ in 2 : N
64+ c *= c
65+ end
66+ TEl = typeof (c)
67+
68+ Interpolation {TEl,N,TCoefs,IT,EB} (prefilter (TCoefs,A,it))
6369end
70+ Interpolation {TIn,N,IT<:InterpolationType,EB<:ExtrapolationBehavior} (A:: AbstractArray{TIn,N} , it:: IT , eb:: EB ) = Interpolation (TIn, A, it, eb)
6471
6572# Unless otherwise specified, use coefficients as they are, i.e. without prefiltering
6673# However, all prefilters copy the array, so do that here as well
67- prefilter {T,N,IT<:InterpolationType} (A:: AbstractArray{T,N} , :: IT ) = copy (A)
74+ # We also ensure that the coefficient array is of the correct type
75+ prefilter {T,N,TCoefs,IT<:InterpolationType} (:: Type{TCoefs} , A:: AbstractArray{T,N} , :: IT ) = copy! (Array (TCoefs,size (A)... ), A)
6876
69- size {T,N,IT<:InterpolationType} (itp:: Interpolation{T,N,IT} , d:: Integer ) =
70- size (itp. coefs, d) - 2 * padding (IT ())
71- size (itp:: Interpolation ) = tuple ([size (itp,i) for i in 1 : ndims (itp)]. .. )
77+ size {T,N,TCoefs,IT<:InterpolationType} (itp:: Interpolation{T,N,TCoefs,IT} , d:: Integer ) = size (itp. coefs, d) - 2 * padding (TCoefs,IT ())
78+ size (itp:: AbstractInterpolation ) = tuple ([size (itp,i) for i in 1 : ndims (itp)]. .. )
7279ndims (itp:: Interpolation ) = ndims (itp. coefs)
73- eltype (itp:: Interpolation ) = eltype (itp. coefs)
80+ eltype {T} (itp:: Interpolation{T} ) = T
81+ coeftype (itp:: Interpolation ) = eltype (itp. coefs)
7482
7583offsetsym (off, d) = off == - 1 ? symbol (string (" ixm_" , d)) :
7684 off == 0 ? symbol (string (" ix_" , d)) :
@@ -89,8 +97,8 @@ include("linear.jl")
8997include (" quadratic.jl" )
9098
9199# If nothing else is specified, don't pad at all
92- padding (:: InterpolationType ) = 0
93- padding {T,N,IT<:InterpolationType} (:: Interpolation{T,N,IT} ) = padding (IT ())
100+ padding {T} (:: Type{T} , :: InterpolationType ) = zero (T)
101+ padding {T,N,IT<:InterpolationType} (:: Interpolation{T,N,IT} ) = padding (T, IT ())
94102
95103function pad_size_and_index (sz:: Tuple , pad)
96104 sz = Int[s+ 2 pad for s in sz]
@@ -101,10 +109,10 @@ function pad_size_and_index(sz::Tuple, pad)
101109 end
102110 sz, ind
103111end
104- function copy_with_padding (A, it:: InterpolationType )
112+ function copy_with_padding (TCoefs, A, it:: InterpolationType )
105113 pad = padding (it)
106114 sz,ind = pad_size_and_index (size (A), pad)
107- coefs = fill ( convert ( eltype (A), 0 ), sz... )
115+ coefs = fill! ( Array (TCoefs, sz... ), 0 )
108116 coefs[ind... ] = A
109117 coefs, pad
110118end
@@ -137,8 +145,8 @@ for IT in (
137145 gr = gridrepresentation (it)
138146 eval (ngenerate (
139147 :N ,
140- :( promote_type (T, x ... )) ,
141- :(getindex {T,N} (itp:: Interpolation{T,N,$IT,$EB} , x:: NTuple{N,Real } ...)),
148+ :T ,
149+ :(getindex {T,N,TCoefs<:Real } (itp:: Interpolation{T,N,TCoefs, $IT,$EB} , x:: NTuple{N,TCoefs } ...)),
142150 N-> quote
143151 # Handle extrapolation, by either throwing an error,
144152 # returning a value, or shifting x to somewhere inside
@@ -157,11 +165,14 @@ for IT in (
157165 ret
158166 end
159167 ))
168+ @ngenerate N T function getindex {T,N,TCoefs<:Real} (itp:: Interpolation{T,N,TCoefs,IT,EB} , xs:: NTuple{N,Real} ...)
169+ getindex (itp, [convert (TCoefs, x) for x in xs]. .. )
170+ end
160171
161172 eval (ngenerate (
162173 :N ,
163- :(Array{ promote_type (T, typeof (x) ... ), 1 }) ,
164- :(gradient! {T,N} (g:: Array{T,1} , itp:: Interpolation{T,N,$IT,$EB} , x:: NTuple{N,Real } ...)),
174+ :T ,
175+ :(gradient! {T,N,TCoefs } (g:: Array{T,1} , itp:: Interpolation{T,N,TCoefs, $IT,$EB} , x:: NTuple{N,TCoefs } ...)),
165176 N-> quote
166177 $ (extrap_transform_x (gr,eb,N))
167178 $ (define_indices (it,N))
@@ -180,7 +191,7 @@ for IT in (
180191 end
181192end
182193
183- gradient {T} (itp:: Interpolation{T} , x... ) = gradient! (Array (T,ndims (itp)), itp, x ... )
194+ gradient1 {T} (itp:: Interpolation{T,1 } , x) = gradient! (Array (T,1 ), itp,x)[ 1 ]
184195
185196# This creates prefilter specializations for all interpolation types that need them
186197for IT in (
@@ -193,8 +204,8 @@ for IT in (
193204 Quadratic{Periodic,OnGrid},
194205 Quadratic{Periodic,OnCell},
195206 )
196- @ngenerate N promote_type_grid (T, x... ) function prefilter {T,N} ( A:: Array{T,N} ,it:: IT )
197- ret, pad = copy_with_padding (A,it)
207+ @ngenerate N promote_type_grid (T, x... ) function prefilter {T,N,TCoefs} ( :: Type{TCoefs} , A:: Array{T,N} ,it:: IT )
208+ ret, pad = copy_with_padding (TCoefs, A,it)
198209
199210 szs = collect (size (ret))
200211 strds = collect (strides (ret))
@@ -203,7 +214,7 @@ for IT in (
203214 n = szs[dim]
204215 szs[dim] = 1
205216
206- M, b = prefiltering_system (eltype (A) , n, it)
217+ M, b = prefiltering_system (TCoefs , n, it)
207218
208219 @nloops N i d-> 1 : szs[d] begin
209220 cc = @ntuple N i
0 commit comments