Skip to content

Commit ec35013

Browse files
authored
Merge pull request #411 from eirikbrandsaas/patch-1
Convenience constructors for constant (nearest-neighbor) interpolation
2 parents 85a06e0 + 3991bdc commit ec35013

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

docs/src/convenience-construction.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11

22
## Convenience notation
33

4-
For linear and cubic spline interpolations, `LinearInterpolation` and `CubicSplineInterpolation`
5-
can be used to create interpolating and extrapolating objects handily:
4+
For constant, linear, and cubic spline interpolations, `ConstantInterpolation`, `LinearInterpolation`, and `CubicSplineInterpolation`
5+
can be used to create interpolating and extrapolating objects handily.
6+
7+
### Motivating Example
8+
By using the convenience constructor one can simplify expressions. For example, the creation of an interpolation object
9+
```julia
10+
extrap_full = extrapolate(scale(interpolate(A, BSpline(Linear())), xs), Line())
11+
```
12+
can be written as the more readable
13+
```julia
14+
extrap = LinearInterpolation(xs, A, extrapolation_bc = Line())
15+
```
16+
by using the convenience constructor.
17+
18+
### Usage
19+
620
```julia
721
f(x) = log(x)
822
xs = 1:0.2:5
@@ -55,7 +69,7 @@ extrap = LinearInterpolation(xs, A, extrapolation_bc = NaN)
5569
@test isnan(extrap(5.2))
5670
```
5771

