Skip to content

Commit be88fca

Browse files
committed
WIP: complete refactor
1 parent ef5c6b0 commit be88fca

File tree

11 files changed

+214
-97
lines changed

11 files changed

+214
-97
lines changed

src/b-splines/b-splines.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ end
8383

8484
index_gen{IT}(::Type{IT}, N::Integer, offsets...) = index_gen(iextract(IT, min(length(offsets)+1, N)), IT, N, offsets...)
8585

86-
@generated function gradient{T,N,TCoefs,IT,GT,pad}(itp::BSplineInterpolation{T,N,TCoefs,IT,GT,pad}, xs...)
87-
n = count_interp_dims(IT, N)
88-
:(gradient!(Array(T,$n), itp, xs...))
89-
end
90-
9186
include("constant.jl")
9287
include("linear.jl")
9388
include("quadratic.jl")

src/b-splines/indexing.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ function gradient_impl{T,N,TCoefs,IT<:DimSpec{BSpline},GT<:DimSpec{GridType},Pad
5858
end
5959

6060

61+
@generated function gradient{T,N,TCoefs,IT,GT,pad}(itp::BSplineInterpolation{T,N,TCoefs,IT,GT,pad}, xs...)
62+
n = count_interp_dims(IT, N)
63+
quote
64+
@which gradient!(Array(T, $n), itp, xs...)
65+
gradient!(Array(T,$n), itp, xs...)
66+
end
67+
end
68+
6169
@generated function gradient!{T,N}(g::AbstractVector, itp::BSplineInterpolation{T,N}, xs::Number...)
6270
length(xs) == N || error("Can only be called with $N indexes")
6371
gradient_impl(itp)

src/extrapolation/constant.jl

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
type ConstantExtrapolation{T,N,ITP,IT,GT} <: AbstractExtrapolation{T,N,ITP,IT,GT}
2-
itp::ITP
1+
function extrap_prep(N, ::Type{Tuple{Flat,Flat}})
2+
:(@nexprs $N d->(xs_d = clamp(xs_d, lbound(etp,d), ubound(etp,d))))
33
end
4-
ConstantExtrapolation{T,ITP,IT,GT}(::Type{T}, N, itp::ITP, ::Type{IT}, ::Type{GT}) =
5-
ConstantExtrapolation{T,N,ITP,IT,GT}(itp)
64

7-
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{Flat}) =
8-
ConstantExtrapolation(T,N,itp,IT,GT)
9-
10-
function extrap_prep{T,N,ITP,IT,GT}(etp::Type{ConstantExtrapolation{T,N,ITP,IT,GT}}, xs...)
11-
:(@nexprs $N d->(xs_d = clamp(xs[d], lbound(etp,d), ubound(etp,d))))
5+
function extrap_prep{T}(N, ::Type{Tuple{Flat,T}})
6+
quote
7+
@nexprs $N d->(xs_d = max(xs_d, lbound(etp,d)))
8+
$(extrap_prep_hi(N, T))
9+
end
1210
end
1311

14-
lbound(etp::ConstantExtrapolation, d) = lbound(etp.itp, d)
15-
ubound(etp::ConstantExtrapolation, d) = ubound(etp.itp, d)
12+
function extrap_prep_hi(N, ::Type{Flat})
13+
:(@nexprs $N d->(xs_d = min(xs_d, ubound(etp,d))))
14+
end

src/extrapolation/error.jl

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
immutable Throw end
2-
type ErrorExtrapolation{T,N,ITPT,IT,GT} <: AbstractExtrapolation{T,N,ITPT,IT,GT}
3-
itp::IT
2+
3+
function extrap_prep(N, ::Type{Tuple{Throw,Throw}})
4+
:(@nexprs $N d->(lbound(etp, d) <= xs_d <= ubound(etp, d) || throw(BoundsError())))
45
end
5-
ErrorExtrapolation{T,ITPT,IT,GT}(::Type{T}, N, itp::ITPT, ::Type{IT}, ::Type{GT}) =
6-
ErrorExtrapolation{T,N,ITPT,IT,GT}(itp)
7-
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{Throw}) =
8-
ErrorExtrapolation(T,N,itp,IT,GT)
96

