Skip to content

Commit 83bc164

Browse files
Update the default value of theta in ROSolverOptions and update LM & LMTR accordingly (#180)
1 parent 4eea439 commit 83bc164

File tree

6 files changed

+27
-30
lines changed

6 files changed

+27
-30
lines changed

src/LMTR_alg.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ function LMTR(
115115

116116
if verbose > 0
117117
#! format: off
118-
@info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "√ξ1" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "1/ν" "TR"
118+
@info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "√ξ1" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "ν" "TR"
119119
#! format: on
120120
end
121121

@@ -132,9 +132,9 @@ function LMTR(
132132

133133
σmax, found_σ = opnorm(Jk)
134134
found_σ || error("operator norm computation failed")
135-
νInv = (1 + θ) * σmax^2 # ‖J'J‖ = ‖J‖²
135+
ν = θ / σmax^2 # ‖J'J‖ = ‖J‖²
136136

137-
mν∇fk = -∇fk / νInv
137+
mν∇fk = -∇fk * ν
138138

139139
optimal = false
140140
tired = k maxIter || elapsed_time > maxTime
@@ -174,8 +174,8 @@ function LMTR(
174174

175175
# Take first proximal gradient step s1 and see if current xk is nearly stationary.
176176
# s1 minimizes φ1(d) + ‖d‖² / 2 / ν + ψ(d) ⟺ s1 ∈ prox{νψ}(-ν∇φ1(0))
177-
ν = 1 / (νInv + 1 / (Δk * α))
178-
prox!(s, ψ, mν∇fk, ν)
177+
ν1 = 1 / (1/ν + 1 / (Δk * α))
178+
prox!(s, ψ, mν∇fk, ν1)
179179
ξ1 = fk + hk - mk1(s) + max(1, abs(fk + hk)) * 10 * eps()
180180
ξ1 > 0 || error("LMTR: first prox-gradient step should produce a decrease but ξ1 = $(ξ1)")
181181

@@ -197,8 +197,8 @@ function LMTR(
197197
set_bounds!(ψ, max.(-∆_effective, l_bound - xk), min.(∆_effective, u_bound - xk)) :
198198
set_radius!(ψ, ∆_effective)
199199
subsolver_options.Δk = ∆_effective / 10
200-
subsolver_options.ν = ν
201-
subsolver_args = subsolver == TRDH ? (SpectralGradient(1 / ν, nls.meta.nvar),) : ()
200+
subsolver_options.ν = ν1
201+
subsolver_args = subsolver == TRDH ? (SpectralGradient(1 / ν1, nls.meta.nvar),) : ()
202202
s, iter, _ = with_logger(subsolver_logger) do
203203
subsolver(φ, ∇φ!, ψ, subsolver_args..., subsolver_options, s)
204204
end
@@ -232,7 +232,7 @@ function LMTR(
232232

233233
if (verbose > 0) && (k % ptf == 0)
234234
#! format: off
235-
@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 ∆_effective χ(xk) sNorm νInv TR_stat
235+
@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 ∆_effective χ(xk) sNorm ν TR_stat
236236
#! format: on
237237
end
238238

@@ -255,8 +255,8 @@ function LMTR(
255255
jtprod_residual!(nls, xk, Fk, ∇fk)
256256
σmax, found_σ = opnorm(Jk)
257257
found_σ || error("operator norm computation failed")
258-
νInv = (1 + θ) * σmax^2 # ‖J'J‖ = ‖J‖²
259-
@. mν∇fk = -∇fk / νInv
258+
ν = θ / σmax^2 # ‖J'J‖ = ‖J‖²
259+
@. mν∇fk = -∇fk * ν
260260
end
261261

262262
if ρk < η1 || ρk == Inf
@@ -273,7 +273,7 @@ function LMTR(
273273
@info @sprintf "%6d %8s %8.1e %8.1e" k "" fk hk
274274
elseif optimal
275275
#! format: off
276-
@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 χ(xk) χ(s) νInv
276+
@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 χ(xk) χ(s) ν
277277
#! format: on
278278
@info "LMTR: terminating with √ξ1 = $(sqrt(ξ1))"
279279
end

src/LM_alg.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ function LM(
127127

128128
σmax, found_σ = opnorm(Jk)
129129
found_σ || error("operator norm computation failed")
130-
νInv = (1 + θ) * (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
130+
ν = θ / (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
131131

132132
s = zero(xk)
133133

@@ -174,12 +174,11 @@ function LM(
174174

175175
# take first proximal gradient step s1 and see if current xk is nearly stationary
176176
# s1 minimizes φ1(s) + ‖s‖² / 2 / ν + ψ(s) ⟺ s1 ∈ prox{νψ}(-ν∇φ1(0)).
177-
ν = 1 / νInv
178177
∇fk .*= -ν # reuse gradient storage
179178
prox!(s, ψ, ∇fk, ν)
180179
ξ1 = fk + hk - mk1(s) + max(1, abs(fk + hk)) * 10 * eps() # TODO: isn't mk(s) returned by subsolver?
181180
ξ1 > 0 || error("LM: first prox-gradient step should produce a decrease but ξ1 = $(ξ1)")
182-
sqrt_ξ1_νInv = sqrt(ξ1 * νInv)
181+
sqrt_ξ1_νInv = sqrt(ξ1 / ν)
183182

184183
if ξ1 0 && k == 1
185184
ϵ_increment = ϵr * sqrt_ξ1_νInv
@@ -196,7 +195,7 @@ function LM(
196195
# subsolver_options.ϵa = k == 1 ? 1.0e-1 : max(ϵ_subsolver, min(1.0e-2, ξ1 / 10))
197196
subsolver_options.ϵa = k == 1 ? 1.0e-3 : min(sqrt_ξ1_νInv^(1.5), sqrt_ξ1_νInv * 1e-3) # 1.0e-5 default
198197
subsolver_options.ν = ν
199-
subsolver_args = subsolver == R2DH ? (SpectralGradient(νInv, nls.meta.nvar),) : ()
198+
subsolver_args = subsolver == R2DH ? (SpectralGradient(1 / ν, nls.meta.nvar),) : ()
200199
@debug "setting inner stopping tolerance to" subsolver_options.optTol
201200
s, iter, _ = with_logger(subsolver_logger) do
202201
subsolver(φ, ∇φ!, ψ, subsolver_args..., subsolver_options, s)
@@ -226,7 +225,7 @@ function LM(
226225

227226
if (verbose > 0) && (k % ptf == 0)
228227
#! format: off
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
228+
@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) 1/ν σ_stat
230229
#! format: off
231230
end
232231

@@ -260,7 +259,7 @@ function LM(
260259
if ρk < η1 || ρk == Inf
261260
σk = σk * γ
262261
end
263-
νInv = (1 + θ) * (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
262+
ν = θ / (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ
264263
tired = k maxIter || elapsed_time > maxTime
265264
end
266265

@@ -269,7 +268,7 @@ function LM(
269268
@info @sprintf "%6d %8s %8.1e %8.1e" k "" fk hk
270269
elseif optimal
271270
#! format: off
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
271+
@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) 1/ν
273272
#! format: on
274273
@info "LM: terminating with √(ξ1/ν) = $(sqrt_ξ1_νInv)"
275274
end

src/R2DH.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ function R2DH(
191191
Dkσk = D.d .+ σk
192192
DNorm = norm(D.d, Inf)
193193

194-
ν = 1 / ((DNorm + σk) * (1 + θ))
194+
ν = θ / (DNorm + σk)
195195
mν∇fk = -ν * ∇fk
196196
sqrt_ξ_νInv = one(R)
197197

@@ -274,7 +274,7 @@ function R2DH(
274274
end
275275

276276
Dkσk .= D.d .+ σk
277-
ν = 1 / ((DNorm + σk) * (1 + θ))
277+
ν = θ / (DNorm + σk)
278278

279279
tired = maxIter > 0 && k maxIter
280280
if !tired

src/R2N.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function R2N(
134134

135135
λmax, found_λ = opnorm(Bk)
136136
found_λ || error("operator norm computation failed")
137-
νInv = (1 + θ) * (σk + λmax)
137+
ν = θ / (σk + λmax)
138138
sqrt_ξ1_νInv = one(R)
139139

140140
optimal = false
@@ -166,11 +166,11 @@ function R2N(
166166
# take first proximal gradient step s1 and see if current xk is nearly stationary
167167
# s1 minimizes φ1(s) + ‖s‖² / 2 / ν + ψ(s) ⟺ s1 ∈ prox{νψ}(-ν∇φ1(0)).
168168

169-
subsolver_options.ν = 1 / νInv
169+
subsolver_options.ν = ν
170170
prox!(s, ψ, -subsolver_options.ν * ∇fk, subsolver_options.ν)
171171
ξ1 = hk - mk1(s) + max(1, abs(hk)) * 10 * eps()
172172
ξ1 > 0 || error("R2N: first prox-gradient step should produce a decrease but ξ1 = $(ξ1)")
173-
sqrt_ξ1_νInv = sqrt(ξ1 * νInv)
173+
sqrt_ξ1_νInv = sqrt(ξ1 / ν)
174174

175175
if ξ1 0 && k == 1
176176
ϵ_increment = ϵr * sqrt_ξ1_νInv
@@ -188,7 +188,7 @@ function R2N(
188188
subsolver_options.ϵa = k == 1 ? 1.0e-3 : min(sqrt_ξ1_νInv^(1.5), sqrt_ξ1_νInv * 1e-3)
189189
verbose > 0 && @debug "setting inner stopping tolerance to" subsolver_options.optTol
190190
subsolver_options.σk = σk
191-
subsolver_args = subsolver == R2DH ? (SpectralGradient(νInv, f.meta.nvar),) : ()
191+
subsolver_args = subsolver == R2DH ? (SpectralGradient(1 / ν, f.meta.nvar),) : ()
192192
s, iter, _ = with_logger(subsolver_logger) do
193193
subsolver(φ, ∇φ!, ψ, subsolver_args..., subsolver_options, s)
194194
end
@@ -256,7 +256,7 @@ function R2N(
256256
if ρk < η1 || ρk == Inf
257257
σk = σk * γ
258258
end
259-
νInv = (1 + θ) * (σk + λmax)
259+
ν = θ / (σk + λmax)
260260
tired = k maxIter || elapsed_time > maxTime
261261
end
262262

src/TRDH_alg.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ function TRDH(
200200
∇f!(∇fk, xk)
201201
∇fk⁻ = copy(∇fk)
202202
DNorm = norm(D.d, Inf)
203-
νInv = DNorm + one(R) /* Δk)
204-
ν = one(R) / νInv
203+
ν =* Δk)/(DNorm + one(R))
205204
mν∇fk = -ν .* ∇fk
206205
sqrt_ξ_νInv = one(R)
207206

@@ -318,8 +317,7 @@ function TRDH(
318317
has_bnds ? set_bounds!(ψ, l_bound_k, u_bound_k) : set_radius!(ψ, Δk)
319318
end
320319

321-
νInv = reduce_TR ? (DNorm + one(R) /* Δk)) : (DNorm + one(R) / α)
322-
ν = one(R) / νInv
320+
ν = reduce_TR ?* Δk)/(DNorm + one(R)) : α / (DNorm + one(R))
323321
mν∇fk .= -ν .* ∇fk
324322

325323
tired = k maxIter || elapsed_time > maxTime

src/input_struct.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mutable struct ROSolverOptions{R}
3434
α::R = 1 / eps(R),
3535
ν::R = eps(R)^(1 / 5),
3636
γ::R = R(3),
37-
θ::R = eps(R)^(1 / 5),
37+
θ::R = 1/(1+eps(R)^(1 / 5)),
3838
β::R = 1 / eps(R),
3939
reduce_TR::Bool = true,
4040
) where {R <: Real}

0 commit comments

Comments
 (0)