Skip to content

Commit 0871eee

Browse files
add compute_obj and compute_grad options
1 parent 030c8cb commit 0871eee

5 files changed

Lines changed: 32 additions & 12 deletions

File tree

src/R2DH.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ or
127127
- `γ::T = T(3)`: regularization parameter multiplier, σ := σ/γ when the iteration is very successful and σ := σγ when the iteration is unsuccessful.
128128
- `θ::T = 1/(1 + eps(T)^(1 / 5))`: is the model decrease fraction with respect to the decrease of the Cauchy model.
129129
- `m_monotone::Int = 6`: monotoneness parameter. By default, R2DH is non-monotone but the monotone variant can be used with `m_monotone = 1`
130+
- `compute_obj::Bool = true`: (advanced) whether `f(x₀)` should be computed or not. If set to false, then the value is retrieved from `stats.solver_specific[:smooth_obj]`;
131+
- `compute_grad::Bool = true`: (advanced) whether `∇f(x₀)` should be computed or not. If set to false, then the value is retrieved from `solver.∇fk`;
130132
131133
The algorithm stops either when `√(ξₖ/νₖ) < atol + rtol*√(ξ₀/ν₀) ` or `ξₖ < 0` and `√(-ξₖ/νₖ) < neg_tol` where ξₖ := f(xₖ) + h(xₖ) - φ(sₖ; xₖ) - ψ(sₖ; xₖ), and √(ξₖ/νₖ) is a stationarity measure.
132134
@@ -228,6 +230,8 @@ function SolverCore.solve!(
228230
η2::T = T(0.9),
229231
γ::T = T(3),
230232
θ::T = 1/(1 + eps(T)^(1 / 5)),
233+
compute_obj::Bool = true,
234+
compute_grad::Bool = true,
231235
) where {T, V}
232236
reset!(stats)
233237

