diff --git a/Project.toml b/Project.toml index 45ca7739..b7bcd4bd 100644 --- a/Project.toml +++ b/Project.toml @@ -12,14 +12,12 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [weakdeps] -DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0" LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" [extensions] -SparseConnectivityTracerDataInterpolationsExt = "DataInterpolations" SparseConnectivityTracerLogExpFunctionsExt = "LogExpFunctions" SparseConnectivityTracerNNlibExt = "NNlib" SparseConnectivityTracerNaNMathExt = "NaNMath" @@ -27,7 +25,6 @@ SparseConnectivityTracerSpecialFunctionsExt = "SpecialFunctions" [compat] ADTypes = "1" -DataInterpolations = "8.0.1" DocStringExtensions = "0.9" FillArrays = "1" LinearAlgebra = "<0.0.1, 1" diff --git a/ext/SparseConnectivityTracerDataInterpolationsExt.jl b/ext/SparseConnectivityTracerDataInterpolationsExt.jl deleted file mode 100644 index 2f668d1b..00000000 --- a/ext/SparseConnectivityTracerDataInterpolationsExt.jl +++ /dev/null @@ -1,122 +0,0 @@ -# WARNING: If you are following the "Adding Overloads" guide's advice to copy an existing package extension, -# copy another, less complicated one! -module SparseConnectivityTracerDataInterpolationsExt - -using SparseConnectivityTracer: AbstractTracer, Dual, primal, tracer -using SparseConnectivityTracer: GradientTracer, gradient_tracer_1_to_1 -using SparseConnectivityTracer: HessianTracer, hessian_tracer_1_to_1 -using FillArrays: Fill # from FillArrays.jl -using DataInterpolations: - AbstractInterpolation, - LinearInterpolation, - QuadraticInterpolation, - LagrangeInterpolation, - AkimaInterpolation, - ConstantInterpolation, - QuadraticSpline, - CubicSpline, - BSplineInterpolation, - BSplineApprox, - CubicHermiteSpline, - # PCHIPInterpolation, - QuinticHermiteSpline, - output_size - -#===========# -# Utilities # -#===========# - -# Limit support to `u` begin an AbstractVector{<:Number} or AbstractMatrix{<:Number}, -# to avoid any cases where the output size is dependent on the input value. -# https://github.com/adrhill/SparseConnectivityTracer.jl/pull/234#discussion_r2031038566 - -function _sct_interpolate( - ::AbstractInterpolation, - uType::Type{<:AbstractVector{<:Number}}, - t::GradientTracer, - is_der_1_zero, - is_der_2_zero, - ) - return gradient_tracer_1_to_1(t, is_der_1_zero) -end -function _sct_interpolate( - ::AbstractInterpolation, - uType::Type{<:AbstractVector{<:Number}}, - t::HessianTracer, - is_der_1_zero, - is_der_2_zero, - ) - return hessian_tracer_1_to_1(t, is_der_1_zero, is_der_2_zero) -end -function _sct_interpolate( - interp::AbstractInterpolation, - uType::Type{<:AbstractMatrix{<:Number}}, - t::GradientTracer, - is_der_1_zero, - is_der_2_zero, - ) - t = gradient_tracer_1_to_1(t, is_der_1_zero) - N = only(output_size(interp)) - return Fill(t, N) -end -function _sct_interpolate( - interp::AbstractInterpolation, - uType::Type{<:AbstractMatrix{<:Number}}, - t::HessianTracer, - is_der_1_zero, - is_der_2_zero, - ) - t = hessian_tracer_1_to_1(t, is_der_1_zero, is_der_2_zero) - N = only(output_size(interp)) - return Fill(t, N) -end - -#===========# -# Overloads # -#===========# - -# We assume that with the exception of ConstantInterpolation and LinearInterpolation, -# all interpolations have a non-zero second derivative at some point in the input domain. - -for (I, is_der1_zero, is_der2_zero) in ( - (:ConstantInterpolation, true, true), - (:LinearInterpolation, false, true), - (:QuadraticInterpolation, false, false), - (:LagrangeInterpolation, false, false), - (:AkimaInterpolation, false, false), - (:QuadraticSpline, false, false), - (:CubicSpline, false, false), - (:BSplineInterpolation, false, false), - (:BSplineApprox, false, false), - (:CubicHermiteSpline, false, false), - (:QuinticHermiteSpline, false, false), - ) - @eval function (interp::$(I){uType})( - t::AbstractTracer - ) where {uType <: AbstractArray{<:Number}} - return _sct_interpolate(interp, uType, t, $is_der1_zero, $is_der2_zero) - end -end - -# Some Interpolations require custom overloads on `Dual` due to mutation of caches. -for I in ( - :LagrangeInterpolation, - :BSplineInterpolation, - :BSplineApprox, - :CubicHermiteSpline, - :QuinticHermiteSpline, - ) - @eval function (interp::$(I){uType})(d::Dual) where {uType <: AbstractVector} - p = interp(primal(d)) - t = interp(tracer(d)) - return Dual(p, t) - end - - @eval function (interp::$(I){uType})(d::Dual) where {uType <: AbstractMatrix} - p = interp(primal(d)) - t = interp(tracer(d)) - return Dual.(p, t) - end -end - -end # module SparseConnectivityTracerDataInterpolationsExt diff --git a/test/Project.toml b/test/Project.toml index 21e0c146..628a9889 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -4,7 +4,6 @@ ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" ComponentArrays = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66" -DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" diff --git a/test/ext/test_DataInterpolations.jl b/test/ext/test_DataInterpolations.jl deleted file mode 100644 index fc6a7307..00000000 --- a/test/ext/test_DataInterpolations.jl +++ /dev/null @@ -1,282 +0,0 @@ -using SparseConnectivityTracer -using SparseConnectivityTracer: DEFAULT_GRADIENT_TRACER, DEFAULT_HESSIAN_TRACER -using SparseConnectivityTracer: trace_input, Dual, primal -using DataInterpolations -using DataInterpolations: AbstractInterpolation - -using LinearAlgebra: I -using Test - -myprimal(x) = x -myprimal(d::Dual) = primal(d) - -#===========# -# Test data # -#===========# - -t = [0.0, 1.0, 2.5, 4.0, 6.0]; -t_scalar = 2.0 -t_vector = [2.0, 2.5, 3.0] -t_range = 2:5 -test_inputs = (t_scalar, t_vector, t_range) - -u = sin.(t) # vector -du = cos.(t) -ddu = -sin.(t) - -#==================# -# Test definitions # -#==================# - -struct InterpolationTest{N, I <: AbstractInterpolation} # N = output dim. of interpolation - interp::I - is_der1_zero::Bool - is_der2_zero::Bool -end -function InterpolationTest( - interp::I; is_der1_zero = false, is_der2_zero = false - ) where {T, I <: AbstractInterpolation{T}} - sz = output_size(interp) - N = isempty(sz) ? 1 : only(sz) - return InterpolationTest{N, I}(interp, is_der1_zero, is_der2_zero) -end -testname(t::InterpolationTest{N}) where {N} = "$N-dim $(typeof(t.interp))" - -#================# -# Jacobian Tests # -#================# - -function test_jacobian(t::InterpolationTest) - return @testset "Jacobian" begin - for input in test_inputs - test_jacobian(t, input) - end - end -end -function test_jacobian(t::InterpolationTest{N}, input::Real) where {N} - N_IN = length(input) - N_OUT = N * N_IN - Jref = t.is_der1_zero ? zeros(N, N_IN) : ones(N, N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Jacobian sparsity" begin - J = jacobian_sparsity(t.interp, input, TracerSparsityDetector()) - @test J ≈ Jref - end - @testset "Local Jacobian sparsity" begin - J = jacobian_sparsity(t.interp, input, TracerLocalSparsityDetector()) - @test J ≈ Jref - end - end -end -function test_jacobian(t::InterpolationTest{1}, input::AbstractVector) - N = 1 - N_IN = length(input) - N_OUT = N * N_IN - Jref = t.is_der1_zero ? zeros(N_IN, N_IN) : I(N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Jacobian sparsity" begin - J = jacobian_sparsity(x -> vec(t.interp(x)), input, TracerSparsityDetector()) - @test J ≈ Jref - end - @testset "Local Jacobian sparsity" begin - J = jacobian_sparsity( - x -> vec(t.interp(x)), input, TracerLocalSparsityDetector() - ) - @test J ≈ Jref - end - end -end -function test_jacobian(t::InterpolationTest{N}, input::AbstractVector) where {N} - N_IN = length(input) - N_OUT = N * N_IN - - # Construct reference Jacobian - Jref = zeros(Bool, N_OUT, N_IN) - if !t.is_der1_zero - for (i, col) in enumerate(eachcol(Jref)) # iterate over outputs - i0 = 1 + N * (i - 1) - irange = i0:(i0 + N - 1) - col[irange] .= true - end - end - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Jacobian sparsity" begin - J = jacobian_sparsity(x -> vec(t.interp(x)), input, TracerSparsityDetector()) - @test J ≈ Jref - end - @testset "Local Jacobian sparsity" begin - J = jacobian_sparsity( - x -> vec(t.interp(x)), input, TracerLocalSparsityDetector() - ) - @test J ≈ Jref - end - end -end - -#===============# -# Hessian Tests # -#===============# - -function test_hessian(t::InterpolationTest) - return @testset "Hessian" begin - for input in test_inputs - test_hessian(t, input) - end - end -end -function test_hessian(t::InterpolationTest{1}, input::Real) - N = 1 - N_IN = length(input) - N_OUT = N * N_IN - Href = t.is_der2_zero ? zeros(N_IN, N_IN) : ones(N_IN, N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Hessian sparsity" begin - H = hessian_sparsity(t.interp, input, TracerSparsityDetector()) - @test H ≈ Href - end - @testset "Local Hessian sparsity" begin - H = hessian_sparsity(t.interp, input, TracerLocalSparsityDetector()) - @test H ≈ Href - end - end -end -function test_hessian(t::InterpolationTest{N}, input::Real) where {N} # N ≠ 1 - N_IN = length(input) - N_OUT = N * N_IN - Href = t.is_der2_zero ? zeros(N_IN, N_IN) : ones(N_IN, N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Hessian sparsity" begin - H = hessian_sparsity(x -> sum(t.interp(x)), input, TracerSparsityDetector()) - @test H ≈ Href - end - @testset "Local Hessian sparsity" begin - H = hessian_sparsity( - x -> sum(t.interp(x)), input, TracerLocalSparsityDetector() - ) - @test H ≈ Href - end - end -end -function test_hessian(t::InterpolationTest{1}, input::AbstractVector) - N = 1 - N_IN = length(input) - N_OUT = N * N_IN - Href = t.is_der2_zero ? zeros(N_IN, N_IN) : I(N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Hessian sparsity" begin - H = hessian_sparsity(x -> sum(t.interp(x)), input, TracerSparsityDetector()) - @test H ≈ Href - end - @testset "Local Hessian sparsity" begin - H = hessian_sparsity( - x -> sum(t.interp(x)), input, TracerLocalSparsityDetector() - ) - @test H ≈ Href - end - end -end -function test_hessian(t::InterpolationTest{N}, input::AbstractVector) where {N} # N ≠ 1 - N_IN = length(input) - N_OUT = N * N_IN - Href = t.is_der2_zero ? zeros(N_IN, N_IN) : I(N_IN) - - return @testset "input type $(typeof(input)): $N_IN inputs, $N states, $N_OUT outputs" begin - @testset "Global Hessian sparsity" begin - H = hessian_sparsity(x -> sum(t.interp(x)), input, TracerSparsityDetector()) - @test H ≈ Href - end - @testset "Local Hessian sparsity" begin - H = hessian_sparsity( - x -> sum(t.interp(x)), input, TracerLocalSparsityDetector() - ) - @test H ≈ Href - end - end -end - -function test_output(t::InterpolationTest) - return @testset "Output sizes and values" begin - @testset "input type: $(typeof(input))" for input in test_inputs - out_ref = t.interp(input) - s_ref = size(out_ref) - - @testset "$T" for T in (DEFAULT_GRADIENT_TRACER, DEFAULT_HESSIAN_TRACER) - t_tracer = trace_input(T, input) - out_tracer = t.interp(t_tracer) - s_tracer = size(out_tracer) - @test s_tracer == s_ref - end - @testset "$T" for T in ( - Dual{eltype(input), DEFAULT_GRADIENT_TRACER}, - Dual{eltype(input), DEFAULT_HESSIAN_TRACER}, - ) - t_dual = trace_input(T, input) - out_dual = t.interp(t_dual) - s_dual = size(out_dual) - @test s_dual == s_ref - @test myprimal.(out_dual) ≈ out_ref - end - end - end -end - -#===========# -# Run tests # -#===========# - -@testset "1D Interpolations" begin - @testset "$(testname(t))" for t in ( - InterpolationTest( - ConstantInterpolation(u, t); is_der1_zero = true, is_der2_zero = true - ), - InterpolationTest(LinearInterpolation(u, t); is_der2_zero = true), - InterpolationTest(QuadraticInterpolation(u, t)), - InterpolationTest(LagrangeInterpolation(u, t)), - InterpolationTest(AkimaInterpolation(u, t)), - InterpolationTest(QuadraticSpline(u, t)), - InterpolationTest(CubicSpline(u, t)), - InterpolationTest(BSplineInterpolation(u, t, 3, :ArcLen, :Average)), - InterpolationTest(BSplineApprox(u, t, 3, 4, :ArcLen, :Average)), - InterpolationTest(PCHIPInterpolation(u, t)), - InterpolationTest(CubicHermiteSpline(du, u, t)), - InterpolationTest(QuinticHermiteSpline(ddu, du, u, t)), - ) - test_jacobian(t) - test_hessian(t) - test_output(t) - yield() - end -end - -for N in (2, 5) - local um = rand(N, length(t)) # matrix - - @testset "$(N)D Interpolations" begin - @testset "$(testname(t))" for t in ( - InterpolationTest( - ConstantInterpolation(um, t); is_der1_zero = true, is_der2_zero = true - ), - InterpolationTest(LinearInterpolation(um, t); is_der2_zero = true), - InterpolationTest(QuadraticInterpolation(um, t)), - InterpolationTest(LagrangeInterpolation(um, t)), - ## The following interpolations appear to not be supported on N dimensions as of DataInterpolations v6.2.0: - # InterpolationTest(AkimaInterpolation(um, t)), - # InterpolationTest(BSplineApprox(um, t, 3, 4, :ArcLen, :Average)), - # InterpolationTest(QuadraticSpline(um, t)), - # InterpolationTest(CubicSpline(um, t)), - # InterpolationTest(BSplineInterpolation(um, t, 3, :ArcLen, :Average)), - # InterpolationTest(PCHIPInterpolation(um, t)), - ) - test_jacobian(t) - test_hessian(t) - test_output(t) - yield() - end - end -end diff --git a/test/linting.jl b/test/linting.jl index 485a6d21..1dd4405c 100644 --- a/test/linting.jl +++ b/test/linting.jl @@ -6,7 +6,6 @@ using JET: JET using ExplicitImports: ExplicitImports # Load package extensions so they get tested by ExplicitImports.jl -using DataInterpolations: DataInterpolations using NaNMath: NaNMath using NNlib: NNlib using SpecialFunctions: SpecialFunctions diff --git a/test/runtests.jl b/test/runtests.jl index fec7b01a..1ff7f202 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -78,13 +78,6 @@ GROUP = get(ENV, "JULIA_SCT_TEST_GROUP", "Core") include("ext/test_$ext.jl") end end - # Some extensions are only loaded in newer Julia releases - for ext in (:DataInterpolations,) - @testset "$ext" begin - @info "...$ext" - include("ext/test_$ext.jl") - end - end end end