Skip to content

Commit b160f08

Browse files
committed
Switch to testsets
1 parent e6a0f7d commit b160f08

17 files changed

+814
-825
lines changed

src/rewrite.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct MyInterp{T,N,A<:AbstractArray{T,N}}
2+
data::A
3+
end
4+
5+
@inline (itp::MyInterp{T,N})(i::Vararg{<:Number,N}) where {T,N} = expand(itp, i)
6+
7+
@inline function expand(itp::MyInterp, ipre::Tuple{Vararg{Number,L}}, ipost::Vararg{Integer,M}) where {L,M} # force specialization
8+
ifront, ilast = Base.front(ipre), ipre[end]
9+
im, ip = floor(ilast), ceil(ilast)
10+
return (ip - ilast)*expand(itp, ifront, unsafe_trunc(Int, im), ipost...) +
11+
(ilast - im)*expand(itp, ifront, unsafe_trunc(Int, ip), ipost...)
12+
end
13+
14+
@inline expand(itp::MyInterp, ::Tuple{}, ipost::Vararg{Integer,N}) where N =
15+
@inbounds itp.data[CartesianIndex(ipost)]

test/InterpolationTestUtils.jl

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
module InterpolationTestUtils
2+
3+
using Test, Interpolations
4+
using Interpolations: degree, itpflag, bounds, lbounds, ubounds
5+
using Interpolations: substitute
6+
7+
export check_axes, check_inbounds_values, check_oob, can_eval_near_boundaries
8+
export MyPair
9+
10+
const failstore = Ref{Any}(nothing) # stash the inputs to failing tests here
11+
12+
## Property accessors
13+
coefs(itp) = itp.coefs
14+
15+
boundaryconditions(itp::AbstractInterpolation) = boundaryconditions(itpflag(itp))
16+
boundaryconditions(bs::BSpline) = degree(bs)
17+
boundaryconditions(ni::NoInterp) = ni
18+
19+
ndaccessor(x, d) = x
20+
ndaccessor(x::Tuple, d) = x[d]
21+
22+
haspadding(itp) = haspadding(boundaryconditions(itp))
23+
haspadding(::Union{Constant,Linear,NoInterp}) = false
24+
haspadding(::Quadratic{BC}) where BC = haspadding(BC())
25+
haspadding(::Cubic{BC}) where BC = haspadding(BC())
26+
haspadding(::BC) where BC<:Interpolations.BoundaryCondition = !(BC <: Union{Periodic,InPlace,InPlaceQ})
27+
haspadding(bcs::Tuple) = map(haspadding, bcs)
28+
haspadding(::NoInterp) = false
29+
30+
getindexib(itp, i...) = @inbounds itp[i...]
31+
callib(itp, i...) = @inbounds itp(i...)
32+
33+
(r1::AbstractRange, r2::AbstractRange) = first(r2) < first(r1) < last(r2) && first(r2) < last(r1) < last(r2)
34+
35+
function check_axes(itp, A, isinplace=false)
36+
@test ndims(itp) == ndims(A)
37+
axsi, axsA = @inferred(axes(itp)), axes(A)
38+
szi, szA = @inferred(size(itp)), size(A)
39+
haspad = haspadding(itp)
40+
for d = 1:ndims(A)
41+
if isinplace && ndaccessor(haspad, d)
42+
@test axsi[d] != axsA[d] && axsi[d] axsA[d]
43+
@test szi[d] < szA[d]
44+
else
45+
@test axsi[d] == axsA[d]
46+
@test szi[d] == szA[d]
47+
end
48+
end
49+
nothing
50+
end
51+
52+
function check_inbounds_values(itp, A)
53+
for i in eachindex(itp)
54+
@test A[i] itp[i] == itp[Tuple(i)...] itp(i) itp(float.(Tuple(i))...)
55+
end
56+
if ndims(itp) == 1
57+
for i in eachindex(itp)
58+
@test itp[i,1] A[i] # used in the AbstractArray display infrastructure
59+
@test_throws BoundsError itp[i,2]
60+
@test getindexib(itp, i, 2) A[i]
61+
@test callib(itp, i, 2) A[i]
62+
end
63+
end
64+
nothing
65+
end
66+
67+
function check_oob(itp)
68+
widen(r) = first(r)-1:last(r)+1
69+
indsi = axes(itp)
70+
indsci = CartesianIndices(indsi)
71+
for i in CartesianIndices(widen.(indsi))
72+
i indsci && continue
73+
@test_throws BoundsError itp[i]
74+
end
75+
nothing
76+
end
77+
78+
function can_eval_near_boundaries(itp::AbstractInterpolation{T,1}) where T
79+
l, u = bounds(itp, 1)
80+
@test isfinite(itp(l+0.1))
81+
@test isfinite(itp(u-0.1))
82+
@test_throws BoundsError itp(l-0.1)
83+
@test_throws BoundsError itp(u+0.1)
84+
end
85+
86+
function can_eval_near_boundaries(itp::AbstractInterpolation)
87+
l, u = lbounds(itp), ubounds(itp)
88+
for d = 1:ndims(itp)
89+
nearl = substitute(l, d, l[d]+0.1)
90+
# @show summary(itp) nearl
91+
@test isfinite(itp(nearl...))
92+
outl = substitute(l, d, l[d]-0.1)
93+
@test_throws BoundsError itp(outl...)
94+
nearu = substitute(u, d, u[d]-0.1)
95+
# @show nearu
96+
@test isfinite(itp(nearu...))
97+
outu = substitute(u, d, u[d]+0.1)
98+
@test_throws BoundsError itp(outu...)
99+
end
100+
end
101+
102+
# Used for multi-valued tests
103+
import Base: +, -, *, /,
104+
105+
struct MyPair{T}
106+
first::T
107+
second::T
108+
end
109+
110+
# Here's the interface your type must define
111+
(+)(p1::MyPair, p2::MyPair) = MyPair(p1.first+p2.first, p1.second+p2.second)
112+
(-)(p1::MyPair, p2::MyPair) = MyPair(p1.first-p2.first, p1.second-p2.second)
113+
(*)(n::Number, p::MyPair) = MyPair(n*p.first, n*p.second)
114+
(*)(p::MyPair, n::Number) = n*p
115+
(/)(p::MyPair, n::Number) = MyPair(p.first/n, p.second/n)
116+
Base.zero(::Type{MyPair{T}}) where {T} = MyPair(zero(T),zero(T))
117+
Base.promote_rule(::Type{MyPair{T1}}, ::Type{T2}) where {T1,T2<:Number} = MyPair{promote_type(T1,T2)}
118+
(p1::MyPair, p2::MyPair) = (p1.first p2.first) & (p1.second p2.second)
119+
120+
end