@@ -293,8 +297,8 @@ function SolverCore.solve!(
293297
local ξ::T
294298
local ρk::T = zero(T)
295299

296-
fk = obj(nlp, xk)
297-
grad!(nlp, xk, ∇fk)
300+
fk = compute_obj ? obj(nlp, xk) : stats.solver_specific[:smooth_obj]
301+
compute_grad && grad!(nlp, xk, ∇fk)
298302
∇fk⁻ .= ∇fk
299303
spectral_test = isa(D, SpectralGradient)
300304

src/R2N.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ For advanced usage, first define a solver "R2NSolver" to preallocate the memory
141141
- `θ::T = 1/(1 + eps(T)^(1 / 5))`: is the model decrease fraction with respect to the decrease of the Cauchy model;
142142
- `opnorm_maxiter::Int = 5`: how many iterations of the power method to use to compute the operator norm of Bₖ. If a negative number is provided, then Arpack is used instead;
143143
- `m_monotone::Int = 1`: monotonicity parameter. By default, R2N is monotone but the non-monotone variant will be used if `m_monotone > 1`;
144+
- `compute_obj::Bool = true`: (advanced) whether `f(x₀)` should be computed or not. If set to false, then the value is retrieved from `stats.solver_specific[:smooth_obj]`;
145+
- `compute_grad::Bool = true`: (advanced) whether `∇f(x₀)` should be computed or not. If set to false, then the value is retrieved from `solver.∇fk`;
144146
- `sub_kwargs::NamedTuple = NamedTuple()`: a named tuple containing the keyword arguments to be sent to the subsolver. The solver will fail if invalid keyword arguments are provided to the subsolver. For example, if the subsolver is `R2Solver`, you can pass `sub_kwargs = (max_iter = 100, σmin = 1e-6,)`.
145147
146148
The algorithm stops either when `√(ξₖ/νₖ) < atol + rtol*√(ξ₀/ν₀) ` or `ξₖ < 0` and `√(-ξₖ/νₖ) < neg_tol` where ξₖ := f(xₖ) + h(xₖ) - φ(sₖ; xₖ) - ψ(sₖ; xₖ), and √(ξₖ/νₖ) is a stationarity measure.
@@ -218,6 +220,8 @@ function SolverCore.solve!(
218220
β::T = 1 / eps(T),
219221
θ::T = 1/(1 + eps(T)^(1 / 5)),
220222
opnorm_maxiter::Int = 5,
223+
compute_obj::Bool = true,
224+
compute_grad::Bool = true,
221225
sub_kwargs::NamedTuple = NamedTuple(),
222226
) where {T, V, G}
223227
reset!(stats)
@@ -285,8 +289,8 @@ function SolverCore.solve!(
285289
local ρk::T = zero(T)
286290
local prox_evals::Int = 0
287291

288-
fk = obj(nlp, xk)
289-
grad!(nlp, xk, ∇fk)
292+
fk = compute_obj ? obj(nlp, xk) : stats.solver_specific[:smooth_obj]
293+
compute_grad && grad!(nlp, xk, ∇fk)
290294
qn_copy!(nlp, solver, stats)
291295

292296
quasiNewtTest = isa(nlp, QuasiNewtonModel)

src/R2_alg.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ For advanced usage, first define a solver "R2Solver" to preallocate the memory u
153153
- `η2::T = T(0.9)`: successful iteration threshold;
154154
- `ν::T = eps(T)^(1 / 5)`: multiplicative inverse of the regularization parameter: ν = 1/σ;
155155
- `γ::T = T(3)`: regularization parameter multiplier, σ := σ/γ when the iteration is very successful and σ := σγ when the iteration is unsuccessful.
156+
- `compute_obj::Bool = true`: (advanced) whether `f(x₀)` should be computed or not. If set to false, then the value is retrieved from `stats.solver_specific[:smooth_obj]`;
157+
- `compute_grad::Bool = true`: (advanced) whether `∇f(x₀)` should be computed or not. If set to false, then the value is retrieved from `solver.∇fk`;
156158
157159
The algorithm stops either when `√(ξₖ/νₖ) < atol + rtol*√(ξ₀/ν₀) ` or `ξₖ < 0` and `√(-ξₖ/νₖ) < neg_tol` where ξₖ := f(xₖ) + h(xₖ) - φ(sₖ; xₖ) - ψ(sₖ; xₖ), and √(ξₖ/νₖ) is a stationarity measure.
158160
@@ -323,6 +325,8 @@ function SolverCore.solve!(
323325
η2::T = T(0.9),
324326
ν::T = eps(T)^(1 / 5),
325327
γ::T = T(3),
328+
compute_obj::Bool = true,
329+
compute_grad::Bool = true,
326330
) where {T, V}
327331
reset!(stats)
328332

@@ -386,8 +390,8 @@ function SolverCore.solve!(
386390
ν = 1 / σk
387391
sqrt_ξ_νInv = one(T)
388392

389-
fk = obj(nlp, xk)
390-
grad!(nlp, xk, ∇fk)
393+
fk = compute_obj ? obj(nlp, xk) : stats.solver_specific[:smooth_obj]
394+
compute_grad && grad!(nlp, xk, ∇fk)
391395
@. mν∇fk = -ν * ∇fk
392396

393397
set_iter!(stats, 0)

src/TRDH_alg.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ For advanced usage, first define a solver "TRDHSolver" to preallocate the memory
135135
- `η2::T = T(0.9)`: very successful iteration threshold;
136136
- `γ::T = T(3)`: trust-region radius parameter multiplier. Must satisfy `γ > 1`. The trust-region radius is updated as Δ := Δ*γ when the iteration is very successful and Δ := Δ/γ when the iteration is unsuccessful;
137137
- `reduce_TR::Bool = true`: see explanation on the stopping criterion below;
138-
- `χ::F = NormLinf(1)`: norm used to define the trust-region;`
139-
- `D::L = nothing`: diagonal quasi-Newton approximation used for the model φ. If nothing is provided and `reg_nlp.model` is not a diagonal quasi-Newton approximation, a spectral gradient approximation is used.`
138+
- `χ::F = NormLinf(1)`: norm used to define the trust-region;
139+
- `D::L = nothing`: diagonal quasi-Newton approximation used for the model φ. If nothing is provided and `reg_nlp.model` is not a diagonal quasi-Newton approximation, a spectral gradient approximation is used;
140+
- `compute_obj::Bool = true`: (advanced) whether `f(x₀)` should be computed or not. If set to false, then the value is retrieved from `stats.solver_specific[:smooth_obj]`;
141+
- `compute_grad::Bool = true`: (advanced) whether `∇f(x₀)` should be computed or not. If set to false, then the value is retrieved from `solver.∇fk`;
140142
141143
The algorithm stops either when `√(ξₖ/νₖ) < atol + rtol*√(ξ₀/ν₀) ` or `ξₖ < 0` and `√(-ξₖ/νₖ) < neg_tol` where ξₖ := f(xₖ) + h(xₖ) - φ(sₖ; xₖ) - ψ(sₖ; xₖ), and √(ξₖ/νₖ) is a stationarity measure.
142144
Alternatively, if `reduce_TR = true`, then ξₖ₁ := f(xₖ) + h(xₖ) - φ(sₖ₁; xₖ) - ψ(sₖ₁; xₖ) is used instead of ξₖ, where sₖ₁ is the Cauchy point.
@@ -241,6 +243,8 @@ function SolverCore.solve!(
241243
η1::T = √√eps(T),
242244
η2::T = T(0.9),
243245
γ::T = T(3),
246+
compute_obj::Bool = true,
247+
compute_grad::Bool = true,
244248
) where {T, G, V}
245249
reset!(stats)
246250

@@ -315,8 +319,8 @@ function SolverCore.solve!(
315319
α = 1 / eps(T)
316320
β = 1 / eps(T)
317321

318-
fk = obj(nlp, xk)
319-
grad!(nlp, xk, ∇fk)
322+
fk = compute_obj ? obj(nlp, xk) : stats.solver_specific[:smooth_obj]
323+
compute_grad && grad!(nlp, xk, ∇fk)
320324
∇fk⁻ .= ∇fk
321325

322326
dk .= D.d

src/TR_alg.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ For advanced usage, first define a solver "TRSolver" to preallocate the memory u
141141
- `opnorm_maxiter::Int = 5`: how many iterations of the power method to use to compute the operator norm of Bₖ. If a negative number is provided, then Arpack is used instead;
142142
- `χ::F = NormLinf(1)`: norm used to define the trust-region;`
143143
- `subsolver::S = R2Solver`: subsolver used to solve the subproblem that appears at each iteration.
144+
- `compute_obj::Bool = true`: (advanced) whether `f(x₀)` should be computed or not. If set to false, then the value is retrieved from `stats.solver_specific[:smooth_obj]`;
145+
- `compute_grad::Bool = true`: (advanced) whether `∇f(x₀)` should be computed or not. If set to false, then the value is retrieved from `solver.∇fk`;
144146
- `sub_kwargs::NamedTuple = NamedTuple()`: a named tuple containing the keyword arguments to be sent to the subsolver. The solver will fail if invalid keyword arguments are provided to the subsolver. For example, if the subsolver is `R2Solver`, you can pass `sub_kwargs = (max_iter = 100, σmin = 1e-6,)`.
145147
146148
The algorithm stops either when `√(ξₖ/νₖ) < atol + rtol*√(ξ₀/ν₀) ` or `ξₖ < 0` and `√(-ξₖ/νₖ) < neg_tol` where ξₖ := f(xₖ) + h(xₖ) - φ(sₖ; xₖ) - ψ(sₖ; xₖ), and √(ξₖ/νₖ) is a stationarity measure.
@@ -213,6 +215,8 @@ function SolverCore.solve!(
213215
γ::T = T(3),
214216
sub_kwargs::NamedTuple = NamedTuple(),
215217
opnorm_maxiter::Int = 5,
218+
compute_obj::Bool = true,
219+
compute_grad::Bool = true,
216220
) where {T, G, V}
217221
reset!(stats)
218222

@@ -286,8 +290,8 @@ function SolverCore.solve!(
286290
α = 1 / eps(T)
287291
β = 1 / eps(T)
288292

289-
fk = obj(nlp, xk)
290-
grad!(nlp, xk, ∇fk)
293+
fk = compute_obj ? obj(nlp, xk) : stats.solver_specific[:smooth_obj]
294+
compute_grad && grad!(nlp, xk, ∇fk)
291295
∇fk⁻ .= ∇fk
292296

293297
quasiNewtTest = isa(nlp, QuasiNewtonModel)

0 commit comments

Comments
 (0)