Skip to content

Commit

Permalink
test: refactor tests into better testsets and also test extrapolation
Browse files Browse the repository at this point in the history
  • Loading branch information
sathvikbhagavan committed Oct 16, 2023
1 parent 2649c4b commit 41a061f
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 204 deletions.
298 changes: 136 additions & 162 deletions test/derivative_tests.jl
Original file line number Diff line number Diff line change
@@ -1,185 +1,159 @@
using DataInterpolations, Test
using FiniteDifferences
using DataInterpolations: derivative
# using Symbolics

function test_derivatives(func, tspan, name::String)
trange = range(minimum(tspan) - 5.0, maximum(tspan) + 5.0, length = 32)
function test_derivatives(method, u, t, args...; name::String)
func = method(u, t, args...)
trange = range(minimum(t) - 5.0, maximum(t) + 5.0, length = 32)
@testset "$name" begin
for t in trange
cdiff = central_fdm(5, 1; geom = true)(_t -> func(_t), t)
adiff = derivative(func, t)
@test isapprox(cdiff, adiff, atol = 1e-8)
end
end
func = method(u, t, args...; extrapolate = false)
@test_throws ErrorException derivative(func, t[1] - 1.0)
@test_throws ErrorException derivative(func, t[end] + 1.0)
end

# Linear Interpolation
u = 2.0collect(1:10)
t = 1.0collect(1:10)
A = LinearInterpolation(u, t)

test_derivatives(A, t, "Linear Interpolation (Vector)")

u = vcat(2.0collect(1:10)', 3.0collect(1:10)')
A = LinearInterpolation(u, t)

test_derivatives(A, t, "Linear Interpolation (Matrix)")

# Quadratic Interpolation
u = [1.0, 4.0, 9.0, 16.0]
t = [1.0, 2.0, 3.0, 4.0]
A = QuadraticInterpolation(u, t)

test_derivatives(A, t, "Quadratic Interpolation (Vector)")

Ab = QuadraticInterpolation(u, t, :Backward)

test_derivatives(Ab, t, "Quadratic Interpolation (Vector), backward")

u = [1.0 4.0 9.0 16.0; 1.0 4.0 9.0 16.0]
A = QuadraticInterpolation(u, t)

test_derivatives(A, t, "Quadratic Interpolation (Matrix)")
@testset "Linear Interpolation" begin
u = 2.0collect(1:10)
t = 1.0collect(1:10)
test_derivatives(LinearInterpolation, u, t; name = "Linear Interpolation (Vector)")
u = vcat(2.0collect(1:10)', 3.0collect(1:10)')
A = LinearInterpolation(u, t)
test_derivatives(LinearInterpolation, u, t; name = "Linear Interpolation (Matrix)")
end

@testset "Backward Quadratic Interpolation" begin
u = [0.5, 0.0, 0.5, 0.0]
@testset "Quadratic Interpolation" begin
u = [1.0, 4.0, 9.0, 16.0]
t = [1.0, 2.0, 3.0, 4.0]
A_f = QuadraticInterpolation(u, t)
A_b = QuadraticInterpolation(u, t, :Backward)
@test derivative(A_f, 1.5) -0.5
@test derivative(A_b, 1.5) -0.5
@test derivative(A_f, 2.25) 0.75
@test derivative(A_b, 2.25) 0.25
@test derivative(A_f, 2.75) 0.25
@test derivative(A_b, 2.75) 0.75
@test derivative(A_f, 3.5) -0.5
@test derivative(A_b, 3.5) -0.5
test_derivatives(QuadraticInterpolation,
u,
t;
name = "Quadratic Interpolation (Vector)")
test_derivatives(QuadraticInterpolation,
u,
t,
:Backward;
name = "Quadratic Interpolation (Vector), backward")
u = [1.0 4.0 9.0 16.0; 1.0 4.0 9.0 16.0]
test_derivatives(QuadraticInterpolation,
u,
t;
name = "Quadratic Interpolation (Matrix)")
end

# Lagrange Interpolation
u = [1.0, 4.0, 9.0]
t = [1.0, 2.0, 3.0]
A = LagrangeInterpolation(u, t)

test_derivatives(A, t, "Lagrange Interpolation (Vector)")

# Lagrange Interpolation
u = [1.0 4.0 9.0; 1.0 2.0 3.0]
t = [1.0, 2.0, 3.0]
A = LagrangeInterpolation(u, t)

test_derivatives(A, t, "Lagrange Interpolation (Matrix)")

# Lagrange Interpolation
u = [[1.0, 4.0, 9.0], [3.0, 7.0, 4.0], [5.0, 4.0, 1.0]]
t = [1.0, 2.0, 3.0]
A = LagrangeInterpolation(u, t)

test_derivatives(A, t, "Lagrange Interpolation (Vector of Vectors)")

