@@ -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
@@ -178,7 +179,7 @@ function LM(
178179 prox! (s, ψ, ∇fk, ν)
179180 ξ1 = fk + hk - mk1 (s) + max (1 , abs (fk + hk)) * 10 * eps () # TODO : isn't mk(s) returned by subsolver?
180181 ξ1 > 0 || error (" LM: first prox-gradient step should produce a decrease but ξ1 = $(ξ1) " )
181- sqrt_ξ1_νInv = sqrt (ξ1 * νInv)
182+ sqrt_ξ1_νInv = ξ1 > 0 ? sqrt (ξ1 * νInv) : 10.
182183
183184 if ξ1 ≥ 0 && k == 1
184185 ϵ_increment = ϵr * sqrt_ξ1_νInv
@@ -192,10 +193,10 @@ function LM(
192193 continue
193194 end
194195
195- 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
196198 subsolver_options. ν = ν
197- # subsolver_args = subsolver == TRDH ? (SpectralGradient(1 / ν, nls.meta.nvar),) : ()
198- subsolver_args = subsolver == R2DH ? (SpectralGradient (1. , nls. meta. nvar),) : ()
199+ subsolver_args = subsolver == R2DH ? (SpectralGradient (νInv, nls. meta. nvar),) : ()
199200 @debug " setting inner stopping tolerance to" subsolver_options. optTol
200201 s, iter, _ = with_logger (subsolver_logger) do
201202 subsolver (φ, ∇φ!, ψ, subsolver_args... , subsolver_options, s)
@@ -246,14 +247,20 @@ function LM(
246247 shift! (ψ, xk)
247248 Jk = jac_op_residual (nls, xk)
248249 jtprod_residual! (nls, xk, Fk, ∇fk)
249- σmax = opnorm (Jk)
250+
251+ # update opnorm if not linear least squares
252+ if nonlinear == true
253+ σmax = opnorm (Jk)
254+ end
255+
250256 Complex_hist[k] += 1
251257 end
252258
253259 if ρk < η1 || ρk == Inf
254260 σk = σk * γ
255261 end
256262 νInv = (1 + θ) * (σmax^ 2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
263+
257264 tired = k ≥ maxIter || elapsed_time > maxTime
258265 end
259266
@@ -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