10-
function extrap_prep{T,N,ITPT,IT,GT}(etp::Type{ErrorExtrapolation{T,N,ITPT,IT,GT}}, xs...)
11-
:(@nexprs $N d->(lbound(etp,d) <= xs[d] <= ubound(etp,d) || throw(BoundsError())))
7+
function extrap_prep{T}(N, ::Type{Tuple{Throw,T}})
8+
quote
9+
@nexprs $N d->(lbound(etp, d) <= xs_d || throw(BoundsError()))
10+
extrap_prep_hi(T, xs...)
11+
end
1212
end
1313

14-
lbound(etp::ErrorExtrapolation, d) = lbound(etp.itp, d)
15-
ubound(etp::ErrorExtrapolation, d) = ubound(etp.itp, d)
14+
function extrap_prep_hi(N, ::Type{Throw})
15+
:(@nexprs $N d->(xs_d <= ubound(etp, d) || throw(BoundsError())))
16+
end

src/extrapolation/extrapolation.jl

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,41 @@
11
export Throw,
22
FilledExtrapolation # for direct control over typeof(fillvalue)
33

4+
type Extrapolation{T,N,ITPT,IT,GT,ET} <: AbstractInterpolationWrapper{T,N,ITPT,IT,GT}
5+
itp::ITPT
6+
end
7+
Extrapolation{T,ITPT,IT,GT,ET}(::Type{T}, N, itp::ITPT, ::Type{IT}, ::Type{GT}, ::Type{ET}) =
8+
Extrapolation{T,N,ITPT,IT,GT,ET}(itp)
9+
extrapolate{T,N,IT,GT,ET}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{ET}) =
10+
Extrapolation(T,N,itp,IT,GT,ET)
11+
12+
extrap_prep{T}(N, ::Type{T}) = extrap_prep(N, Tuple{T,T})
13+
14+
415
include("error.jl")
516
include("constant.jl")
617
include("linear.jl")
718
include("reflect.jl")
819
include("periodic.jl")
9-
include("indexing.jl")
20+
21+
@generated function getindex{T,N,ITPT,IT,GT,ET}(etp::Extrapolation{T,N,ITPT,IT,GT,ET}, xs...)
22+
quote
23+
@nexprs $N d->(xs_d = xs[d])
24+
$(extrap_prep(N, ET))
25+
itp = etp.itp
26+
@nref $N itp xs
27+
end
28+
end
29+
30+
@generated function gradient!{T,N,ITPT,IT,GT,ET}(g::AbstractVector, etp::Extrapolation{T,N,ITPT,IT,GT,ET}, xs...)
31+
quote
32+
$(extrap_prep_gradient(N, ET, xs...))
33+
gradient!(g)
34+
end
35+
end
36+
37+
lbound(etp::Extrapolation, d) = lbound(etp.itp, d)
38+
ubound(etp::Extrapolation, d) = ubound(etp.itp, d)
39+
size(etp::Extrapolation, d) = size(etp.itp, d)
1040

1141
include("filled.jl")

src/extrapolation/indexing.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +0,0 @@
1-
@generated function getindex{T,N}(etp::AbstractExtrapolation{T,N}, xs...)
2-
quote
3-
$(extrap_prep(etp, xs...))
4-
itp = etp.itp
5-
@nref $N itp xs
6-
end
7-
end

src/extrapolation/linear.jl

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,32 @@
1-
type LinearExtrapolation{T,N,ITP,IT,GT} <: AbstractExtrapolation{T,N,ITP,IT,GT}
2-
itp::ITP
1+
function extrap_prep{T}(N, ::Type{Tuple{Linear,T}}, xs...)
2+
quote
3+
$(extrap_prep_lo(N, Linear, xs...))
4+
$(extrap_prep_hi(N, T, xs...))
5+
end
36
end
4-
LinearExtrapolation{T,ITP,IT,GT}(::Type{T}, N, itp::ITP, ::Type{IT}, ::Type{GT}) =
5-
LinearExtrapolation{T,N,ITP,IT,GT}(itp)
67