# Lagrange Interpolation
u = [[3.0 1.0 4.0; 1.0 5.0 9.0], [2.0 6.0 5.0; 3.0 5.0 8.0], [9.0 7.0 9.0; 3.0 2.0 3.0]]
t = [1.0, 2.0, 3.0]
A = LagrangeInterpolation(u, t)

test_derivatives(A, t, "Lagrange Interpolation (Vector of Matrices)")

# Akima Interpolation
u = [0.0, 2.0, 1.0, 3.0, 2.0, 6.0, 5.5, 5.5, 2.7, 5.1, 3.0]
t = collect(0.0:10.0)
A = AkimaInterpolation(u, t)

test_derivatives(A, t, "Akima Interpolation")

@testset "Akima smooth derivative at end points" begin
@test derivative(A, t[1]) derivative(A, nextfloat(t[1]))
@test derivative(A, t[end]) derivative(A, prevfloat(t[end]))
@testset "Lagrange Interpolation" begin
u = [1.0, 4.0, 9.0]
t = [1.0, 2.0, 3.0]
test_derivatives(LagrangeInterpolation, u, t; name = "Lagrange Interpolation (Vector)")
u = [1.0 4.0 9.0; 1.0 2.0 3.0]
test_derivatives(LagrangeInterpolation, u, t; name = "Lagrange Interpolation (Matrix)")
u = [[1.0, 4.0, 9.0], [3.0, 7.0, 4.0], [5.0, 4.0, 1.0]]
test_derivatives(LagrangeInterpolation,
u,
t;
name = "Lagrange Interpolation (Vector of Vectors)")
u = [[3.0 1.0 4.0; 1.0 5.0 9.0], [2.0 6.0 5.0; 3.0 5.0 8.0], [9.0 7.0 9.0; 3.0 2.0 3.0]]
test_derivatives(LagrangeInterpolation,
u,
t;
name = "Lagrange Interpolation (Vector of Matrices)")
end

# QuadraticSpline Interpolation
u = [0.0, 1.0, 3.0]
t = [-1.0, 0.0, 1.0]

A = QuadraticSpline(u, t)

test_derivatives(A, t, "Quadratic Interpolation (Vector)")

# QuadraticSpline Interpolation
u = [[1.0, 2.0, 9.0], [3.0, 7.0, 5.0], [5.0, 4.0, 1.0]]
t = [-1.0, 0.0, 1.0]

A = QuadraticSpline(u, t)

test_derivatives(A, t, "Quadratic Interpolation (Vector of Vectors)")

# QuadraticSpline Interpolation
u = [[1.0 4.0 9.0; 5.0 9.0 2.0], [3.0 7.0 4.0; 6.0 5.0 3.0], [5.0 4.0 1.0; 2.0 3.0 8.0]]
t = [-1.0, 0.0, 1.0]

A = QuadraticSpline(u, t)

test_derivatives(A, t, "Quadratic Interpolation (Vector of Matrices)")

# CubicSpline Interpolation
u = [0.0, 1.0, 3.0]
t = [-1.0, 0.0, 1.0]

A = CubicSpline(u, t)

test_derivatives(A, t, "Cubic Spline Interpolation (Vector)")

# CubicSpline Interpolation
u = [[1.0, 2.0, 9.0], [3.0, 7.0, 5.0], [5.0, 4.0, 1.0]]
t = [-1.0, 0.0, 1.0]

A = CubicSpline(u, t)

test_derivatives(A, t, "Cubic Spline Interpolation (Vector of Vectors)")

# CubicSpline Interpolation
u = [[1.0 4.0 9.0; 5.0 9.0 2.0], [3.0 7.0 4.0; 6.0 5.0 3.0], [5.0 4.0 1.0; 2.0 3.0 8.0]]
t = [-1.0, 0.0, 1.0]

A = CubicSpline(u, t)

test_derivatives(A, t, "Cubic Spline Interpolation (Vector of Matrices)")

# BSpline Interpolation and Approximation
t = [0, 62.25, 109.66, 162.66, 205.8, 252.3]
u = [14.7, 11.51, 10.41, 14.95, 12.24, 11.22]

A = BSplineInterpolation(u, t, 2, :Uniform, :Uniform)

test_derivatives(A, t, "BSpline Interpolation (Uniform, Uniform)")

A = BSplineInterpolation(u, t, 2, :ArcLen, :Average)

test_derivatives(A, t, "BSpline Interpolation (Arclen, Average)")

A = BSplineApprox(u, t, 3, 4, :Uniform, :Uniform)

test_derivatives(A, t, "BSpline Approx (Uniform, Uniform)")
@testset "Akima Interpolation" begin
u = [0.0, 2.0, 1.0, 3.0, 2.0, 6.0, 5.5, 5.5, 2.7, 5.1, 3.0]
t = collect(0.0:10.0)
test_derivatives(AkimaInterpolation, u, t; name = "Akima Interpolation")
@testset "Akima smooth derivative at end points" begin
A = AkimaInterpolation(u, t)
@test derivative(A, t[1]) derivative(A, nextfloat(t[1]))
@test derivative(A, t[end]) derivative(A, prevfloat(t[end]))
end
end

