diff --git a/Project.toml b/Project.toml index 307e797..3c26ff2 100644 --- a/Project.toml +++ b/Project.toml @@ -20,6 +20,8 @@ Documenter = "1" JLArrays = "0.3" OrdinaryDiffEq = "6, 7" Plots = "1" +SafeTestsets = "0.1, 1" +SciMLTesting = "1" Test = "1" julia = "1.10" @@ -29,10 +31,11 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] docs = ["Documenter", "DataInterpolations", "OrdinaryDiffEq", "Plots"] -test = ["DataInterpolations", "JET", "JLArrays", "OrdinaryDiffEq", "Pkg", "Test"] +test = ["DataInterpolations", "JET", "JLArrays", "OrdinaryDiffEq", "SafeTestsets", "SciMLTesting", "Test"] diff --git a/test/collocation.jl b/test/collocation.jl new file mode 100644 index 0000000..42a9152 --- /dev/null +++ b/test/collocation.jl @@ -0,0 +1,25 @@ +using DataCollocations +using OrdinaryDiffEq +using Test +include(joinpath(@__DIR__, "shared", "kernels_setup.jl")) + +@testset "Collocation of data" begin + f(u, p, t) = p .* u + rc = 2 + ps = repeat([-0.001], rc) + tspan = (0.0, 10.0) # Reduced time span + u0 = 3.4 .+ ones(rc) + t = collect(range(minimum(tspan); stop = maximum(tspan), length = 100)) # Reduced data points + prob = ODEProblem(f, u0, tspan, ps) + data = Array(solve(prob, Tsit5(); saveat = t, abstol = 1.0e-12, reltol = 1.0e-12)) + @testset "$kernel" for kernel in [ + bounded_support_kernels..., unbounded_support_kernels..., + ] + u′, u = collocate_data(data, t, kernel, 0.1) # Higher bandwidth + @test sum(abs2, u - data) < 1.0e-6 # More lenient tolerance + end + @testset "$kernel" for kernel in [bounded_support_kernels...] + # Errors out as the bandwidth is too low + @test_throws ErrorException collocate_data(data, t, kernel, 0.001) + end +end diff --git a/test/datainterpolations_ext.jl b/test/datainterpolations_ext.jl new file mode 100644 index 0000000..de81f99 --- /dev/null +++ b/test/datainterpolations_ext.jl @@ -0,0 +1,15 @@ +using DataCollocations +using DataInterpolations +using Test + +@testset "DataInterpolations Extension" begin + # Test with simple data + t = 0.0:0.1:1.0 + data = sin.(t) + tpoints_sample = 0.05:0.1:0.95 + + # Test that the extension method works + du, u = collocate_data(data, collect(t), collect(tpoints_sample), LinearInterpolation) + @test length(du) == length(tpoints_sample) + @test length(u) == length(tpoints_sample) +end diff --git a/test/interface.jl b/test/interface.jl new file mode 100644 index 0000000..f746640 --- /dev/null +++ b/test/interface.jl @@ -0,0 +1,42 @@ +using DataCollocations +using JLArrays +using Test + +@testset "Interface Compatibility" begin + @testset "BigFloat support" begin + # Test that BigFloat inputs are supported and eltype is preserved + tpoints = BigFloat.(collect(range(0.0, stop = 10.0, length = 30))) + data = BigFloat.(reshape(sin.(Float64.(tpoints)), 1, :)) + bandwidth = BigFloat(0.5) + + kernels = [ + EpanechnikovKernel(), UniformKernel(), TriangularKernel(), + QuarticKernel(), TriweightKernel(), TricubeKernel(), + GaussianKernel(), CosineKernel(), LogisticKernel(), + SigmoidKernel(), SilvermanKernel(), + ] + + @testset "$kernel" for kernel in kernels + u_prime, u = collocate_data(data, tpoints, kernel, bandwidth) + @test eltype(u_prime) == BigFloat + @test eltype(u) == BigFloat + end + end + + @testset "GPU array error message" begin + # Test that GPU-like arrays (JLArrays) give a clear error message + # instead of cryptic scalar indexing errors + tpoints = JLArray([1.0, 2.0, 3.0, 4.0, 5.0]) + data = JLArray([1.0 2.0 3.0 4.0 5.0]) + + @test_throws ArgumentError collocate_data(data, tpoints) + + # Also test that only GPU tpoints triggers error + tpoints_cpu = collect(1.0:5.0) + @test_throws ArgumentError collocate_data(data, tpoints_cpu) + + # And only GPU data triggers error + data_cpu = reshape(collect(1.0:5.0), 1, :) + @test_throws ArgumentError collocate_data(data_cpu, tpoints) + end +end diff --git a/test/kernel_functions.jl b/test/kernel_functions.jl new file mode 100644 index 0000000..3d69fda --- /dev/null +++ b/test/kernel_functions.jl @@ -0,0 +1,34 @@ +using DataCollocations +using Test +include(joinpath(@__DIR__, "shared", "kernels_setup.jl")) + +@testset "Kernel Functions" begin + ts = collect(-5.0:0.1:5.0) + @testset "Kernels with support from -1 to 1" begin + minus_one_index = findfirst(x -> ==(x, -1.0), ts) + plus_one_index = findfirst(x -> ==(x, 1.0), ts) + @testset "$kernel" for (kernel, x0) in zip( + bounded_support_kernels, + [0.75, 0.5, 1.0, 15.0 / 16.0, 35.0 / 32.0, 70.0 / 81.0, pi / 4.0] + ) + ws = DataCollocations.calckernel.((kernel,), ts) + # t < -1 + @test all(ws[1:(minus_one_index - 1)] .== 0.0) + # t > 1 + @test all(ws[(plus_one_index + 1):end] .== 0.0) + # -1 < t <1 + @test all(ws[(minus_one_index + 1):(plus_one_index - 1)] .> 0.0) + # t = 0 + @test DataCollocations.calckernel(kernel, 0.0) == x0 + end + end + @testset "Kernels with unbounded support" begin + @testset "$kernel" for (kernel, x0) in zip( + unbounded_support_kernels, + [1 / (sqrt(2 * pi)), 0.25, 1 / pi, 1 / (2 * sqrt(2))] + ) + # t = 0 + @test DataCollocations.calckernel(kernel, 0.0) == x0 + end + end +end diff --git a/test/qa/Project.toml b/test/qa/Project.toml index 1275e98..2823e0b 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,6 +1,8 @@ [deps] DataCollocations = "9454e98c-75cb-4dbc-9573-481819719962" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] @@ -8,5 +10,7 @@ DataCollocations = {path = "../.."} [compat] JET = "0.9, 0.10" +SafeTestsets = "0.1, 1" +SciMLTesting = "1" Test = "1" julia = "1.10" diff --git a/test/runtests.jl b/test/runtests.jl index f24d4fc..a18a7cc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,129 +1,2 @@ -using Pkg -using DataCollocations -using Test -using OrdinaryDiffEq -using DataInterpolations -using JLArrays - -const GROUP = get(ENV, "GROUP", "All") - -if GROUP == "QA" - Pkg.activate(joinpath(@__DIR__, "qa")) - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() - include(joinpath(@__DIR__, "qa", "qa.jl")) -else - @testset "DataCollocations.jl" begin - bounded_support_kernels = [ - EpanechnikovKernel(), UniformKernel(), TriangularKernel(), - QuarticKernel(), TriweightKernel(), TricubeKernel(), CosineKernel(), - ] - - unbounded_support_kernels = [ - GaussianKernel(), LogisticKernel(), SigmoidKernel(), SilvermanKernel(), - ] - - @testset "Kernel Functions" begin - ts = collect(-5.0:0.1:5.0) - @testset "Kernels with support from -1 to 1" begin - minus_one_index = findfirst(x -> ==(x, -1.0), ts) - plus_one_index = findfirst(x -> ==(x, 1.0), ts) - @testset "$kernel" for (kernel, x0) in zip( - bounded_support_kernels, - [0.75, 0.5, 1.0, 15.0 / 16.0, 35.0 / 32.0, 70.0 / 81.0, pi / 4.0] - ) - ws = DataCollocations.calckernel.((kernel,), ts) - # t < -1 - @test all(ws[1:(minus_one_index - 1)] .== 0.0) - # t > 1 - @test all(ws[(plus_one_index + 1):end] .== 0.0) - # -1 < t <1 - @test all(ws[(minus_one_index + 1):(plus_one_index - 1)] .> 0.0) - # t = 0 - @test DataCollocations.calckernel(kernel, 0.0) == x0 - end - end - @testset "Kernels with unbounded support" begin - @testset "$kernel" for (kernel, x0) in zip( - unbounded_support_kernels, - [1 / (sqrt(2 * pi)), 0.25, 1 / pi, 1 / (2 * sqrt(2))] - ) - # t = 0 - @test DataCollocations.calckernel(kernel, 0.0) == x0 - end - end - end - - @testset "Collocation of data" begin - f(u, p, t) = p .* u - rc = 2 - ps = repeat([-0.001], rc) - tspan = (0.0, 10.0) # Reduced time span - u0 = 3.4 .+ ones(rc) - t = collect(range(minimum(tspan); stop = maximum(tspan), length = 100)) # Reduced data points - prob = ODEProblem(f, u0, tspan, ps) - data = Array(solve(prob, Tsit5(); saveat = t, abstol = 1.0e-12, reltol = 1.0e-12)) - @testset "$kernel" for kernel in [ - bounded_support_kernels..., unbounded_support_kernels..., - ] - u′, u = collocate_data(data, t, kernel, 0.1) # Higher bandwidth - @test sum(abs2, u - data) < 1.0e-6 # More lenient tolerance - end - @testset "$kernel" for kernel in [bounded_support_kernels...] - # Errors out as the bandwidth is too low - @test_throws ErrorException collocate_data(data, t, kernel, 0.001) - end - end - - @testset "DataInterpolations Extension" begin - # Test with simple data - t = 0.0:0.1:1.0 - data = sin.(t) - tpoints_sample = 0.05:0.1:0.95 - - # Test that the extension method works - du, u = collocate_data(data, collect(t), collect(tpoints_sample), LinearInterpolation) - @test length(du) == length(tpoints_sample) - @test length(u) == length(tpoints_sample) - end - - @testset "Interface Compatibility" begin - @testset "BigFloat support" begin - # Test that BigFloat inputs are supported and eltype is preserved - tpoints = BigFloat.(collect(range(0.0, stop = 10.0, length = 30))) - data = BigFloat.(reshape(sin.(Float64.(tpoints)), 1, :)) - bandwidth = BigFloat(0.5) - - kernels = [ - EpanechnikovKernel(), UniformKernel(), TriangularKernel(), - QuarticKernel(), TriweightKernel(), TricubeKernel(), - GaussianKernel(), CosineKernel(), LogisticKernel(), - SigmoidKernel(), SilvermanKernel(), - ] - - @testset "$kernel" for kernel in kernels - u_prime, u = collocate_data(data, tpoints, kernel, bandwidth) - @test eltype(u_prime) == BigFloat - @test eltype(u) == BigFloat - end - end - - @testset "GPU array error message" begin - # Test that GPU-like arrays (JLArrays) give a clear error message - # instead of cryptic scalar indexing errors - tpoints = JLArray([1.0, 2.0, 3.0, 4.0, 5.0]) - data = JLArray([1.0 2.0 3.0 4.0 5.0]) - - @test_throws ArgumentError collocate_data(data, tpoints) - - # Also test that only GPU tpoints triggers error - tpoints_cpu = collect(1.0:5.0) - @test_throws ArgumentError collocate_data(data, tpoints_cpu) - - # And only GPU data triggers error - data_cpu = reshape(collect(1.0:5.0), 1, :) - @test_throws ArgumentError collocate_data(data_cpu, tpoints) - end - end - end -end +using SciMLTesting +run_tests() diff --git a/test/shared/kernels_setup.jl b/test/shared/kernels_setup.jl new file mode 100644 index 0000000..b2f9766 --- /dev/null +++ b/test/shared/kernels_setup.jl @@ -0,0 +1,10 @@ +using DataCollocations + +bounded_support_kernels = [ + EpanechnikovKernel(), UniformKernel(), TriangularKernel(), + QuarticKernel(), TriweightKernel(), TricubeKernel(), CosineKernel(), +] + +unbounded_support_kernels = [ + GaussianKernel(), LogisticKernel(), SigmoidKernel(), SilvermanKernel(), +]