@@ -47,6 +47,7 @@ function LM(
4747 subsolver = R2,
4848 subsolver_options = ROSolverOptions (ϵa = options. ϵa),
4949 selected:: AbstractVector{<:Integer} = 1 : (nls. meta. nvar),
50+ nonlinear:: Bool = true ,
5051) where {H}
5152 start_time = time ()
5253 elapsed_time = 0.0
@@ -62,6 +63,7 @@ function LM(
6263 γ = options. γ
6364 θ = options. θ
6465 σmin = options. σmin
66+ σk = options. σk
6567
6668 # store initial values of the subsolver_options fields that will be modified
6769 ν_subsolver = subsolver_options. ν
@@ -85,7 +87,6 @@ function LM(
8587 end
8688
8789 # initialize parameters
88- σk = max (1 / options. ν, σmin)
8990 xk = copy (x0)
9091 hk = h (xk[selected])
9192 if hk == Inf
@@ -101,6 +102,7 @@ function LM(
101102 xkn = similar (xk)
102103
103104 local ξ1
105+ local sqrt_ξ1_νInv
104106 k = 0
105107 Fobj_hist = zeros (maxIter)
106108 Hobj_hist = zeros (maxIter)
@@ -110,7 +112,7 @@ function LM(
110112
111113 if verbose > 0
112114 # ! format: off
113- @info @sprintf " %6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" " outer" " inner" " f(x)" " h(x)" " √ξ1 " " √ξ" " ρ" " σ" " ‖x‖" " ‖s‖" " ‖Jₖ‖²" " reg"
115+ @info @sprintf " %6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" " outer" " inner" " f(x)" " h(x)" " √(ξ1/ν) " " √ξ" " ρ" " σ" " ‖x‖" " ‖s‖" " ‖Jₖ‖²" " reg"
114116 # ! format: on
115117 end
116118
@@ -177,22 +179,24 @@ function LM(
177179 prox! (s, ψ, ∇fk, ν)
178180 ξ1 = fk + hk - mk1 (s) + max (1 , abs (fk + hk)) * 10 * eps () # TODO : isn't mk(s) returned by subsolver?
179181 ξ1 > 0 || error (" LM: first prox-gradient step should produce a decrease but ξ1 = $(ξ1) " )
182+ sqrt_ξ1_νInv = sqrt (ξ1 * νInv)
180183
181184 if ξ1 ≥ 0 && k == 1
182- ϵ_increment = ϵr * sqrt (ξ1)
185+ ϵ_increment = ϵr * sqrt_ξ1_νInv
183186 ϵ += ϵ_increment # make stopping test absolute and relative
184187 ϵ_subsolver += ϵ_increment
185188 end
186189
187- if sqrt (ξ1) < ϵ
190+ if sqrt_ξ1_νInv < ϵ
188191 # the current xk is approximately first-order stationary
189192 optimal = true
190193 continue
191194 end
192195
193- subsolver_options. ϵa = k == 1 ? 1.0e-1 : max (ϵ_subsolver, min (1.0e-2 , ξ1 / 10 ))
196+ # subsolver_options.ϵa = k == 1 ? 1.0e-1 : max(ϵ_subsolver, min(1.0e-2, ξ1 / 10))
197+ subsolver_options. ϵa = k == 1 ? 1.0e-3 : min (sqrt_ξ1_νInv ^ (1.5 ) , sqrt_ξ1_νInv * 1e-3 ) # 1.0e-5 default
194198 subsolver_options. ν = ν
195- subsolver_args = subsolver == TRDH ? (SpectralGradient (1 / ν , nls. meta. nvar),) : ()
199+ subsolver_args = subsolver == R2DH ? (SpectralGradient (νInv , nls. meta. nvar),) : ()
196200 @debug " setting inner stopping tolerance to" subsolver_options. optTol
197201 s, iter, _ = with_logger (subsolver_logger) do
198202 subsolver (φ, ∇φ!, ψ, subsolver_args... , subsolver_options, s)
@@ -222,7 +226,7 @@ function LM(
222226
223227 if (verbose > 0 ) && (k % ptf == 0 )
224228 # ! format: off
225- @info @sprintf " %6d %8d %8.1e %8.1e %7.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k iter fk hk sqrt (ξ1) sqrt (ξ) ρk σk norm (xk) norm (s) νInv σ_stat
229+ @info @sprintf " %6d %8d %8.1e %8.1e %7.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k iter fk hk sqrt_ξ1_νInv sqrt (ξ) ρk σk norm (xk) norm (s) νInv σ_stat
226230 # ! format: off
227231 end
228232
@@ -244,8 +248,11 @@ function LM(
244248 Jk = jac_op_residual (nls, xk)
245249 jtprod_residual! (nls, xk, Fk, ∇fk)
246250
247- σmax, found_σ = opnorm (Jk)
248- found_σ || error (" operator norm computation failed" )
251+ # update opnorm if not linear least squares
252+ if nonlinear == true
253+ σmax, found_σ = opnorm (Jk)
254+ found_σ || error (" operator norm computation failed" )
255+ end
249256
250257 Complex_hist[k] += 1
251258 end
@@ -262,9 +269,9 @@ function LM(
262269 @info @sprintf " %6d %8s %8.1e %8.1e" k " " fk hk
263270 elseif optimal
264271 # ! format: off
265- @info @sprintf " %6d %8d %8.1e %8.1e %7.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k 1 fk hk sqrt (ξ1) sqrt (ξ1) " " σk norm (xk) norm (s) νInv
272+ @info @sprintf " %6d %8d %8.1e %8.1e %7.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k 1 fk hk sqrt_ξ1_νInv sqrt (ξ1) " " σk norm (xk) norm (s) νInv
266273 # ! format: on
267- @info " LM: terminating with √ξ1 = $(sqrt (ξ1) ) "
274+ @info " LM: terminating with √(ξ1/ν) = $(sqrt_ξ1_νInv ) "
268275 end
269276 end
270277 status = if optimal
@@ -281,7 +288,7 @@ function LM(
281288 set_status! (stats, status)
282289 set_solution! (stats, xk)
283290 set_objective! (stats, fk + hk)
284- set_residuals! (stats, zero (eltype (xk)), ξ1 ≥ 0 ? sqrt (ξ1) : ξ1)
291+ set_residuals! (stats, zero (eltype (xk)), ξ1 ≥ 0 ? sqrt_ξ1_νInv : ξ1)
285292 set_iter! (stats, k)
286293 set_time! (stats, elapsed_time)
287294 set_solver_specific! (stats, :Fhist , Fobj_hist[1 : k])
0 commit comments