From 3a5680bc82ae6007a52ff0729d2e342945c0df0e Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Tue, 23 Jul 2024 13:45:00 +0200 Subject: [PATCH 1/7] add Counters --- src/quasi-newton.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/quasi-newton.jl b/src/quasi-newton.jl index 5d11857..a8abdb0 100644 --- a/src/quasi-newton.jl +++ b/src/quasi-newton.jl @@ -17,6 +17,7 @@ mutable struct LBFGSModel{ Op <: LBFGSOperator{T}, } <: QuasiNewtonModel{T, S} meta::Meta + counters::Counters model::M op::Op end @@ -29,6 +30,7 @@ mutable struct LSR1Model{ Op <: LSR1Operator{T}, } <: QuasiNewtonModel{T, S} meta::Meta + counters::Counters model::M op::Op end @@ -41,6 +43,7 @@ mutable struct DiagonalQNModel{ Op <: AbstractDiagonalQuasiNewtonOperator{T}, } <: AbstractDiagonalQNModel{T, S} meta::Meta + counters::Counters model::M op::Op end @@ -48,13 +51,13 @@ end "Construct a `LBFGSModel` from another type of model." function LBFGSModel(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LBFGSOperator(T, nlp.meta.nvar; kwargs...) - return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) + return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) end "Construct a `LSR1Model` from another type of nlp." function LSR1Model(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LSR1Operator(T, nlp.meta.nvar; kwargs...) - return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) + return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters() ,nlp, op) end """ @@ -71,7 +74,7 @@ function DiagonalPSBModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalPSB(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) end """ @@ -88,7 +91,7 @@ function DiagonalAndreiModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalAndrei(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) end """ @@ -102,7 +105,7 @@ for more information about the used algorithms. """ function SpectralGradientModel(nlp::AbstractNLPModel{T, S}; σ::T = one(T)) where {T, S} op = SpectralGradient(σ, nlp.meta.nvar) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) end NLPModels.show_header(io::IO, nlp::QuasiNewtonModel) = From 4a0a9e0a10e6ff439174a59439796c658fdfe65e Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Tue, 23 Jul 2024 13:54:00 +0200 Subject: [PATCH 2/7] update counters --- src/quasi-newton.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/quasi-newton.jl b/src/quasi-newton.jl index a8abdb0..558379c 100644 --- a/src/quasi-newton.jl +++ b/src/quasi-newton.jl @@ -51,13 +51,13 @@ end "Construct a `LBFGSModel` from another type of model." function LBFGSModel(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LBFGSOperator(T, nlp.meta.nvar; kwargs...) - return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) + return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) end "Construct a `LSR1Model` from another type of nlp." function LSR1Model(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LSR1Operator(T, nlp.meta.nvar; kwargs...) - return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters() ,nlp, op) + return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters ,nlp, op) end """ @@ -74,7 +74,7 @@ function DiagonalPSBModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalPSB(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) end """ @@ -91,7 +91,7 @@ function DiagonalAndreiModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalAndrei(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) end """ @@ -105,7 +105,7 @@ for more information about the used algorithms. """ function SpectralGradientModel(nlp::AbstractNLPModel{T, S}; σ::T = one(T)) where {T, S} op = SpectralGradient(σ, nlp.meta.nvar) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, Counters(), nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) end NLPModels.show_header(io::IO, nlp::QuasiNewtonModel) = From 869d7ea623bf143bdabb11677a6438a2bf6ed9a7 Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Tue, 23 Jul 2024 14:06:33 +0200 Subject: [PATCH 3/7] add macro --- src/quasi-newton.jl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/quasi-newton.jl b/src/quasi-newton.jl index 558379c..881c054 100644 --- a/src/quasi-newton.jl +++ b/src/quasi-newton.jl @@ -17,7 +17,6 @@ mutable struct LBFGSModel{ Op <: LBFGSOperator{T}, } <: QuasiNewtonModel{T, S} meta::Meta - counters::Counters model::M op::Op end @@ -30,7 +29,6 @@ mutable struct LSR1Model{ Op <: LSR1Operator{T}, } <: QuasiNewtonModel{T, S} meta::Meta - counters::Counters model::M op::Op end @@ -43,7 +41,6 @@ mutable struct DiagonalQNModel{ Op <: AbstractDiagonalQuasiNewtonOperator{T}, } <: AbstractDiagonalQNModel{T, S} meta::Meta - counters::Counters model::M op::Op end @@ -51,13 +48,13 @@ end "Construct a `LBFGSModel` from another type of model." function LBFGSModel(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LBFGSOperator(T, nlp.meta.nvar; kwargs...) - return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) + return LBFGSModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) end "Construct a `LSR1Model` from another type of nlp." function LSR1Model(nlp::AbstractNLPModel{T, S}; kwargs...) where {T, S} op = LSR1Operator(T, nlp.meta.nvar; kwargs...) - return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters ,nlp, op) + return LSR1Model{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) end """ @@ -74,7 +71,7 @@ function DiagonalPSBModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalPSB(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) end """ @@ -91,7 +88,7 @@ function DiagonalAndreiModel( d0::S = fill!(S(undef, nlp.meta.nvar), one(T)), ) where {T, S} op = DiagonalAndrei(d0) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) end """ @@ -105,7 +102,7 @@ for more information about the used algorithms. """ function SpectralGradientModel(nlp::AbstractNLPModel{T, S}; σ::T = one(T)) where {T, S} op = SpectralGradient(σ, nlp.meta.nvar) - return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp.counters, nlp, op) + return DiagonalQNModel{T, S, typeof(nlp), typeof(nlp.meta), typeof(op)}(nlp.meta, nlp, op) end NLPModels.show_header(io::IO, nlp::QuasiNewtonModel) = @@ -118,6 +115,7 @@ function Base.show(io::IO, nlp::QuasiNewtonModel) end @default_counters QuasiNewtonModel model +@default_counters AbstractDiagonalQNModel model function NLPModels.reset_data!(nlp::QuasiNewtonModel) reset!(nlp.op) From 29f591a6a45e46e97c71e446e8d6bad300955819 Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Tue, 23 Jul 2024 15:00:58 +0200 Subject: [PATCH 4/7] add tests --- test/nlp/quasi-newton.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/nlp/quasi-newton.jl b/test/nlp/quasi-newton.jl index 1e9766d..a78c845 100644 --- a/test/nlp/quasi-newton.jl +++ b/test/nlp/quasi-newton.jl @@ -125,7 +125,8 @@ @test Hop * v ≈ H(x) * v Hop = hess_op!(nlp, x, Hv) @test Hop * v ≈ H(x) * v - + @test nlp.counters == nlp.model.counters + reset_data!(nlp) Hop = hess_op!(nlp, x, Hv) @test Hop * v == v From 3bff157330b36371915e0c1a28269020988bc753 Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Wed, 24 Jul 2024 18:20:01 +0200 Subject: [PATCH 5/7] add getproperty function for counters --- src/quasi-newton.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/quasi-newton.jl b/src/quasi-newton.jl index 881c054..24247dd 100644 --- a/src/quasi-newton.jl +++ b/src/quasi-newton.jl @@ -114,8 +114,15 @@ function Base.show(io::IO, nlp::QuasiNewtonModel) show(io, nlp.model.counters) end +function Base.getproperty(nlp::QuasiNewtonModel, s::Symbol) + if s == :counters + return nlp.model.counters + else + return getfield(nlp, s) + end +end + @default_counters QuasiNewtonModel model -@default_counters AbstractDiagonalQNModel model function NLPModels.reset_data!(nlp::QuasiNewtonModel) reset!(nlp.op) From 9a220e62a279c23cbf56ac60f88a9cdb0e2f68a9 Mon Sep 17 00:00:00 2001 From: MaxenceGollier <134112149+MaxenceGollier@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:48:31 +0200 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Tangi Migot --- src/quasi-newton.jl | 8 -------- test/nlp/quasi-newton.jl | 4 ++++ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/quasi-newton.jl b/src/quasi-newton.jl index 24247dd..5d11857 100644 --- a/src/quasi-newton.jl +++ b/src/quasi-newton.jl @@ -114,14 +114,6 @@ function Base.show(io::IO, nlp::QuasiNewtonModel) show(io, nlp.model.counters) end -function Base.getproperty(nlp::QuasiNewtonModel, s::Symbol) - if s == :counters - return nlp.model.counters - else - return getfield(nlp, s) - end -end - @default_counters QuasiNewtonModel model function NLPModels.reset_data!(nlp::QuasiNewtonModel) diff --git a/test/nlp/quasi-newton.jl b/test/nlp/quasi-newton.jl index a78c845..862d46a 100644 --- a/test/nlp/quasi-newton.jl +++ b/test/nlp/quasi-newton.jl @@ -126,6 +126,10 @@ Hop = hess_op!(nlp, x, Hv) @test Hop * v ≈ H(x) * v @test nlp.counters == nlp.model.counters + @test neval_obj(nlp) == neval_obj(nlp.model) + @test neval_grad(nlp) == neval_grad(nlp.model) + @test neval_hess(nlp) == neval_hess(nlp.model) + @test neval_hprod(nlp) == neval_hprod(nlp.model) reset_data!(nlp) Hop = hess_op!(nlp, x, Hv) From 4e140fb1569cdcd276b4f220ce2220564fb7033c Mon Sep 17 00:00:00 2001 From: MaxenceGollier <134112149+MaxenceGollier@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:34:20 +0000 Subject: [PATCH 7/7] Update test/nlp/quasi-newton.jl Co-authored-by: Dominique --- test/nlp/quasi-newton.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nlp/quasi-newton.jl b/test/nlp/quasi-newton.jl index 862d46a..90ee3f5 100644 --- a/test/nlp/quasi-newton.jl +++ b/test/nlp/quasi-newton.jl @@ -126,7 +126,7 @@ Hop = hess_op!(nlp, x, Hv) @test Hop * v ≈ H(x) * v @test nlp.counters == nlp.model.counters - @test neval_obj(nlp) == neval_obj(nlp.model) + @test neval_obj(nlp) == neval_obj(nlp.model) @test neval_grad(nlp) == neval_grad(nlp.model) @test neval_hess(nlp) == neval_hess(nlp.model) @test neval_hprod(nlp) == neval_hprod(nlp.model)