4
4
5
5
A derivative-free line search and global convergence of Broyden-like method for nonlinear
6
6
equations [li2000derivative](@cite).
7
+
8
+ !!! tip
9
+
10
+ For static arrays and numbers if `nan_maxiters` is either `nothing` or `missing`,
11
+ we provide a fully non-allocating implementation of the algorithm, that can be used
12
+ inside GPU kernels. However, this particular version doesn't support `stats` and
13
+ `reinit!` and those will be ignored. Additionally, we fix the initial alpha for the
14
+ search to be `1`.
7
15
"""
8
16
@kwdef @concrete struct LiFukushimaLineSearch <: AbstractLineSearchAlgorithm
9
17
lambda_0 = 1
10
- beta = 1 // 2
11
- sigma_1 = 1 // 1000
12
- sigma_2 = 1 // 1000
13
- eta = 1 // 10
14
- rho = 9 // 10
15
- nan_maxiters:: Int = 5
18
+ beta = 0.5
19
+ sigma_1 = 0.001
20
+ sigma_2 = 0.001
21
+ eta = 0.1
22
+ rho = 0.9
23
+ nan_maxiters <: Union{Missing, Nothing, Int} = 5
16
24
maxiters:: Int = 100
17
25
end
18
26
19
27
@concrete mutable struct LiFukushimaLineSearchCache <: AbstractLineSearchCache
20
28
ϕ
21
29
f
22
30
p
23
- internalnorm
24
31
u_cache
25
32
fu_cache
26
33
λ₀
30
37
η
31
38
ρ
32
39
α
33
- nan_maxiters:: Int
40
+ nan_maxiters <: Union{Missing, Nothing, Int}
34
41
maxiters:: Int
35
42
stats <: Union{SciMLBase.NLStats, Nothing}
36
43
alg <: LiFukushimaLineSearch
37
44
end
38
45
46
+ @concrete struct StaticLiFukushimaLineSearchCache <: AbstractLineSearchCache
47
+ f
48
+ p
49
+ λ₀
50
+ β
51
+ σ₁
52
+ σ₂
53
+ η
54
+ ρ
55
+ maxiters:: Int
56
+ end
57
+
39
58
function CommonSolve. init (
40
- prob:: AbstractNonlinearProblem , alg:: LiFukushimaLineSearch , fu, u;
59
+ prob:: AbstractNonlinearProblem , alg:: LiFukushimaLineSearch ,
60
+ fu:: Union{SArray, Number} , u:: Union{SArray, Number} ;
41
61
stats:: Union{SciMLBase.NLStats, Nothing} = nothing , kwargs... )
62
+ if (alg. nan_maxiters === nothing || alg. nan_maxiters === missing ) && stats === nothing
63
+ T = promote_type (eltype (fu), eltype (u))
64
+ return StaticLiFukushimaLineSearchCache (prob. f, prob. p, T (alg. lambda_0),
65
+ T (alg. beta), T (alg. sigma_1), T (alg. sigma_2), T (alg. eta), T (alg. rho),
66
+ alg. maxiters)
67
+ end
68
+ return generic_lifukushima_init (prob, alg, fu, u; stats, kwargs... )
69
+ end
70
+
71
+ function CommonSolve. init (
72
+ prob:: AbstractNonlinearProblem , alg:: LiFukushimaLineSearch , fu, u; kwargs... )
73
+ return generic_lifukushima_init (prob, alg, fu, u; kwargs... )
74
+ end
75
+
76
+ function generic_lifukushima_init (
77
+ prob:: AbstractNonlinearProblem , alg:: LiFukushimaLineSearch ,
78
+ fu, u; stats:: Union{SciMLBase.NLStats, Nothing} = nothing , kwargs... )
42
79
@bb u_cache = similar (u)
43
80
@bb fu_cache = similar (fu)
44
81
T = promote_type (eltype (fu), eltype (u))
@@ -51,7 +88,7 @@ function CommonSolve.init(
51
88
end
52
89
53
90
return LiFukushimaLineSearchCache (
54
- ϕ, prob. f, prob. p, T ( 1 ), u_cache, fu_cache, T (alg. lambda_0), T (alg. beta),
91
+ ϕ, prob. f, prob. p, u_cache, fu_cache, T (alg. lambda_0), T (alg. beta),
55
92
T (alg. sigma_1), T (alg. sigma_2), T (alg. eta), T (alg. rho), T (1 ), alg. nan_maxiters,
56
93
alg. maxiters, stats, alg)
57
94
end
@@ -74,7 +111,8 @@ function CommonSolve.solve!(cache::LiFukushimaLineSearchCache, u, du)
74
111
λ₂, λ₁ = cache. λ₀, cache. λ₀
75
112
fxλp_norm = ϕ (λ₂)
76
113
77
- if ! isfinite (fxλp_norm)
114
+ if ! isfinite (fxλp_norm) && cache. nan_maxiters != = nothing &&
115
+ cache. nan_maxiters != = missing
78
116
nan_converged = false
79
117
for _ in 1 : (cache. nan_maxiters)
80
118
λ₁, λ₂ = λ₂, cache. β * λ₂
@@ -85,7 +123,7 @@ function CommonSolve.solve!(cache::LiFukushimaLineSearchCache, u, du)
85
123
nan_converged || return LineSearchSolution (cache. α, ReturnCode. Failure)
86
124
end
87
125
88
- for i in 1 : (cache. maxiters)
126
+ for _ in 1 : (cache. maxiters)
89
127
fxλp_norm = ϕ (λ₂)
90
128
converged = fxλp_norm ≤ (1 + cache. η) * fx_norm - cache. σ₁ * λ₂^ 2 * du_norm^ 2
91
129
converged && return LineSearchSolution (λ₂, ReturnCode. Success)
@@ -95,6 +133,29 @@ function CommonSolve.solve!(cache::LiFukushimaLineSearchCache, u, du)
95
133
return LineSearchSolution (cache. α, ReturnCode. Failure)
96
134
end
97
135
136
+ function CommonSolve. solve! (cache:: StaticLiFukushimaLineSearchCache , u, du)
137
+ T = promote_type (eltype (du), eltype (u))
138
+
139
+ fx_norm = norm (cache. f (u, cache. p))
140
+ du_norm = norm (du)
141
+ fxλ_norm = norm (cache. f (u .+ du, cache. p))
142
+
143
+ if fxλ_norm ≤ cache. ρ * fx_norm - cache. σ₂ * du_norm^ 2
144
+ return LineSearchSolution (T (true ), ReturnCode. Success)
145
+ end
146
+
147
+ λ₂, λ₁ = cache. λ₀, cache. λ₀
148
+
149
+ for _ in 1 : (cache. maxiters)
150
+ fxλp_norm = norm (cache. f (u .+ λ₂ .* du, cache. p))
151
+ converged = fxλp_norm ≤ (1 + cache. η) * fx_norm - cache. σ₁ * λ₂^ 2 * du_norm^ 2
152
+ converged && return LineSearchSolution (λ₂, ReturnCode. Success)
153
+ λ₁, λ₂ = λ₂, cache. β * λ₂
154
+ end
155
+
156
+ return LineSearchSolution (T (true ), ReturnCode. Failure)
157
+ end
158
+
98
159
function SciMLBase. reinit! (
99
160
cache:: LiFukushimaLineSearchCache ; p = missing , stats = missing , kwargs... )
100
161
p != = missing && (cache. p = p)
0 commit comments