From 52665f1598c85c845da01a182c14b8d1029cd742 Mon Sep 17 00:00:00 2001 From: tmigot Date: Thu, 13 Jul 2023 17:31:25 -0400 Subject: [PATCH 1/4] Add derivative check for Jacobian of residual --- test/runtests.jl | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 44f37d5..485c548 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,3 +6,44 @@ end include("testBundleAdjustmentModels.jl") include("testBundleAdjustmentAllocations.jl") + +function jacobian_residual_check( + nlp::AbstractNLSModel; + x::AbstractVector = nlp.meta.x0, + atol::Float64 = 1.0e-6, + rtol::Float64 = 1.0e-4, +) + + # Fast exit if there are no constraints. + J_errs = Dict{Tuple{Int, Int}, Float64}() + nlp.nls_meta.nequ > 0 || return J_errs + + # Optimal-ish step for second-order centered finite differences. + step = (eps(Float64) / 3)^(1 / 3) + + # Check constraints Jacobian. + J = jac_residual(nlp, x) + h = zeros(nlp.meta.nvar) + cxph = zeros(nlp.nls_meta.nequ) + cxmh = zeros(nlp.nls_meta.nequ) + # Differentiate all constraints with respect to each variable in turn. + for i = 1:(nlp.meta.nvar) + h[i] = step + residual!(nlp, x + h, cxph) + residual!(nlp, x - h, cxmh) + dcdxi = (cxph - cxmh) / 2 / step + for j = 1:(nlp.nls_meta.nequ) + err = abs(dcdxi[j] - J[j, i]) + if err > atol + rtol * abs(dcdxi[j]) + J_errs[(j, i)] = err + end + end + h[i] = 0 + end + return J_errs +end + +@testset "" begin + nls = BundleAdjustmentModel("problem-49-7776-pre") + @test length(jacobian_residual_check(nls)) == 0 +end From 282f51fd8e1a7d273416737acc1aea7d4bd2a6ea Mon Sep 17 00:00:00 2001 From: tmigot Date: Thu, 13 Jul 2023 17:31:53 -0400 Subject: [PATCH 2/4] add test title --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 485c548..c3cc207 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -43,7 +43,7 @@ function jacobian_residual_check( return J_errs end -@testset "" begin +@testset "Test derivative Jacobian of residual" begin nls = BundleAdjustmentModel("problem-49-7776-pre") @test length(jacobian_residual_check(nls)) == 0 end From e8d805958fda70ae1cbe8b247952429d431c5b46 Mon Sep 17 00:00:00 2001 From: tmigot Date: Thu, 13 Jul 2023 17:58:25 -0400 Subject: [PATCH 3/4] fix --- test/runtests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index c3cc207..e2a7c7b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,6 +7,7 @@ end include("testBundleAdjustmentModels.jl") include("testBundleAdjustmentAllocations.jl") +# https://github.com/JuliaSmoothOptimizers/NLPModelsTest.jl/blob/src/dercheck.jl#L43 function jacobian_residual_check( nlp::AbstractNLSModel; x::AbstractVector = nlp.meta.x0, @@ -45,5 +46,6 @@ end @testset "Test derivative Jacobian of residual" begin nls = BundleAdjustmentModel("problem-49-7776-pre") + x = 10 * [-(-1.0)^i for i = 1:nls.meta.nvar] @test length(jacobian_residual_check(nls)) == 0 end From 64a857d1251e2622cad4c9e5035afc2b1c85da3b Mon Sep 17 00:00:00 2001 From: tmigot Date: Thu, 13 Jul 2023 18:29:57 -0400 Subject: [PATCH 4/4] Update runtests.jl --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index e2a7c7b..6656615 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -47,5 +47,5 @@ end @testset "Test derivative Jacobian of residual" begin nls = BundleAdjustmentModel("problem-49-7776-pre") x = 10 * [-(-1.0)^i for i = 1:nls.meta.nvar] - @test length(jacobian_residual_check(nls)) == 0 + @test length(jacobian_residual_check(nls, x = x)) == 0 end