Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 345b28f

Browse files
author
Tomas Lycken
committedJan 1, 2015
First attempt at handling eltypes better
1 parent cfe3e8a commit 345b28f

File tree

4 files changed

+53
-53
lines changed

4 files changed

+53
-53
lines changed
 

‎src/Interpolations.jl

+33-22
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,34 @@ abstract InterpolationType{D<:Degree,BC<:BoundaryCondition,GR<:GridRepresentatio
5151
include("extrapolation.jl")
5252

5353
abstract 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}
5656
end
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))
6369
end
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)]...)
7279
ndims(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

7583
offsetsym(off, d) = off == -1 ? symbol(string("ixm_", d)) :
7684
off == 0 ? symbol(string("ix_", d)) :
@@ -89,8 +97,8 @@ include("linear.jl")
8997
include("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

95103
function pad_size_and_index(sz::Tuple, pad)
96104
sz = Int[s+2pad for s in sz]
@@ -101,10 +109,10 @@ function pad_size_and_index(sz::Tuple, pad)
101109
end
102110
sz, ind
103111
end
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
110118
end
@@ -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
181192
end
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
186197
for 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

‎src/extrapolation.jl

+1-12
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,7 @@ end
8282

8383
immutable ExtrapPeriodic <: ExtrapolationBehavior end
8484
function extrap_transform_x(::GridRepresentation, ::ExtrapPeriodic, N)
85-
quote
86-
@nexprs $N d->begin
87-
# translate x_d to inside the domain
88-
n = convert(typeof(x_d), size(itp,d))
89-
while x_d < .5
90-
x_d += n
91-
end
92-
while x_d >= n + .5
93-
x_d -= n
94-
end
95-
end
96-
end
85+
:(@nexprs $N d->(x_d = mod1(x_d, size(itp,d))))
9786
end
9887

9988
immutable ExtrapLinear <: ExtrapolationBehavior end

‎src/linear.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ Linear{GR<:GridRepresentation}(::GR) = Linear{GR}()
55
function define_indices(::Linear, N)
66
quote
77
@nexprs $N d->begin
8-
ix_d = clamp(floor(Int,x_d), 1, size(itp,d)-1)
9-
ixp_d = ix_d + 1
10-
fx_d = x_d - convert(typeof(x_d), ix_d)
8+
ix_d = clamp(floor(x_d), 1, size(itp,d)-1)
9+
ixp_d = ix_d + one(typeof(ix_d))
10+
fx_d = x_d - ix_d
1111
end
1212
end
1313
end

‎src/quadratic.jl

+16-16
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ Quadratic{BC<:BoundaryCondition,GR<:GridRepresentation}(::BC, ::GR) = Quadratic{
55

66
function define_indices(q::Quadratic, N)
77
quote
8-
pad = padding($q)
8+
pad = padding(TCoefs, $q)
99
@nexprs $N d->begin
10-
ix_d = clamp(round(Integer, x_d), 1, size(itp,d)) + pad
10+
ix_d = clamp(round(x_d), 1, size(itp,d)) + pad
1111
ixp_d = ix_d + 1
1212
ixm_d = ix_d - 1
1313

14-
fx_d = x_d - convert(typeof(x_d), ix_d - pad)
14+
fx_d = x_d - (ix_d - pad)
1515
end
1616
end
1717
end
1818
function define_indices(q::Quadratic{Periodic}, N)
1919
quote
20-
pad = padding($q)
20+
pad = padding(TCoefs, $q)
2121
@nexprs $N d->begin
22-
ix_d = clamp(round(Integer, x_d), 1, size(itp,d)) + pad
23-
ixp_d = mod1(ix_d + 1, size(itp,d))
24-
ixm_d = mod1(ix_d - 1, size(itp,d))
22+
ix_d = clamp(round(x_d), 1, size(itp,d)) + pad
23+
ixp_d = mod1(ix_d + one(typeof(ix_d)), size(itp,d))
24+
ixm_d = mod1(ix_d - one(typeof(ix_d)), size(itp,d))
2525

26-
fx_d = x_d - convert(typeof(x_d), ix_d - pad)
26+
fx_d = x_d - (ix_d - pad)
2727
end
2828
end
2929
end
@@ -36,19 +36,19 @@ function coefficients(q::Quadratic, N, d)
3636
symm, sym, symp = symbol(string("cm_",d)), symbol(string("c_",d)), symbol(string("cp_",d))
3737
symfx = symbol(string("fx_",d))
3838
quote
39-
$symm = .5 * ($symfx - .5)^2
40-
$sym = .75 - $symfx^2
41-
$symp = .5 * ($symfx + .5)^2
39+
$symm = convert(TCoefs, .5) * ($symfx - convert(TCoefs, .5))^2
40+
$sym = convert(TCoefs, .75) - $symfx^2
41+
$symp = convert(TCoefs, .5) * ($symfx + convert(TCoefs, .5))^2
4242
end
4343
end
4444

4545
function gradient_coefficients(q::Quadratic, N, d)
4646
symm, sym, symp = symbol(string("cm_",d)), symbol(string("c_",d)), symbol(string("cp_",d))
4747
symfx = symbol(string("fx_",d))
4848
quote
49-
$symm = $symfx-.5
50-
$sym = -2*$symfx
51-
$symp = $symfx+.5
49+
$symm = $symfx - convert(TCoefs, .5)
50+
$sym = -convert(TCoefs, 2) * $symfx
51+
$symp = $symfx + convert(TCoefs, .5)
5252
end
5353
end
5454

@@ -69,10 +69,10 @@ end
6969
# Quadratic interpolation has 1 extra coefficient at each boundary
7070
# Therefore, make the coefficient array 1 larger in each direction,
7171
# in each dimension.
72-
padding(::Quadratic) = 1
72+
padding{T}(::Type{T}, ::Quadratic) = one(T)
7373
# For periodic boundary conditions, we don't pad - instead, we wrap the
7474
# the coefficients
75-
padding(::Quadratic{Periodic}) = 0
75+
padding{T}(::Type{T}, ::Quadratic{Periodic}) = zero(T)
7676

7777
function inner_system_diags{T}(::Type{T}, n::Int, ::Quadratic)
7878
du = fill(convert(T,1/8), n-1)

0 commit comments

Comments
 (0)
Please sign in to comment.