test/b-splines/constant.jl

Lines changed: 42 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,48 @@
1-
module ConstantTests
2-
3-
using Interpolations
4-
using Test
5-
6-
# Instantiation
7-
N1 = 10
8-
A1 = rand(Float64, N1) * 100
9-
A2 = rand(Float64, N1, N1) * 100
10-
A3 = rand(Float64, N1, N1, N1) * 100
11-
12-
getindexib(itp, i...) = @inbounds itp[i...]
13-
callib(itp, i...) = @inbounds itp(i...)
14-
15-
for (constructor, copier) in ((interpolate, x->x), (interpolate!, copy))
16-
itp1c = @inferred(constructor(copier(A1), BSpline(Constant()), OnCell()))
17-
itp1g = @inferred(constructor(copier(A1), BSpline(Constant()), OnGrid()))
18-
itp2c = @inferred(constructor(copier(A2), BSpline(Constant()), OnCell()))
19-
itp2g = @inferred(constructor(copier(A2), BSpline(Constant()), OnGrid()))
20-
itp3c = @inferred(constructor(copier(A3), BSpline(Constant()), OnCell()))
21-
itp3g = @inferred(constructor(copier(A3), BSpline(Constant()), OnGrid()))
22-
23-
@test parent(itp1c) === itp1c.coefs
1+
@testset "Constant" begin
2+
# Instantiation
3+
N1 = 10
4+
A1 = rand(Float64, N1) * 100
5+
A2 = rand(Float64, N1, N1) * 100
6+
A3 = rand(Float64, N1, N1, N1) * 100
7+
8+
for (constructor, copier) in ((interpolate, x->x), (interpolate!, copy))
9+
isinplace = constructor == interpolate!
10+
itp1c = @inferred(constructor(copier(A1), BSpline(Constant()), OnCell()))
11+
itp1g = @inferred(constructor(copier(A1), BSpline(Constant()), OnGrid()))
12+
itp2c = @inferred(constructor(copier(A2), BSpline(Constant()), OnCell()))
13+
itp2g = @inferred(constructor(copier(A2), BSpline(Constant()), OnGrid()))
14+
itp3c = @inferred(constructor(copier(A3), BSpline(Constant()), OnCell()))
15+
itp3g = @inferred(constructor(copier(A3), BSpline(Constant()), OnGrid()))
16+
17+
@test parent(itp1c) === itp1c.coefs
18+
@test Interpolations.lbounds(itp1c) == (0.5,)
19+
@test Interpolations.lbounds(itp1g) == (1,)
20+
@test Interpolations.ubounds(itp1c) == (N1 + 0.5,)
21+
@test Interpolations.ubounds(itp1g) == (N1,)
22+
23+
# Evaluation on provided data points
24+
for (itp, A) in ((itp1c, A1), (itp1g, A1), (itp2c, A2), (itp2g, A2), (itp3c, A3), (itp3g, A3))
25+
check_axes(itp, A, isinplace)
26+
check_inbounds_values(itp, A)
27+
check_oob(itp)
28+
can_eval_near_boundaries(itp)
29+
end
2430

