Skip to content

Commit 5e5d34e

Browse files
committed
Add tests
1 parent 44b17f2 commit 5e5d34e

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

src/broyden.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ An implementation of `Broyden` with resetting and line search.
3636
+ `Val(:diagonal)`: Only update the diagonal of the Jacobian. This algorithm may be
3737
useful for specific problems, but whether it will work may depend strongly on the
3838
problem.
39-
+ `Val(:exciting_mixing)`: Update the diagonal of the Jacobian. This is based off
40-
SciPy's implementation of Broyden's method. This algorithm may be useful for
41-
specific problems, but whether it will work may depend strongly on the problem.
4239
"""
4340
@concrete struct GeneralBroyden{IJ, UR, CJ, AD} <: AbstractNewtonAlgorithm{CJ, AD}
4441
ad::AD
@@ -65,7 +62,7 @@ function GeneralBroyden(; max_resets = 100, linesearch = nothing, reset_toleranc
6562
init_jacobian::Val = Val(:identity), autodiff = nothing, alpha = nothing,
6663
update_rule = Val(:good_broyden))
6764
UR = _unwrap_val(update_rule)
68-
@assert UR (:good_broyden, :bad_broyden, :diagonal, :exciting_mixing)
65+
@assert UR (:good_broyden, :bad_broyden, :diagonal)
6966
IJ = _unwrap_val(init_jacobian)
7067
@assert IJ (:identity, :true_jacobian)
7168
linesearch = linesearch isa LineSearch ? linesearch : LineSearch(; method = linesearch)
@@ -167,7 +164,12 @@ function perform_step!(cache::GeneralBroydenCache{iip, IJ, UR}) where {iip, IJ,
167164
T = eltype(cache.u)
168165

169166
if IJ === :true_jacobian && cache.stats.nsteps == 0
170-
cache.J⁻¹ = __safe_inv(jacobian!!(cache.J⁻¹, cache)) # This allocates
167+
if __isdiag(cache.J⁻¹) && cache.J⁻¹_cache !== nothing
168+
cache.J⁻¹_cache = __safe_inv(jacobian!!(cache.J⁻¹_cache, cache))
169+
cache.J⁻¹ = __get_diagonal!!(cache.J⁻¹, cache.J⁻¹_cache)
170+
else
171+
cache.J⁻¹ = __safe_inv(jacobian!!(cache.J⁻¹, cache))
172+
end
171173
end
172174

173175
if __isdiag(cache.J⁻¹)
@@ -195,7 +197,7 @@ function perform_step!(cache::GeneralBroydenCache{iip, IJ, UR}) where {iip, IJ,
195197
return nothing
196198
end
197199
if IJ === :true_jacobian
198-
if __isdiag(cache.J⁻¹)
200+
if __isdiag(cache.J⁻¹) && cache.J⁻¹_cache !== nothing
199201
cache.J⁻¹_cache = __safe_inv(jacobian!!(cache.J⁻¹_cache, cache))
200202
cache.J⁻¹ = __get_diagonal!!(cache.J⁻¹, cache.J⁻¹_cache)
201203
else

test/23_test_problems.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,25 @@ end
9494
GeneralBroyden(; init_jacobian = Val(:true_jacobian)),
9595
GeneralBroyden(; update_rule = Val(:bad_broyden)),
9696
GeneralBroyden(; init_jacobian = Val(:true_jacobian),
97-
update_rule = Val(:bad_broyden)))
97+
update_rule = Val(:bad_broyden)),
98+
GeneralBroyden(; update_rule = Val(:diagonal)),
99+
GeneralBroyden(; init_jacobian = Val(:true_jacobian), update_rule = Val(:diagonal)))
98100

99101
broken_tests = Dict(alg => Int[] for alg in alg_ops)
100102
broken_tests[alg_ops[1]] = [1, 5, 6, 11]
101103
broken_tests[alg_ops[2]] = [1, 5, 6, 8, 11, 18]
102104
broken_tests[alg_ops[3]] = [1, 4, 5, 6, 9, 11]
103105
broken_tests[alg_ops[4]] = [1, 5, 6, 8, 11]
106+
broken_tests[alg_ops[5]] = [1, 3, 4, 5, 6, 8, 9, 11, 12, 15, 21]
107+
broken_tests[alg_ops[6]] = [3, 4, 5, 6, 8, 9, 11, 12, 21]
104108

105109
skip_tests = Dict(alg => Int[] for alg in alg_ops)
106110
skip_tests[alg_ops[1]] = [2, 22]
107111
skip_tests[alg_ops[2]] = [2, 22]
108112
skip_tests[alg_ops[3]] = [2, 22]
109113
skip_tests[alg_ops[4]] = [2, 22]
114+
skip_tests[alg_ops[5]] = [2, 22]
115+
skip_tests[alg_ops[6]] = [2, 22]
110116

111117
test_on_library(problems, dicts, alg_ops, broken_tests; skip_tests)
112118
end

test/basictests.jl

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -692,42 +692,50 @@ end
692692
# --- GeneralBroyden tests ---
693693

694694
@testset "GeneralBroyden" begin
695-
function benchmark_nlsolve_oop(f, u0, p = 2.0; linesearch = nothing)
695+
function benchmark_nlsolve_oop(f, u0, p = 2.0; linesearch = nothing,
696+
init_jacobian = Val(:identity), update_rule = Val(:good_broyden))
696697
prob = NonlinearProblem{false}(f, u0, p)
697-
return solve(prob, GeneralBroyden(; linesearch), abstol = 1e-9)
698+
return solve(prob, GeneralBroyden(; linesearch, init_jacobian, update_rule);
699+
abstol = 1e-9)
698700
end
699701

700-
function benchmark_nlsolve_iip(f, u0, p = 2.0; linesearch = nothing)
702+
function benchmark_nlsolve_iip(f, u0, p = 2.0; linesearch = nothing,
703+
init_jacobian = Val(:identity), update_rule = Val(:good_broyden))
701704
prob = NonlinearProblem{true}(f, u0, p)
702-
return solve(prob, GeneralBroyden(; linesearch), abstol = 1e-9)
705+
return solve(prob, GeneralBroyden(; linesearch, init_jacobian, update_rule);
706+
abstol = 1e-9)
703707
end
704708

705-
@testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad))" for lsmethod in (Static(),
709+
@testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad)) Init Jacobian: $(init_jacobian) Update Rule: $(update_rule)" for lsmethod in (Static(),
706710
StrongWolfe(), BackTracking(), HagerZhang(), MoreThuente(),
707711
LiFukushimaLineSearch()),
708-
ad in (AutoFiniteDiff(), AutoZygote())
712+
ad in (AutoFiniteDiff(), AutoZygote()),
713+
init_jacobian in (Val(:identity), Val(:true_jacobian)),
714+
update_rule in (Val(:good_broyden), Val(:bad_broyden), Val(:diagonal))
709715

710716
linesearch = LineSearch(; method = lsmethod, autodiff = ad)
711717
u0s = ([1.0, 1.0], @SVector[1.0, 1.0], 1.0)
712718

713719
@testset "[OOP] u0: $(typeof(u0))" for u0 in u0s
714-
sol = benchmark_nlsolve_oop(quadratic_f, u0; linesearch)
720+
sol = benchmark_nlsolve_oop(quadratic_f, u0; linesearch, update_rule,
721+
init_jacobian)
715722
@test SciMLBase.successful_retcode(sol)
716723
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
717724

718725
cache = init(NonlinearProblem{false}(quadratic_f, u0, 2.0),
719-
GeneralBroyden(; linesearch), abstol = 1e-9)
726+
GeneralBroyden(; linesearch, update_rule, init_jacobian), abstol = 1e-9)
720727
@test (@ballocated solve!($cache)) < 200
721728
end
722729

723730
@testset "[IIP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0],)
724731
ad isa AutoZygote && continue
725-
sol = benchmark_nlsolve_iip(quadratic_f!, u0; linesearch)
732+
sol = benchmark_nlsolve_iip(quadratic_f!, u0; linesearch, update_rule,
733+
init_jacobian)
726734
@test SciMLBase.successful_retcode(sol)
727735
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
728736

729737
cache = init(NonlinearProblem{true}(quadratic_f!, u0, 2.0),
730-
GeneralBroyden(; linesearch), abstol = 1e-9)
738+
GeneralBroyden(; linesearch, update_rule, init_jacobian), abstol = 1e-9)
731739
@test (@ballocated solve!($cache)) 64
732740
end
733741
end

0 commit comments

Comments
 (0)