58-
Irregular grids are supported as well; note that presently only `LinearInterpolation` supports irregular grids.
72+
Irregular grids are supported as well; note that presently only `ConstantInterpolation` and `LinearInterpolation` supports irregular grids.
5973
```julia
6074
xs = [x^2 for x = 1:0.2:5]
6175
A = [f(x) for x in xs]

src/Interpolations.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export
2323
InPlaceQ,
2424
Throw,
2525

26+
ConstantInterpolation,
2627
LinearInterpolation,
2728
CubicSplineInterpolation,
2829

src/convenience-constructors.jl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
# convenience copnstructors for linear / cubic spline interpolations
1+
# convenience copnstructors for constant / linear / cubic spline interpolations
22
# 1D version
3+
ConstantInterpolation(range::AbstractRange, vs::AbstractVector; extrapolation_bc = Throw()) =
4+
extrapolate(scale(interpolate(vs, BSpline(Constant())), range), extrapolation_bc)
5+
ConstantInterpolation(range::AbstractVector, vs::AbstractVector; extrapolation_bc = Throw()) =
6+
extrapolate(interpolate((range, ), vs, Gridded(Constant())), extrapolation_bc)
37
LinearInterpolation(range::AbstractRange, vs::AbstractVector; extrapolation_bc = Throw()) =
48
extrapolate(scale(interpolate(vs, BSpline(Linear())), range), extrapolation_bc)
59
LinearInterpolation(range::AbstractVector, vs::AbstractVector; extrapolation_bc = Throw()) =
@@ -9,6 +13,12 @@ CubicSplineInterpolation(range::AbstractRange, vs::AbstractVector;
913
extrapolate(scale(interpolate(vs, BSpline(Cubic(bc))), range), extrapolation_bc)
1014

1115
# multivariate versions
16+
ConstantInterpolation(ranges::NTuple{N,AbstractRange}, vs::AbstractArray{T,N};
17+
extrapolation_bc = Throw()) where {N,T} =
18+
extrapolate(scale(interpolate(vs, BSpline(Constant())), ranges...), extrapolation_bc)
19+
ConstantInterpolation(ranges::NTuple{N,AbstractVector}, vs::AbstractArray{T,N};
20+
extrapolation_bc = Throw()) where {N,T} =
21+
extrapolate(interpolate(ranges, vs, Gridded(Constant())), extrapolation_bc)
1222
LinearInterpolation(ranges::NTuple{N,AbstractRange}, vs::AbstractArray{T,N};
1323
extrapolation_bc = Throw()) where {N,T} =
1424
extrapolate(scale(interpolate(vs, BSpline(Linear())), ranges...), extrapolation_bc)
@@ -28,6 +38,15 @@ where `scheme` is either `BSpline(Linear())` or `Gridded(Linear())` depending on
2838
"""
2939
LinearInterpolation
3040

41+
"""
42+
etp = ConstantInterpolation(knots, A; extrapolation_bc=Throw())
43+
44+
A shorthand for `extrapolate(interpolate(knots, A, scheme), extrapolation_bc)`,
45+
where `scheme` is either `BSpline(Constant())` or `Gridded(Constant())` depending on whether
46+
`knots` are ranges or vectors.
47+
"""
48+
ConstantInterpolation
49+
3150
"""
3251
etp = CubicSplineInterpolation(knots, A; bc=Line(OnGrid()), extrapolation_bc=Throw())
3352

test/convenience-constructors.jl

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ YLEN = convert(Integer, floor((YMAX - YMIN)/ΔY) + 1)
3131
@test_throws BoundsError interp(XMIN - ΔX / 2)
3232
@test_throws BoundsError interp(XMAX + ΔX / 2)
3333
end
34+
35+
@testset "1d-regular-grids-constant" begin
36+
xs = XMIN:ΔX:XMAX
37+
f(x) = log(x)
38+
A = [f(x) for x in xs]
39+
interp = ConstantInterpolation(xs, A) # using convenience constructor
40+
interp_full = extrapolate(scale(interpolate(A, BSpline(Constant())), xs), Throw()) # using full constructor
41+
42+
@test typeof(interp) == typeof(interp_full)
43+
@test interp(XMIN) f(XMIN)
44+
@test interp(XMAX) f(XMAX)
45+
@test interp(XMIN + ΔX) f(XMIN + ΔX)
46+
@test interp(XMAX - ΔX) f(XMAX - ΔX)
47+
@test interp(XMIN + ΔX / 2) f(XMIN + ΔX / 2) atol=.1
48+
@test_throws BoundsError interp(XMIN - ΔX / 2)
49+
@test_throws BoundsError interp(XMAX + ΔX / 2)
50+
end
3451

3552
@testset "1d-regular-grids-cubic" begin
3653
xs = XMIN:ΔX:XMAX
@@ -66,6 +83,24 @@ YLEN = convert(Integer, floor((YMAX - YMIN)/ΔY) + 1)
6683
@test_throws BoundsError interp(xmin - ΔX / 2)
6784
@test_throws BoundsError interp(xmax + ΔX / 2)
6885
end
86+
87+
@testset "1d-irregular-grids-constant" begin
88+
xs = [x^2 for x in XMIN:ΔX:XMAX]
89+
xmin = xs[1]
90+
xmax = xs[XLEN]
91+
f(x) = log(x)
92+
A = [f(x) for x in xs]
93+
interp = ConstantInterpolation(xs, A)
94+
interp_full = extrapolate(interpolate((xs, ), A, Gridded(Constant())), Throw())
95+
96+
@test typeof(interp) == typeof(interp_full)
97+
@test interp(xmin) f(xmin)
98+
@test interp(xmax) f(xmax)
99+
@test interp(xs[2]) f(xs[2])
100+
@test interp(xmin + ΔX / 2) f(xmin + ΔX / 2) atol=.1
101+
@test_throws BoundsError interp(xmin - ΔX / 2)
102+
@test_throws BoundsError interp(xmax + ΔX / 2)
103+
end
69104

70105
@testset "1d-handling-extrapolation" begin
71106
xs = XMIN:ΔX:XMAX
@@ -108,6 +143,29 @@ end
108143
@test_throws BoundsError interp(XMIN + ΔX / 2,YMIN - ΔY / 2)
109144
@test_throws BoundsError interp(XMAX + ΔX / 2,YMAX + ΔY / 2)
110145
end
146+
147+
@testset "2d-regular-grids-constant" begin
148+
xs = XMIN:ΔX:XMAX
149+
ys = YMIN:ΔY:YMAX
150+
f(x, y) = log(x+y)
151+
A = [f(x,y) for x in xs, y in ys]
152+
interp = ConstantInterpolation((xs, ys), A)
153+
interp_full = extrapolate(scale(interpolate(A, BSpline(Constant())), xs, ys), Throw())
154+
155+
@test typeof(interp) == typeof(interp_full)
156+
@test interp(XMIN,YMIN) f(XMIN,YMIN)
157+
@test interp(XMIN,YMAX) f(XMIN,YMAX)
158+
@test interp(XMAX,YMIN) f(XMAX,YMIN)
159+
@test interp(XMAX,YMAX) f(XMAX,YMAX)
160+
@test interp(XMIN + ΔX,YMIN) f(XMIN + ΔX,YMIN)
161+
@test interp(XMIN,YMIN + ΔY) f(XMIN,YMIN + ΔY)
162+
@test interp(XMIN + ΔX,YMIN + ΔY) f(XMIN + ΔX,YMIN + ΔY)
163+
@test interp(XMIN + ΔX / 2,YMIN + ΔY / 2) f(XMIN + ΔX / 2,YMIN + ΔY / 2) atol=.1
164+
@test_throws BoundsError interp(XMIN - ΔX / 2,YMIN - ΔY / 2)
165+
@test_throws BoundsError interp(XMIN - ΔX / 2,YMIN + ΔY / 2)
166+
@test_throws BoundsError interp(XMIN + ΔX / 2,YMIN - ΔY / 2)
167+
@test_throws BoundsError interp(XMAX + ΔX / 2,YMAX + ΔY / 2)
168+
end
111169

112170
@testset "2d-regular-grids-cubic" begin
113171
xs = XMIN:ΔX:XMAX
@@ -158,6 +216,33 @@ end
158216
@test_throws BoundsError interp(xmin + ΔX / 2,ymin - ΔY / 2)
159217
@test_throws BoundsError interp(xmax + ΔX / 2,ymax + ΔY / 2)
160218
end
219+
220+
@testset "2d-irregular-grids-constant" begin
221+
xs = [x^2 for x in XMIN:ΔX:XMAX]
222+
ys = [y^2 for y in YMIN:ΔY:YMAX]
223+
xmin = xs[1]
224+
xmax = xs[XLEN]
225+
ymin = ys[1]
226+
ymax = ys[YLEN]
227+
f(x, y) = log(x+y)
228+
A = [f(x,y) for x in xs, y in ys]
229+
interp = ConstantInterpolation((xs, ys), A)
230+
interp_full = extrapolate(interpolate((xs, ys), A, Gridded(Constant())), Throw())
231+
232+
@test typeof(interp) == typeof(interp_full)
233+
@test interp(xmin,ymin) f(xmin,ymin)
234+
@test interp(xmin,ymax) f(xmin,ymax)
235+
@test interp(xmax,ymin) f(xmax,ymin)
236+
@test interp(xmax,ymax) f(xmax,ymax)
237+
@test interp(xs[2],ymin) f(xs[2],ymin)
238+
@test interp(xmin,ys[2]) f(xmin,ys[2])
239+
@test interp(xs[2],ys[2]) f(xs[2],ys[2])
240+
@test interp(xmin + ΔX / 2,ymin + ΔY / 2) f(xmin + ΔX / 2,ymin + ΔY / 2) atol=.1
241+
@test_throws BoundsError interp(xmin - ΔX / 2,ymin - ΔY / 2)
242+
@test_throws BoundsError interp(xmin - ΔX / 2,ymin + ΔY / 2)
243+
@test_throws BoundsError interp(xmin + ΔX / 2,ymin - ΔY / 2)
244+
@test_throws BoundsError interp(xmax + ΔX / 2,ymax + ΔY / 2)
245+
end
161246

162247
@testset "2d-handling-extrapolation" begin
163248
xs = XMIN:ΔX:XMAX

0 commit comments

Comments
 (0)