Skip to content

Commit f8a256d

Browse files
committed
Introduce getters for components of a QuasiNewtonModel
Without those getters, certain operations in NLPModelstests (e.g., the derivative checker) fail for user-defined quasi-Newton models whose fields have names other than "model" or "op".
1 parent 622b9c3 commit f8a256d

2 files changed

Lines changed: 50 additions & 19 deletions

File tree

src/quasi-newton.jl

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,31 @@ export AbstractDiagonalQNModel,
44
LSR1Model,
55
DiagonalPSBModel,
66
DiagonalAndreiModel,
7-
SpectralGradientModel
7+
SpectralGradientModel,
8+
get_model,
9+
get_op
810

911
abstract type QuasiNewtonModel{T, S} <: AbstractNLPModel{T, S} end
1012
abstract type AbstractDiagonalQNModel{T, S} <: QuasiNewtonModel{T, S} end
1113

14+
"""
15+
get_model(nlp::QuasiNewtonModel)
16+
17+
Return the underlying model of a `QuasiNewtonModel`.
18+
"""
19+
function get_model(nlp::QuasiNewtonModel)
20+
error("get_model is not implemented for $(typeof(nlp)).")
21+
end
22+
23+
"""
24+
get_op(nlp::QuasiNewtonModel)
25+
26+
Return the quasi-Newton operator of a `QuasiNewtonModel`.
27+
"""
28+
function get_op(nlp::QuasiNewtonModel)
29+
error("get_op is not implemented for $(typeof(nlp)).")
30+
end
31+
1232
mutable struct LBFGSModel{
1333
T,
1434
S,
@@ -22,6 +42,10 @@ mutable struct LBFGSModel{
2242
v::S # extra vector to compute and store yₖ = ∇fₖ₊₁ - ∇fₖ
2343
end
2444

45+
get_model(nlp::LBFGSModel) = nlp.model
46+
get_op(nlp::LBFGSModel) = nlp.op
47+
@default_counters LBFGSModel model
48+
2549
mutable struct LSR1Model{
2650
T,
2751
S,
@@ -35,6 +59,10 @@ mutable struct LSR1Model{
3559
v::S # extra vector to compute and store yₖ = ∇fₖ₊₁ - ∇fₖ
3660
end
3761

62+
get_model(nlp::LSR1Model) = nlp.model
63+
get_op(nlp::LSR1Model) = nlp.op
64+
@default_counters LSR1Model model
65+
3866
mutable struct DiagonalQNModel{
3967
T,
4068
S,
@@ -47,6 +75,10 @@ mutable struct DiagonalQNModel{
4775
op::Op
4876
end
4977

78+
get_model(nlp::DiagonalQNModel) = nlp.model
79+
get_op(nlp::DiagonalQNModel) = nlp.op
80+
@default_counters DiagonalQNModel model
81+
5082
"Construct a `LBFGSModel` from another type of model."
5183
function LBFGSModel(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S}
5284
op = LBFGSOperator(T, nlp.meta.nvar; kwargs...)
@@ -115,13 +147,11 @@ NLPModels.show_header(io::IO, nlp::QuasiNewtonModel) =
115147
function Base.show(io::IO, nlp::QuasiNewtonModel)
116148
show_header(io, nlp)
117149
show(io, nlp.meta)
118-
show(io, nlp.model.counters)
150+
show(io, get_model(nlp).counters)
119151
end
120152

121-
@default_counters QuasiNewtonModel model
122-
123153
function NLPModels.reset_data!(nlp::QuasiNewtonModel)
124-
reset!(nlp.op)
154+
reset!(get_op(nlp))
125155
return nlp
126156
end
127157

@@ -139,7 +169,7 @@ for meth in (
139169
:jac_lin,
140170
:jac_nln,
141171
)
142-
@eval NLPModels.$meth(nlp::QuasiNewtonModel, x::AbstractVector) = $meth(nlp.model, x)
172+
@eval NLPModels.$meth(nlp::QuasiNewtonModel, x::AbstractVector) = $meth(get_model(nlp), x)
143173
end
144174
for meth in (
145175
:grad!,
@@ -159,35 +189,36 @@ for meth in (
159189
:jac_nln_coord!,
160190
)
161191
@eval NLPModels.$meth(nlp::QuasiNewtonModel, x::AbstractVector, y::AbstractVector) =
162-
$meth(nlp.model, x, y)
192+
$meth(get_model(nlp), x, y)
163193
end
164194
for meth in (:jprod!, :jprod_lin!, :jprod_nln!, :jtprod!, :jtprod_lin!, :jtprod_nln!)
165195
@eval NLPModels.$meth(
166196
nlp::QuasiNewtonModel,
167197
x::AbstractVector,
168198
y::AbstractVector,
169199
z::AbstractVector,
170-
) = $meth(nlp.model, x, y, z)
200+
) = $meth(get_model(nlp), x, y, z)
171201
end
172202
NLPModels.jac_structure!(
173203
nlp::QuasiNewtonModel,
174204
rows::AbstractVector{<:Integer},
175205
cols::AbstractVector{<:Integer},
176-
) = jac_structure!(nlp.model, rows, cols)
206+
) = jac_structure!(get_model(nlp), rows, cols)
177207
NLPModels.jac_lin_structure!(
178208
nlp::QuasiNewtonModel,
179209
rows::AbstractVector{<:Integer},
180210
cols::AbstractVector{<:Integer},
181-
) = jac_lin_structure!(nlp.model, rows, cols)
211+
) = jac_lin_structure!(get_model(nlp), rows, cols)
182212
NLPModels.jac_nln_structure!(
183213
nlp::QuasiNewtonModel,
184214
rows::AbstractVector{<:Integer},
185215
cols::AbstractVector{<:Integer},
186-
) = jac_nln_structure!(nlp.model, rows, cols)
216+
) = jac_nln_structure!(get_model(nlp), rows, cols)
187217

188218
# the following methods are affected by the Hessian approximation
189-
NLPModels.hess_op(nlp::QuasiNewtonModel, x::AbstractVector; kwargs...) = nlp.op
190-
NLPModels.hprod(nlp::QuasiNewtonModel, x::AbstractVector, v::AbstractVector; kwargs...) = nlp.op * v
219+
NLPModels.hess_op(nlp::QuasiNewtonModel, x::AbstractVector; kwargs...) = get_op(nlp)
220+
NLPModels.hprod(nlp::QuasiNewtonModel, x::AbstractVector, v::AbstractVector; kwargs...) =
221+
get_op(nlp) * v
191222

192223
function NLPModels.hprod!(
193224
nlp::QuasiNewtonModel,
@@ -207,16 +238,16 @@ function NLPModels.hprod!(
207238
kwargs...,
208239
)
209240
@lencheck nlp.meta.nvar Hv x v
210-
mul!(Hv, nlp.op, v)
241+
mul!(Hv, get_op(nlp), v)
211242
return Hv
212243
end
213244

214-
NLPModels.neval_hprod(nlp::LBFGSModel) = nlp.op.nprod
215-
NLPModels.neval_hprod(nlp::LSR1Model) = nlp.op.nprod
216-
NLPModels.neval_hprod(nlp::DiagonalQNModel) = nlp.op.nprod
245+
NLPModels.neval_hprod(nlp::LBFGSModel) = get_op(nlp).nprod
246+
NLPModels.neval_hprod(nlp::LSR1Model) = get_op(nlp).nprod
247+
NLPModels.neval_hprod(nlp::DiagonalQNModel) = get_op(nlp).nprod
217248

218249
function Base.push!(nlp::QuasiNewtonModel, args...)
219-
push!(nlp.op, args...)
250+
push!(get_op(nlp), args...)
220251
return nlp
221252
end
222253

test/nlp/quasi-newton.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
@test obj(nlp, x) f(x)
5050
@test grad(nlp, x) ∇f(x)
5151
@test hprod(nlp, x, v) H(x) * v
52-
@test neval_hprod(nlp.model) == 0
52+
@test neval_hprod(get_model(nlp)) == 0
5353
(QNM == LSR1Model) ? (@test neval_hprod(nlp) == 2) : (@test neval_hprod(nlp) == 1)
5454
@test cons(nlp, x) c(x)
5555
@test jac(nlp, x) J(x)

0 commit comments

Comments
 (0)