Skip to content

Commit ac25507

Browse files
geoffroylecontedpo
andauthored
Update criticality measure (#117)
Co-authored-by: Dominique <dominique.orban@gmail.com>
1 parent 2f8b9fc commit ac25507

7 files changed

Lines changed: 51 additions & 44 deletions

File tree

benchmarks/tables/fh-table.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ uvar = fill(Inf, 5)
1313
data, simulate, resid, misfit, x0 = RegularizedProblems.FH_smooth_term()
1414
model = ADNLPModel(misfit, ones(5), lvar, uvar)
1515
f = LBFGSModel(model)
16-
λ = cstr ? 2.0e1 : 1.0e1
16+
λ = cstr ? 4.0e1 : 1.0e1
1717

18-
h = NormL1(λ)
18+
h = cstr ? NormL1(λ) : NormL0(λ)
1919
ν = 1.0e0
2020
verbose = 0 #10
2121
maxIter = 500

benchmarks/tables/regulopt-tables.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function benchmark_table(
107107
"solver",
108108
L"$f(x)$",
109109
L"$h(x) / \lambda$",
110-
L"$\xi$",
110+
L"$\sqrt{\xi / \nu}$",
111111
L"$\# \ f$",
112112
L"$\# \ \nabla f$",
113113
L"$\# \ prox$",
@@ -118,7 +118,7 @@ function benchmark_table(
118118
"solver",
119119
"\$f(x)\$",
120120
L"$h(x)/\lambda$",
121-
L"$\xi$",
121+
L"$\sqrt{\xi / \nu}$",
122122
pb_name[1:3] == "SVM" ? L"$(Train, Test)$" : L"$\|x-x_T\|_2$",
123123
L"$\# \ f$",
124124
L"$\# \ \nabla f$",
@@ -128,13 +128,13 @@ function benchmark_table(
128128
end
129129
else
130130
if length(sol) == 0
131-
header = ["solver", "f(x)", "h(x)/λ", "ξ", "# f", "# ∇f", "# prox", "t (s)"]
131+
header = ["solver", "f(x)", "h(x)/λ", "√(ξ/ν)", "# f", "# ∇f", "# prox", "t (s)"]
132132
else
133133
header = [
134134
"solver",
135135
"f(x)",
136136
"h(x)/λ",
137-
"ξ",
137+
"√ξ/√ν",
138138
pb_name[1:3] == "SVM" ? "(Train, Test)" : "||x-x*||",
139139
"# f",
140140
"# ∇f",

benchmarks/tables/svm-table.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ verbose = 0 #10
1515
ϵ = 1.0e-4
1616
ϵi = 1.0e-3
1717
ϵri = 1.0e-6
18-
maxIter = 500
18+
maxIter = 1000
1919
maxIter_inner = 100
2020
options =
2121
ROSolverOptions= ν, ϵa = ϵ, ϵr = ϵ, verbose = verbose, maxIter = maxIter, spectral = true)

src/R2_alg.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function R2(nlp::AbstractNLPModel, args...; kwargs...)
117117
set_status!(stats, outdict[:status])
118118
set_solution!(stats, xk)
119119
set_objective!(stats, outdict[:fk] + outdict[:hk])
120-
set_residuals!(stats, zero(eltype(xk)), ξ 0 ? sqrt(ξ) : ξ)
120+
set_residuals!(stats, zero(eltype(xk)), ξ)
121121
set_iter!(stats, k)
122122
set_time!(stats, outdict[:elapsed_time])
123123
set_solver_specific!(stats, :Fhist, outdict[:Fhist])
@@ -258,14 +258,15 @@ function R2!(
258258

259259
if verbose > 0
260260
#! format: off
261-
@info @sprintf "%6s %8s %8s %7s %8s %7s %7s %7s %1s" "iter" "f(x)" "h(x)" "ξ" "ρ" "σ" "‖x‖" "‖s‖" ""
261+
@info @sprintf "%6s %8s %8s %7s %8s %7s %7s %7s %1s" "iter" "f(x)" "h(x)" "(ξ/ν)" "ρ" "σ" "‖x‖" "‖s‖" ""
262262
#! format: off
263263
end
264264

265265
local ξ::R
266266
k = 0
267267
σk = max(1 / ν, σmin)
268268
ν = 1 / σk
269+
sqrt_ξ_νInv = one(R)
269270

270271
fk = f(xk)
271272
∇f!(∇fk, xk)
@@ -288,12 +289,13 @@ function R2!(
288289
Complex_hist[k] += 1
289290
mks = mk(s)
290291
ξ = hk - mks + max(1, abs(hk)) * 10 * eps()
292+
sqrt_ξ_νInv = ξ 0 ? sqrt/ ν) : sqrt(-ξ / ν)
291293

292294
if ξ 0 && k == 1
293-
ϵ += ϵr * sqrt/ν) # make stopping test absolute and relative
295+
ϵ += ϵr * sqrt_ξ_νInv # make stopping test absolute and relative
294296
end
295297

296-
if< 0 && sqrt(-ξ/ν) neg_tol) || 0 && sqrt/ν) ϵ)
298+
if< 0 && sqrt_ξ_νInv neg_tol) || 0 && sqrt_ξ_νInv ϵ)
297299
optimal = true
298300
continue
299301
end
@@ -310,7 +312,7 @@ function R2!(
310312
if (verbose > 0) && (k % ptf == 0)
311313
#! format: off
312314
σ_stat = (η2 ρk < Inf) ? "" : (ρk < η1 ? "" : "=")
313-
@info @sprintf "%6d %8.1e %8.1e %7.1e %8.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt/ν) ρk σk norm(xk) norm(s) σ_stat
315+
@info @sprintf "%6d %8.1e %8.1e %7.1e %8.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt_ξ_νInv ρk σk norm(xk) norm(s) σ_stat
314316

315317
#! format: on
316318
end
@@ -350,7 +352,7 @@ function R2!(
350352
#! format: off
351353
@info @sprintf "%6d %8.1e %8.1e %7.1e %8s %7.1e %7.1e %7.1e" k fk hk sqrt/ν) "" σk norm(xk) norm(s)
352354
#! format: on
353-
@info "R2: terminating with √ξ/√ν = $(sqrt/ν))"
355+
@info "R2: terminating with √(ξ/ν) = $(sqrt_ξ_νInv)"
354356
end
355357
end
356358

@@ -364,5 +366,5 @@ function R2!(
364366
:exception
365367
end
366368

367-
return k, status, fk, hk, ξ
369+
return k, status, fk, hk, sqrt_ξ_νInv
368370
end

src/TRDH_alg.jl

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function TRDH(
7272
set_status!(stats, outdict[:status])
7373
set_solution!(stats, xk)
7474
set_objective!(stats, outdict[:fk] + outdict[:hk])
75-
set_residuals!(stats, zero(eltype(xk)), ξ 0 ? sqrt(ξ) : ξ)
75+
set_residuals!(stats, zero(eltype(xk)), ξ)
7676
set_iter!(stats, k)
7777
set_time!(stats, outdict[:elapsed_time])
7878
set_solver_specific!(stats, :Fhist, outdict[:Fhist])
@@ -188,9 +188,9 @@ function TRDH(
188188
if verbose > 0
189189
#! format: off
190190
if reduce_TR
191-
@info @sprintf "%6s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "f(x)" "h(x)" "ξ1" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Dₖ‖" "TRDH"
191+
@info @sprintf "%6s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "f(x)" "h(x)" "(ξ1/ν)" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Dₖ‖" "TRDH"
192192
else
193-
@info @sprintf "%6s %8s %8s %7s %8s %7s %7s %7s %7s %1s" "outer" "f(x)" "h(x)" "ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Dₖ‖" "TRDH"
193+
@info @sprintf "%6s %8s %8s %7s %8s %7s %7s %7s %7s %1s" "outer" "f(x)" "h(x)" "(ξ/ν)" "ρ" "Δ" "‖x‖" "‖s‖" "‖Dₖ‖" "TRDH"
194194
end
195195
#! format: off
196196
end
@@ -209,6 +209,7 @@ function TRDH(
209209
νInv = (DkNorm + one(R) /* Δk))
210210
ν = one(R) / νInv
211211
mν∇fk = -ν .* ∇fk
212+
sqrt_ξ_νInv = one(R)
212213

213214
optimal = false
214215
tired = maxIter > 0 && k maxIter || elapsed_time > maxTime
@@ -227,12 +228,13 @@ function TRDH(
227228
prox!(s, ψ, mν∇fk, ν)
228229
Complex_hist[k] += 1
229230
ξ1 = hk - mk1(s) + max(1, abs(hk)) * 10 * eps()
231+
sqrt_ξ_νInv = ξ1 0 ? sqrt(ξ1 / ν) : sqrt(-ξ1 / ν)
230232

231233
if ξ1 0 && k == 1
232-
ϵ += ϵr * sqrt(ξ1) # make stopping test absolute and relative
234+
ϵ += ϵr * sqrt_ξ_νInv # make stopping test absolute and relative
233235
end
234236

235-
if (ξ1 < 0 && sqrt(-ξ1) neg_tol) || (ξ1 0 && sqrt(ξ1) < ϵ)
237+
if (ξ1 < 0 && sqrt_ξ_νInv neg_tol) || (ξ1 0 && sqrt_ξ_νInv < ϵ)
236238
# the current xk is approximately first-order stationary
237239
optimal = true
238240
continue
@@ -267,11 +269,13 @@ function TRDH(
267269
ξ = hk - mk(s) + max(1, abs(hk)) * 10 * eps()
268270

269271
if !reduce_TR
272+
273+
sqrt_ξ_νInv = ξ 0 ? sqrt/ ν) : sqrt(-ξ / ν)
270274
if ξ 0 && k == 1
271-
ϵ += ϵr * sqrt(ξ) # make stopping test absolute and relative
275+
ϵ += ϵr * sqrt_ξ_νInv # make stopping test absolute and relative
272276
end
273277

274-
if< 0 && sqrt(-ξ) neg_tol) || 0 && sqrt(ξ) < ϵ)
278+
if< 0 && sqrt_ξ_νInv neg_tol) || 0 && sqrt_ξ_νInv < ϵ)
275279
# the current xk is approximately first-order stationary
276280
optimal = true
277281
continue
@@ -289,9 +293,9 @@ function TRDH(
289293
if (verbose > 0) && (k % ptf == 0)
290294
#! format: off
291295
if reduce_TR
292-
@info @sprintf "%6d %8.1e %8.1e %7.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt(ξ1) sqrt(ξ) ρk Δk χ(xk) sNorm norm(Dk.d) TR_stat
296+
@info @sprintf "%6d %8.1e %8.1e %7.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt_ξ_νInv sqrt(ξ) ρk Δk χ(xk) sNorm norm(Dk.d) TR_stat
293297
else
294-
@info @sprintf "%6d %8.1e %8.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt(ξ) ρk Δk χ(xk) sNorm norm(Dk.d) TR_stat
298+
@info @sprintf "%6d %8.1e %8.1e %7.1e %8.1e %7.1e %7.1e %7.1e %7.1e %1s" k fk hk sqrt_ξ_νInv ρk Δk χ(xk) sNorm norm(Dk.d) TR_stat
295299
end
296300
#! format: on
297301
end
@@ -321,7 +325,7 @@ function TRDH(
321325
has_bnds ? set_bounds!(ψ, l_bound_k, u_bound_k) : set_radius!(ψ, Δk)
322326
end
323327

324-
νInv = (DkNorm + one(R) /* Δk))
328+
νInv = reduce_TR ? (DkNorm + one(R) /* Δk)) : (DkNorm + one(R) / α)
325329
ν = one(R) / νInv
326330
mν∇fk .= -ν .* ∇fk
327331

@@ -334,14 +338,12 @@ function TRDH(
334338
elseif optimal
335339
#! format: off
336340
if reduce_TR
337-
@info @sprintf "%6d %8.1e %8.1e %7.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k fk hk sqrt(ξ1) sqrt(ξ1) "" Δk χ(xk) χ(s) norm(Dk.d)
341+
@info @sprintf "%6d %8.1e %8.1e %7.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k fk hk sqrt_ξ_νInv sqrt(ξ1) "" Δk χ(xk) χ(s) norm(Dk.d)
338342
#! format: on
339-
@info "TRDH: terminating with √ξ1 = $(sqrt(ξ1))"
343+
@info "TRDH: terminating with √(ξ1/ν) = $(sqrt_ξ_νInv)"
340344
else
341-
@info @sprintf "%6d %8.1e %8.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k fk hk sqrt(ξ) "" Δk χ(
342-
xk,
343-
) χ(s) norm(Dk.d)
344-
@info "TRDH: terminating with √ξ = $(sqrt(ξ))"
345+
@info @sprintf "%6d %8.1e %8.1e %7.1e %8s %7.1e %7.1e %7.1e %7.1e" k fk hk sqrt_ξ_νInv "" Δk χ(xk) χ(s) norm(Dk.d)
346+
@info "TRDH: terminating with √(ξ/ν) = $(sqrt_ξ_νInv)"
345347
end
346348
end
347349
end
@@ -365,7 +367,7 @@ function TRDH(
365367
:status => status,
366368
:fk => fk,
367369
:hk => hk,
368-
=> ξ1,
370+
=> sqrt_ξ_νInv,
369371
:elapsed_time => elapsed_time,
370372
)
371373

src/TR_alg.jl

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ function TR(
4848
f::AbstractNLPModel,
4949
h::H,
5050
χ::X,
51-
options::ROSolverOptions;
52-
x0::AbstractVector = f.meta.x0,
51+
options::ROSolverOptions{R};
52+
x0::AbstractVector{R} = f.meta.x0,
5353
subsolver_logger::Logging.AbstractLogger = Logging.NullLogger(),
5454
subsolver = R2,
5555
subsolver_options = ROSolverOptions(ϵa = options.ϵa),
5656
selected::AbstractVector{<:Integer} = 1:(f.meta.nvar),
57-
) where {H, X}
57+
) where {H, X, R}
5858
start_time = time()
5959
elapsed_time = 0.0
6060
# initialize passed options
@@ -117,7 +117,7 @@ function TR(
117117
Complex_hist = zeros(Int, maxIter)
118118
if verbose > 0
119119
#! format: off
120-
@info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "ξ1" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Bₖ‖" "TR"
120+
@info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "(ξ1/ν)" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Bₖ‖" "TR"
121121
#! format: on
122122
end
123123

@@ -133,6 +133,8 @@ function TR(
133133

134134
λmax = opnorm(Bk)
135135
νInv = (1 + θ) * λmax
136+
ν = 1 / (νInv + 1 / (Δk * α))
137+
sqrt_ξ1_νInv = one(R)
136138

137139
optimal = false
138140
tired = k maxIter || elapsed_time > maxTime
@@ -160,24 +162,24 @@ function TR(
160162

161163
# Take first proximal gradient step s1 and see if current xk is nearly stationary.
162164
# s1 minimizes φ1(s) + ‖s‖² / 2 / ν + ψ(s) ⟺ s1 ∈ prox{νψ}(-ν∇φ1(0)).
163-
ν = 1 / (νInv + 1 / (Δk * α))
164165
prox!(s, ψ, -ν * ∇fk, ν)
165166
ξ1 = hk - mk1(s) + max(1, abs(hk)) * 10 * eps()
166167
ξ1 > 0 || error("TR: first prox-gradient step should produce a decrease but ξ1 = $(ξ1)")
168+
sqrt_ξ1_νInv = sqrt(ξ1 / ν)
167169

168170
if ξ1 0 && k == 1
169-
ϵ_increment = ϵr * sqrt(ξ1)
171+
ϵ_increment = ϵr * sqrt_ξ1_νInv
170172
ϵ += ϵ_increment # make stopping test absolute and relative
171173
ϵ_subsolver += ϵ_increment
172174
end
173175

174-
if sqrt(ξ1) < ϵ
176+
if sqrt_ξ1_νInv < ϵ
175177
# the current xk is approximately first-order stationary
176178
optimal = true
177179
continue
178180
end
179181

180-
subsolver_options.ϵa = k == 1 ? 1.0e-5 : max(ϵ_subsolver, min(1e-2, sqrt(ξ1)) * ξ1)
182+
subsolver_options.ϵa = k == 1 ? 1.0e-5 : max(ϵ_subsolver, min(1e-2, sqrt_ξ1_νInv))
181183
∆_effective = min* χ(s), Δk)
182184
(has_bounds(f) || subsolver == TRDH) ?
183185
set_bounds!(ψ, max.(-∆_effective, l_bound - xk), min.(∆_effective, u_bound - xk)) :
@@ -214,7 +216,7 @@ function TR(
214216

215217
if (verbose > 0) && (k % ptf == 0)
216218
#! format: off
217-
@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
219+
@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 ∆_effective χ(xk) sNorm νInv TR_stat
218220
#! format: on
219221
end
220222

@@ -248,6 +250,7 @@ function TR(
248250
(has_bounds(f) || subsolver == TRDH) ?
249251
set_bounds!(ψ, max.(-Δk, l_bound - xk), min.(Δk, u_bound - xk)) : set_radius!(ψ, Δk)
250252
end
253+
ν = 1 / (νInv + 1 / (Δk * α))
251254
tired = k maxIter || elapsed_time > maxTime
252255
end
253256

@@ -256,9 +259,9 @@ function TR(
256259
@info @sprintf "%6d %8s %8.1e %8.1e" k "" fk hk
257260
elseif optimal
258261
#! format: off
259-
@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
262+
@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 χ(xk) χ(s) νInv
260263
#! format: on
261-
@info "TR: terminating with √ξ1 = $(sqrt(ξ1))"
264+
@info "TR: terminating with √(ξ1/ν) = $(sqrt_ξ1_νInv)"
262265
end
263266
end
264267

@@ -276,7 +279,7 @@ function TR(
276279
set_status!(stats, status)
277280
set_solution!(stats, xk)
278281
set_objective!(stats, fk + hk)
279-
set_residuals!(stats, zero(eltype(xk)), ξ1 0 ? sqrt(ξ1) : ξ1)
282+
set_residuals!(stats, zero(eltype(xk)), sqrt_ξ1_νInv)
280283
set_iter!(stats, k)
281284
set_time!(stats, elapsed_time)
282285
set_solver_specific!(stats, :Fhist, Fobj_hist[1:k])

src/input_struct.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mutable struct ROSolverOptions{R}
2323
function ROSolverOptions{R}(;
2424
ϵa::R = eps(R),
2525
ϵr::R = eps(R),
26-
neg_tol::R = eps(R)^(1 / 3),
26+
neg_tol::R = eps(R)^(1 / 4),
2727
Δk::R = one(R),
2828
verbose::Int = 0,
2929
maxIter::Int = 10000,

0 commit comments

Comments
 (0)