1
1
using SimpleNonlinearSolve
2
2
using StaticArrays
3
3
using BenchmarkTools
4
+ using DiffEqBase
4
5
using Test
5
6
7
+ const BATCHED_BROYDEN_SOLVERS = Broyden[]
8
+ const BROYDEN_SOLVERS = Broyden[]
9
+
10
+ for mode in instances (NLSolveTerminationMode. T)
11
+ if mode ∈
12
+ (NLSolveTerminationMode. SteadyStateDefault, NLSolveTerminationMode. RelSafeBest,
13
+ NLSolveTerminationMode. AbsSafeBest)
14
+ continue
15
+ end
16
+
17
+ termination_condition = NLSolveTerminationCondition (mode; abstol = nothing ,
18
+ reltol = nothing )
19
+ push! (BROYDEN_SOLVERS, Broyden (; batched = false , termination_condition))
20
+ push! (BATCHED_BROYDEN_SOLVERS, Broyden (; batched = true , termination_condition))
21
+ end
22
+
6
23
# SimpleNewtonRaphson
7
24
function benchmark_scalar (f, u0)
8
25
probN = NonlinearProblem {false} (f, u0)
@@ -50,16 +67,19 @@ if VERSION >= v"1.7"
50
67
end
51
68
52
69
# Broyden
53
- function benchmark_scalar (f, u0)
70
+ function benchmark_scalar (f, u0, alg )
54
71
probN = NonlinearProblem {false} (f, u0)
55
- sol = (solve (probN, Broyden () ))
72
+ sol = (solve (probN, alg ))
56
73
end
57
74
58
- sol = benchmark_scalar (sf, csu0)
59
- @test sol. retcode === ReturnCode. Success
60
- @test sol. u * sol. u - 2 < 1e-9
61
- if VERSION >= v " 1.7"
62
- @test (@ballocated benchmark_scalar (sf, csu0)) == 0
75
+ for alg in BROYDEN_SOLVERS
76
+ sol = benchmark_scalar (sf, csu0, alg)
77
+ @test sol. retcode === ReturnCode. Success
78
+ @test sol. u * sol. u - 2 < 1e-9
79
+ # FIXME : Termination Condition Implementation is allocating. Not sure how to fix it.
80
+ # if VERSION >= v"1.7"
81
+ # @test (@ballocated benchmark_scalar($sf, $csu0, $termination_condition)) == 0
82
+ # end
63
83
end
64
84
65
85
# Klement
@@ -101,8 +121,8 @@ using ForwardDiff
101
121
# Immutable
102
122
f, u0 = (u, p) -> u .* u .- p, @SVector [1.0 , 1.0 ]
103
123
104
- for alg in (SimpleNewtonRaphson (), Broyden (), LBroyden (), Klement (), SimpleTrustRegion (),
105
- SimpleDFSane ())
124
+ for alg in (SimpleNewtonRaphson (), LBroyden (), Klement (), SimpleTrustRegion (),
125
+ SimpleDFSane (), BROYDEN_SOLVERS ... )
106
126
g = function (p)
107
127
probN = NonlinearProblem {false} (f, csu0, p)
108
128
sol = solve (probN, alg, abstol = 1e-9 )
117
137
118
138
# Scalar
119
139
f, u0 = (u, p) -> u * u - p, 1.0
120
- for alg in (SimpleNewtonRaphson (), Broyden (), LBroyden (), Klement (), SimpleTrustRegion (),
121
- SimpleDFSane (), Halley ())
140
+ for alg in (SimpleNewtonRaphson (), LBroyden (), Klement (), SimpleTrustRegion (),
141
+ SimpleDFSane (), Halley (), BROYDEN_SOLVERS ... )
122
142
g = function (p)
123
143
probN = NonlinearProblem {false} (f, oftype (p, u0), p)
124
144
sol = solve (probN, alg)
@@ -183,8 +203,8 @@ for alg in [Bisection(), Falsi(), Ridder(), Brent()]
183
203
@test ForwardDiff. jacobian (g, p) ≈ ForwardDiff. jacobian (t, p)
184
204
end
185
205
186
- for alg in (SimpleNewtonRaphson (), Broyden (), LBroyden (), Klement (), SimpleTrustRegion (),
187
- SimpleDFSane (), Halley ())
206
+ for alg in (SimpleNewtonRaphson (), LBroyden (), Klement (), SimpleTrustRegion (),
207
+ SimpleDFSane (), Halley (), BROYDEN_SOLVERS ... )
188
208
global g, p
189
209
g = function (p)
190
210
probN = NonlinearProblem {false} (f, 0.5 , p)
@@ -199,14 +219,15 @@ end
199
219
f, u0 = (u, p) -> u .* u .- 2.0 , @SVector [1.0 , 1.0 ]
200
220
probN = NonlinearProblem (f, u0)
201
221
202
- @test solve (probN, SimpleNewtonRaphson ()). u[end ] ≈ sqrt (2.0 )
203
- @test solve (probN, SimpleNewtonRaphson (; autodiff = false )). u[end ] ≈ sqrt (2.0 )
204
- @test solve (probN, SimpleTrustRegion ()). u[end ] ≈ sqrt (2.0 )
205
- @test solve (probN, SimpleTrustRegion (; autodiff = false )). u[end ] ≈ sqrt (2.0 )
206
- @test solve (probN, Broyden ()). u[end ] ≈ sqrt (2.0 )
207
- @test solve (probN, LBroyden ()). u[end ] ≈ sqrt (2.0 )
208
- @test solve (probN, Klement ()). u[end ] ≈ sqrt (2.0 )
209
- @test solve (probN, SimpleDFSane ()). u[end ] ≈ sqrt (2.0 )
222
+ for alg in (SimpleNewtonRaphson (), SimpleNewtonRaphson (; autodiff = false ),
223
+ SimpleTrustRegion (),
224
+ SimpleTrustRegion (; autodiff = false ), LBroyden (), Klement (), SimpleDFSane (),
225
+ BROYDEN_SOLVERS... )
226
+ sol = solve (probN, alg)
227
+
228
+ @test sol. retcode == ReturnCode. Success
229
+ @test sol. u[end ] ≈ sqrt (2.0 )
230
+ end
210
231
211
232
# Separate Error check for Halley; will be included in above error checks for the improved Halley
212
233
f, u0 = (u, p) -> u * u - 2.0 , 1.0
@@ -220,18 +241,16 @@ for u0 in [1.0, [1, 1.0]]
220
241
probN = NonlinearProblem (f, u0)
221
242
sol = sqrt (2 ) * u0
222
243
223
- @test solve (probN, SimpleNewtonRaphson ()). u ≈ sol
224
- @test solve (probN, SimpleNewtonRaphson ()). u ≈ sol
225
- @test solve (probN, SimpleNewtonRaphson (; autodiff = false )). u ≈ sol
226
-
227
- @test solve (probN, SimpleTrustRegion ()). u ≈ sol
228
- @test solve (probN, SimpleTrustRegion ()). u ≈ sol
229
- @test solve (probN, SimpleTrustRegion (; autodiff = false )). u ≈ sol
244
+ for alg in (SimpleNewtonRaphson (), SimpleNewtonRaphson (; autodiff = false ),
245
+ SimpleTrustRegion (),
246
+ SimpleTrustRegion (; autodiff = false ), LBroyden (), Klement (),
247
+ SimpleDFSane (),
248
+ BROYDEN_SOLVERS... )
249
+ sol2 = solve (probN, alg)
230
250
231
- @test solve (probN, Broyden ()). u ≈ sol
232
- @test solve (probN, LBroyden ()). u ≈ sol
233
- @test solve (probN, Klement ()). u ≈ sol
234
- @test solve (probN, SimpleDFSane ()). u ≈ sol
251
+ @test sol2. retcode == ReturnCode. Success
252
+ @test sol2. u ≈ sol
253
+ end
235
254
end
236
255
237
256
# Bisection Tests
@@ -411,3 +430,10 @@ probN = NonlinearProblem{false}(f, u0, p);
411
430
sol = solve (probN, Broyden (batched = true ))
412
431
413
432
@test abs .(sol. u) ≈ sqrt .(p)
433
+
434
+ for alg in BATCHED_BROYDEN_SOLVERS
435
+ sol = solve (probN, alg)
436
+
437
+ @test sol. retcode == ReturnCode. Success
438
+ @test abs .(sol. u) ≈ sqrt .(p)
439
+ end
0 commit comments