using Symbolics
@testset "Quadratic Spline" begin
u = [0.0, 1.0, 3.0]
t = [-1.0, 0.0, 1.0]
test_derivatives(QuadraticSpline, u, t; name = "Quadratic Interpolation (Vector)")
u = [[1.0, 2.0, 9.0], [3.0, 7.0, 5.0], [5.0, 4.0, 1.0]]
test_derivatives(QuadraticSpline,
u,
t;
name = "Quadratic Interpolation (Vector of Vectors)")
u = [[1.0 4.0 9.0; 5.0 9.0 2.0], [3.0 7.0 4.0; 6.0 5.0 3.0], [5.0 4.0 1.0; 2.0 3.0 8.0]]
test_derivatives(QuadraticSpline,
u,
t;
name = "Quadratic Interpolation (Vector of Matrices)")
end

u = [0.0, 1.5, 0.0]
t = [0.0, 0.5, 1.0]
A = QuadraticSpline(u, t)
@variables τ, ω(τ)
D = Symbolics.Differential(τ)
expr = A(ω)
@test isequal(Symbolics.derivative(expr, τ), D(ω) * DataInterpolations.derivative(A, ω))
@testset "Cubic Spline" begin
u = [0.0, 1.0, 3.0]
t = [-1.0, 0.0, 1.0]
test_derivatives(CubicSpline, u, t; name = "Cubic Spline Interpolation (Vector)")
u = [[1.0, 2.0, 9.0], [3.0, 7.0, 5.0], [5.0, 4.0, 1.0]]
test_derivatives(CubicSpline,
u,
t;
name = "Cubic Spline Interpolation (Vector of Vectors)")
u = [[1.0 4.0 9.0; 5.0 9.0 2.0], [3.0 7.0 4.0; 6.0 5.0 3.0], [5.0 4.0 1.0; 2.0 3.0 8.0]]
test_derivatives(CubicSpline,
u,
t;
name = "Cubic Spline Interpolation (Vector of Matrices)")
end

derivexpr = expand_derivatives(substitute(D(A(ω)), Dict=> 0.5τ)))
symfunc = Symbolics.build_function(derivexpr, τ; expression = Val{false})
@test symfunc(0.5) == 0.5 * 3
@testset "BSplines" begin
t = [0, 62.25, 109.66, 162.66, 205.8, 252.3]
u = [14.7, 11.51, 10.41, 14.95, 12.24, 11.22]
test_derivatives(BSplineInterpolation,
u,
t,
2,
:Uniform,
:Uniform;
name = "BSpline Interpolation (Uniform, Uniform)")
test_derivatives(BSplineInterpolation,
u,
t,
2,
:ArcLen,
:Average;
name = "BSpline Interpolation (Arclen, Average)")
test_derivatives(BSplineApprox,
u,
t,
3,
4,
:Uniform,
:Uniform;
name = "BSpline Approx (Uniform, Uniform)")
end

u = [0.0, 1.5, 0.0]
t = [0.0, 0.5, 1.0]
@variables τ
D = Symbolics.Differential(τ)
f = LinearInterpolation(u, t)
df = expand_derivatives(D(f(τ)))
symfunc = Symbolics.build_function(df, τ; expression = Val{false})
ts = 0.0:0.1:1.0
@test all(map(ti -> symfunc(ti) == derivative(f, ti), ts))
@testset "Symbolic derivatives" begin
u = [0.0, 1.5, 0.0]
t = [0.0, 0.5, 1.0]
A = QuadraticSpline(u, t)
@variables τ, ω(τ)
D = Symbolics.Differential(τ)
expr = A(ω)
@test isequal(Symbolics.derivative(expr, τ), D(ω) * DataInterpolations.derivative(A, ω))

derivexpr = expand_derivatives(substitute(D(A(ω)), Dict=> 0.5τ)))
symfunc = Symbolics.build_function(derivexpr, τ; expression = Val{false})
@test symfunc(0.5) == 0.5 * 3

u = [0.0, 1.5, 0.0]
t = [0.0, 0.5, 1.0]
@variables τ
D = Symbolics.Differential(τ)
f = LinearInterpolation(u, t)
df = expand_derivatives(D(f(τ)))
symfunc = Symbolics.build_function(df, τ; expression = Val{false})
ts = 0.0:0.1:1.0
@test all(map(ti -> symfunc(ti) == derivative(f, ti), ts))
end
2 changes: 1 addition & 1 deletion test/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ for i in 11:20
@test t[i - 10] == A[i]
end

A = LinearInterpolation{false}(u, t)
A = LinearInterpolation{false}(u, t, true)
@test length(A) == 10
for i in 1:10
@test u[i] == A[i]
Expand Down
Loading

0 comments on commit 41a061f

Please sign in to comment.