7-
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{Linear}) =
8-
LinearExtrapolation(T,N,itp,IT,GT)
9-
10-
function extrap_prep{T,N,ITP,IT}(etp::Type{LinearExtrapolation{T,N,ITP,IT,OnGrid}}, xs...)
8+
function extrap_prep_lo(N, ::Type{Linear})
9+
coords = [symbol("xs_", k) for k in 1:N]
1110
quote
12-
xc = collect(xs...)
1311
@nexprs $N d->begin
14-
if xc[d] < 1
15-
xc[d] = one(eltype(xc))
16-
k = gradient(etp.itp, xc...)[d]
17-
return etp.itp[xc...] + k * (xs[d] - one(typeof(xc[d])))
18-
elseif xc[d] > size(etp.itp, d)
19-
xc[d] = size(etp.itp, d)
20-
k = gradient(etp.itp, xc...)[d]
21-
return etp.itp[xc...] + k * (xs[d] - size(etp.itp, d))
12+
if xs_d < lbound(etp.itp, d)
13+
xs_d = lbound(etp.itp, d)
14+
k = gradient(etp.itp, $(coords...))[d]
15+
return (@nref $N etp xs) + k * (xs[d] - lbound(etp.itp, d))
2216
end
17+
2318
end
2419
end
2520
end
26-
27-
function extrap_prep{T,N,ITP,IT}(etp::Type{LinearExtrapolation{T,N,ITP,IT,OnCell}}, xs...)
21+
function extrap_prep_hi(N, ::Type{Linear})
22+
coords = [symbol("xs_", k) for k in 1:N]
2823
quote
29-
xc = collect(xs...)
3024
@nexprs $N d->begin
31-
if xc[d] < 1//2
32-
xc[d] = convert(typeof(xc[d], 1//2))
33-
k = gradient(etp.itp, xc...)[d]
34-
return etp.itp[xc...] + k * (xs[d] - convert(typeof(xc[d], 1//2)))
35-
elseif xc[d] > size(etp.itp, d) + 1//2
36-
xc[d] = size(etp.itp, d) + convert(typeof(xc[d], 1//2))
37-
k = gradient(etp.itp, xc...)[d]
38-
return etp.itp[xc...] + k * (xs[d] - size(etp.itp, d) - convert(typeof(xc[d], 1//2)))
25+
if xs_d > ubound(etp.itp, d)
26+
xs_d = ubound(etp.itp, d)
27+
k = gradient(etp.itp, $(coords...))[d]
28+
return (@nref $N etp xs) + k * (xs[d] - ubound(etp.itp, d))
3929
end
4030
end
41-
@nexprs $N d->(x_d = xs[d])
4231
end
4332
end

src/extrapolation/periodic.jl

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,39 @@
1-
type PeriodicExtrapolation{T,N,ITP,IT,GT} <: AbstractExtrapolation{T,N,ITP,IT,GT}
2-
itp::ITP
1+
function extrap_prep(N, ::Type{Tuple{Periodic, Periodic}})
2+
:(@nexprs $N d->$(extrap_prep_dim(:d, Periodic)))
33
end
4-
PeriodicExtrapolation{T,ITP,IT,GT}(::Type{T}, N, itp::ITP, ::Type{IT}, ::Type{GT}) =
5-
PeriodicExtrapolation{T,N,ITP,IT,GT}(itp)
64

7-
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{Periodic}) =
8-
PeriodicExtrapolation(T,N,itp,IT,GT)
5+
function extrap_prep_dim(d, ::Type{Periodic})
6+
xs_d = symbol("xs_", d)
7+
:($xs_d = mod(xs[$d] - lbound(etp.itp, $d), ubound(etp.itp, $d) - lbound(etp.itp, $d)) + lbound(etp.itp, $d))
8+
end
99

10-
function extrap_prep{T,N,ITP,IT,GT}(etp::Type{PeriodicExtrapolation{T,N,ITP,IT,GT}}, xs...)
11-
:(@nexprs $N d->(x_d = mod(xs[d]-one($xs[d]), size(etp.itp,d)-one($xs[d]))+one($xs[d])))
10+
function extrap_prep{T}(N, ::Type{Tuple{Periodic, T}})
11+
quote
12+
@nexprs $N d -> begin
13+
xs_d = xs[d]
14+
if xs_d < lbound(etp.itp, d)
15+
$(extrap_prep_dim(:d, Periodic))
16+
end
17+
end
18+
$(extrap_prep_hi(N, T))
19+
end
20+
end
21+
function extrap_prep_hi(N, ::Type{Periodic})
22+
quote
23+
@nexprs $N d -> begin
24+
xs_d = xs[d]
25+
if xs_d > ubound(etp.itp, d)
26+
$(extrap_prep_dim(d, Periodic))
27+
end
28+
end
29+
end
1230
end
31+
#=
32+
33+
0 <= x - lbound(itp) < ubound(itp) - lbound(itp)
34+
35+
=> N = ubound(itp) - lbound(itp)
36+
37+
mod(x - lbound(itp), ubound(itp) - lbound(itp)) + lbound(itp) =
38+
39+
=#

src/extrapolation/reflect.jl

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
1-
type ReflectingExtrapolation{T,N,ITP,IT,GT} <: AbstractExtrapolation{T,N,ITP,IT,GT}
2-
itp::ITP
1+
function extrap_prep(N, ::Type{Tuple{Reflect,Reflect}})
2+
:(@nexprs $N d->$(extrap_prep_dim(:d, Reflect)))
33
end
4-
ReflectingExtrapolation{T,ITP,IT,GT}(::Type{T}, N, itp::ITP, ::Type{IT}, ::Type{GT}) =
5-
ReflectingExtrapolation{T,N,ITP,IT,GT}(itp)
64

7-
extrapolate{T,N,IT,GT}(itp::AbstractInterpolation{T,N,IT,GT}, ::Type{Reflect}) =
8-
ReflectingExtrapolation(T,N,itp,IT,GT)
95

10-
function extrap_prep{T,N,ITP,IT,GT}(etp::Type{ReflectingExtrapolation{T,N,ITP,IT,GT}}, xs...)
11-
# First, translate x into the domain over [1,2N-1) (OnGrid) or [.5,2N+.5) (OnCell)
12-
# i.e. into twice the size of the domain.
13-
# Next, if x is now in the upper part of this "double-domain", reflect over the middle
14-
# to obtain a new value x' for which f(x') == f(x), but where x' is inside the domain
15-
if GT == OnGrid
16-
return quote
17-
@nexprs $N d->begin
18-
x_d = mod(xs[d] - one($xs[d]), 2 * size(etp.itp,d) - 2) + one($xs[d])
19-
x_d > size(etp.itp,d) && (x_d = convert($xs[d], 2) * size(etp.itp,d) - x_d)
20-
end
21-
end
22-
else # GT == OnCell
23-
return quote
24-
@nexprs $N d->begin
25-
x_d = mod(xs[d] - 1//2, 2*size(etp.itp,d) + 1//2)
26-
x_d > size(etp.itp,d) + 1//2 && (x = convert($xs[d],2) * size(etp.itp,d) + one($xs[d] - x_d))
27-
end
28-
end
6+
"""
7+
`extrap_prep_dim(d, ::Type{Reflect})`
8+
9+
First, translate x into the domain over [lbound, 2(ubound-lbound)) i.e. into twice the size of the domain.
10+
Next, if x is now in the upper part of this ''double-domain´´, reflect over the middle to obtain a new value x' for which f(x') == f(x), but where x' is inside the domain
11+
"""
12+
function extrap_prep_dim(d, ::Type{Reflect})
13+
xs_d = symbol("xs_", d)
14+
quote
15+
start = lbound(etp.itp, $d)
16+
width = ubound(etp.itp, $d) - start
17+
18+
$xs_d = mod($xs_d - start, 2width) + start
19+
$xs_d > start + width && (xs_d = start + width - $xs_d)
2920
end
3021
end
22+
23+
function extrap_prep_hi(N, ::Type{Reflect})
24+
:(@nexprs $N d->(xs_d > ubound(etp.itp, d) && $(extrap_prep_dim(:d, Periodic))))
25+
end

test/extrapolation/runtests.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ExtrapTests
22

3-
using Base.Test
3+
using Base.Test, DualNumbers
44
using Interpolations
55

66
f(x) = sin((x-3)*2pi/9 - 1)
@@ -39,4 +39,16 @@ k_hi = A[end] - A[end-1]
3939
x_hi = xmax + 5.7
4040
@test_approx_eq etpl[x_hi] A[end]+k_hi*(x_hi-xmax)
4141

42+
43+
xmax, ymax = 8,8
44+
g(x, y) = (x^2 + 3x - 8) * (-2y^2 + y + 1)
45+
46+
itp2g = interpolate(Float64[g(x,y) for x in 1:xmax, y in 1:ymax], Tuple{BSpline(Quadratic(Free)), BSpline(Linear)}, OnGrid)
47+
etp2g = extrapolate(itp2g, Tuple{Linear, Flat})
48+
49+
@test_approx_eq @inferred(getindex(etp2g, -.5, 4)) itp2g[1,4]-1.5*epsilon(g(dual(1,1),4))
50+
@test_approx_eq @inferred(getindex(etp2g, 5, 100)) itp2g[5,ymax]
51+
4252
end
53+
54+
include("type-stability.jl")

0 commit comments

Comments
 (0)