|
| 1 | +@testitem "ForwardDiff.jl Integration: NonlinearProblem" tags=[:core] begin |
| 2 | + using ArrayInterface |
| 3 | + using ForwardDiff, FiniteDiff, SimpleNonlinearSolve, StaticArrays, LinearAlgebra, |
| 4 | + Zygote, ReverseDiff, SciMLBase |
| 5 | + using DifferentiationInterface |
| 6 | + |
| 7 | + const DI = DifferentiationInterface |
| 8 | + |
| 9 | + test_f!(du, u, p) = (@. du = u^2 - p) |
| 10 | + test_f(u, p) = u .^ 2 .- p |
| 11 | + |
| 12 | + jacobian_f(::Number, p) = 1 / (2 * √p) |
| 13 | + jacobian_f(::Number, p::Number) = 1 / (2 * √p) |
| 14 | + jacobian_f(u, p::Number) = one.(u) .* (1 / (2 * √p)) |
| 15 | + jacobian_f(u, p::AbstractArray) = diagm(vec(@. 1 / (2 * √p))) |
| 16 | + |
| 17 | + @testset for alg in ( |
| 18 | + SimpleNewtonRaphson(), |
| 19 | + SimpleTrustRegion(), |
| 20 | + SimpleTrustRegion(; nlsolve_update_rule = Val(true)), |
| 21 | + SimpleHalley(), |
| 22 | + SimpleBroyden(), |
| 23 | + SimpleKlement(), |
| 24 | + SimpleDFSane() |
| 25 | + ) |
| 26 | + us = ( |
| 27 | + 2.0, |
| 28 | + @SVector([1.0, 1.0]), |
| 29 | + [1.0, 1.0], |
| 30 | + ones(2, 2), |
| 31 | + @SArray(ones(2, 2)) |
| 32 | + ) |
| 33 | + |
| 34 | + @testset "Scalar AD" begin |
| 35 | + for p in 1.0:0.1:100.0, u0 in us |
| 36 | + sol = solve(NonlinearProblem{false}(test_f, u0, p), alg) |
| 37 | + if SciMLBase.successful_retcode(sol) |
| 38 | + gs = abs.(ForwardDiff.derivative(p) do pᵢ |
| 39 | + solve(NonlinearProblem{false}(test_f, u0, pᵢ), alg).u |
| 40 | + end) |
| 41 | + gs_true = abs.(jacobian_f(u0, p)) |
| 42 | + |
| 43 | + if !(isapprox(gs, gs_true, atol = 1e-5)) |
| 44 | + @show sol.retcode, sol.u |
| 45 | + @error "ForwardDiff Failed for u0=$(u0) and p=$(p) with $(alg)" forwardiff_gradient=gs true_gradient=gs_true |
| 46 | + else |
| 47 | + @test abs.(gs)≈abs.(gs_true) atol=1e-5 |
| 48 | + end |
| 49 | + end |
| 50 | + end |
| 51 | + end |
| 52 | + |
| 53 | + @testset "Jacobian" begin |
| 54 | + @testset "$(typeof(u0))" for u0 in us[2:end], |
| 55 | + p in ([2.0, 1.0], [2.0 1.0; 3.0 4.0]) |
| 56 | + |
| 57 | + if u0 isa AbstractArray && p isa AbstractArray |
| 58 | + size(u0) != size(p) && continue |
| 59 | + end |
| 60 | + |
| 61 | + @testset for (iip, fn) in ((false, test_f), (true, test_f!)) |
| 62 | + iip && (u0 isa Number || !ArrayInterface.can_setindex(u0)) && continue |
| 63 | + |
| 64 | + sol = solve(NonlinearProblem{iip}(fn, u0, p), alg) |
| 65 | + if SciMLBase.successful_retcode(sol) |
| 66 | + gs = abs.(ForwardDiff.jacobian(p) do pᵢ |
| 67 | + solve(NonlinearProblem{iip}(fn, u0, pᵢ), alg).u |
| 68 | + end) |
| 69 | + gs_true = abs.(jacobian_f(u0, p)) |
| 70 | + |
| 71 | + if !(isapprox(gs, gs_true, atol = 1e-5)) |
| 72 | + @show sol.retcode, sol.u |
| 73 | + @error "ForwardDiff Failed for u0=$(u0) and p=$(p) with $(alg)" forwardiff_jacobian=gs true_jacobian=gs_true |
| 74 | + else |
| 75 | + @test abs.(gs)≈abs.(gs_true) atol=1e-5 |
| 76 | + end |
| 77 | + end |
| 78 | + end |
| 79 | + end |
| 80 | + end |
| 81 | + end |
| 82 | +end |
| 83 | + |
1 | 84 | @testitem "ForwardDiff.jl Integration NonlinearLeastSquaresProblem" tags=[:core] begin
|
2 | 85 | using ForwardDiff, FiniteDiff, SimpleNonlinearSolve, StaticArrays, LinearAlgebra,
|
3 | 86 | Zygote, ReverseDiff
|
|
0 commit comments