Skip to content

Commit d85ba1d

Browse files
authored
Merge pull request #233 from JuliaMath/teh/fix_232
Clean-ups to extrapolate
2 parents 34a50c7 + 35100ad commit d85ba1d

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ extrap = LinearInterpolation(xs, A, extrapolation_bc = Line())
152152
@test extrap(1 - 0.2) # ≈ f(1) - (f(1.2) - f(1))
153153
@test extrap(5 + 0.2) # ≈ f(5) + (f(5) - f(4.8))
154154
```
155+
You can also use a "fill" value, which gets returned whenever you ask for out-of-range values:
156+
157+
```julia
158+
extrap = LinearInterpolation(xs, A, extrapolation_bc = NaN)
159+
@test isnan(extrap(5.2))
160+
```
161+
155162
Irregular grids are supported as well; note that presently only `LinearInterpolation` supports irregular grids.
156163
```julia
157164
xs = [x^2 for x = 1:0.2:5]
@@ -303,7 +310,18 @@ plot!(xs, ys, label="spline")
303310

304311
## Extrapolation
305312

306-
The call to `extrapolate` defines what happens if you try to index into the interpolation object with coordinates outside of `[1, size(data,d)]` in any dimension `d`. The implemented boundary conditions are `Throw`, `Flat`, `Linear`, `Periodic` and `Reflect`, with more options planned. `Periodic` and `Reflect` require that there is a method of `Base.mod` that can handle the indices used.
313+
The call to `extrapolate` defines what happens if you try to index into the interpolation object with coordinates outside of its
314+
bounds in any dimension. The implemented boundary conditions are `Throw`, `Flat`, `Linear`, `Periodic` and `Reflect`,
315+
or you can pass a constant to be used as a "fill" value returned for any out-of-bounds evaluation.
316+
`Periodic` and `Reflect` require that there is a method of `Base.mod` that can handle the indices used.
317+
318+
Examples:
319+
320+
```
321+
itp = interpolate(1:7, BSpline(Linear()))
322+
etpf = extrapolate(itp, Flat()) # gives 1 on the left edge and 7 on the right edge
323+
etp0 = extrapolate(itp, 0) # gives 0 everywhere outside [1,7]
324+
```
307325

308326
## Performance shootout
309327

src/extrapolation/filled.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ function FilledExtrapolation(itp::AbstractInterpolation{T,N,IT}, fillvalue) wher
88
FilledExtrapolation{Te,N,typeof(itp),IT,typeof(fillvalue)}(itp, fillvalue)
99
end
1010

11+
@noinline FilledExtrapolation(itp::AbstractInterpolation{T,N,IT}, ::Type{F}) where {T,N,IT,F} =
12+
throw(ArgumentError("cannot create a filled extrapolation with a type $F, use a value of this type instead (e.g., $F(0))"))
13+
@noinline FilledExtrapolation(itp::AbstractInterpolation{T,N,IT}, ::Type{F}) where {T,N,IT,F<:BoundaryCondition} =
14+
throw(ArgumentError("cannot create a filled extrapolation with a type $F, use a value of this type instead (e.g., $F())"))
15+
1116
Base.parent(A::FilledExtrapolation) = A.itp
1217
etpflag(A::FilledExtrapolation) = A.fillvalue
1318
itpflag(A::FilledExtrapolation) = itpflag(A.itp)
@@ -21,8 +26,7 @@ extrapolate(itp::AbstractInterpolation{T,N,IT}, fillvalue) where {T,N,IT} = Fill
2126
itp = parent(etp)
2227
Tret = typeof(prod(x) * zero(T))
2328
if checkbounds(Bool, itp, x...)
24-
wis = weightedindexes((value_weights,), itpinfo(itp)..., x)
25-
convert(Tret, itp.coefs[wis...])
29+
@inbounds itp(x...)
2630
else
2731
convert(Tret, etp.fillvalue)
2832
end

test/extrapolation/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ using Test
9191
@test itpe(10.1, 1) 10.1
9292
@test_throws BoundsError itpe(9.9, 0)
9393

94+
# Issue #232
95+
targeterr = ArgumentError("cannot create a filled extrapolation with a type Line, use a value of this type instead (e.g., Line())")
96+
@test_throws targeterr extrapolate(itp, Line)
97+
9498
include("type-stability.jl")
9599
include("non1.jl")
96100
end

test/readme-examples.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,26 @@ using Interpolations, Test
5151
itp = interpolate(knots, A, Gridded(Linear()))
5252
@test itp(4,1.2) A[2,6] atol=.1 # approximately A[2,6]
5353

54+
## extrapolate
55+
itp = interpolate(1:7, BSpline(Linear()))
56+
etpf = extrapolate(itp, Flat())
57+
@test etpf(0) == 1
58+
@test etpf(1) == 1
59+
@test etpf(7) == 7
60+
@test etpf(7.8) == 7
61+
etp0 = extrapolate(itp, 0)
62+
@test etp0(0) === 0.0
63+
@test etp0(1) === 1.0
64+
@test etp0(7) === 7.0
65+
@test etp0(7.8) === 0.0
66+
67+
f(x) = log(x)
68+
xs = 1:0.2:5
69+
A = [f(x) for x in xs]
70+
extrap = LinearInterpolation(xs, A, extrapolation_bc = Line())
71+
@test extrap(1 - 0.2) f(1) - (f(1.2) - f(1))
72+
@test extrap(5 + 0.2) f(5) + (f(5) - f(4.8))
73+
extrap = LinearInterpolation(xs, A, extrapolation_bc = NaN)
74+
@test isnan(extrap(5.2))
75+
5476
end

0 commit comments

Comments
 (0)