25-
# Evaluation on provided data points
26-
for (itp, A) in ((itp1c, A1), (itp1g, A1), (itp2c, A2), (itp2g, A2), (itp3c, A3), (itp3g, A3))
27-
for i in eachindex(itp)
28-
@test A[i] == itp[i] == itp[Tuple(i)...] == itp(i) == itp(float.(Tuple(i))...)
31+
# Evaluation between data points (tests constancy)
32+
for i in 2:N1-1
33+
@test A1[i] == itp1c(i+.3) == itp1g(i+.3) == itp1c(i-.3) == itp1g(i-.3)
2934
end
30-
@test @inferred(axes(itp)) == axes(A)
31-
@test @inferred(size(itp)) == size(A)
32-
# @test @inferred(axes(itp)) == (contructor == interpolate ? (1:N1) : (2:N1-1))
33-
# @test @inferred(size(itp)) == (contructor == interpolate ? N1 : N1-2)
34-
end
35-
for itp in (itp1c, itp1g)
36-
for i = 1:N1
37-
@test itp[i,1] == A1[i] # used in the AbstractArray display infrastructure
38-
@test_throws BoundsError itp[i,2]
39-
@test_broken getindexib(itp, i, 2) == A1[i]
40-
@test_broken callib(itp, i, 2) == A1[i]
35+
# 2D
36+
for i in 2:N1-1, j in 2:N1-1
37+
@test A2[i,j] == itp2c(i+.4,j-.3) == itp2g(i+.4,j-.3)
38+
end
39+
# 3D
40+
for i in 2:N1-1, j in 2:N1-1, k in 2:N1-1
41+
@test A3[i,j,k] == itp3c(i+.4,j-.3,k+.1) == itp3g(i+.4,j-.3,k+.2)
4142
end
42-
end
4343

44-
# Evaluation between data points (tests constancy)
45-
for i in 2:N1-1
46-
@test A1[i] == itp1c(i+.3) == itp1g(i+.3) == itp1c(i-.3) == itp1g(i-.3)
47-
end
48-
# 2D
49-
for i in 2:N1-1, j in 2:N1-1
50-
@test A2[i,j] == itp2c(i+.4,j-.3) == itp2g(i+.4,j-.3)
51-
end
52-
# 3D
53-
for i in 2:N1-1, j in 2:N1-1, k in 2:N1-1
54-
@test A3[i,j,k] == itp3c(i+.4,j-.3,k+.1) == itp3g(i+.4,j-.3,k+.2)
44+
# Edge behavior
45+
@test A1[1] == itp1c(.7)
46+
@test A1[N1] == itp1c(N1+.3)
5547
end
56-
57-
# Edge behavior
58-
@test A1[1] == itp1c(.7)
59-
@test A1[N1] == itp1c(N1+.3)
60-
end
61-
6248
end

0 commit comments

Comments
 (0)