From ab827406a1d62281008be5e314082f368af3e4ef Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Sun, 18 Aug 2024 02:19:43 -0400 Subject: [PATCH 1/7] Add jth_hess_coord, jth_hprod and ghjvprod --- src/moi_nlp_model.jl | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index 190eab5..aabee1f 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -349,6 +349,38 @@ function NLPModels.hess_coord!( return vals end +function NLPModels.jth_hess_coord!( + nlp::MathOptNLPModel, + x::AbstractVector, + j::Integer, + vals::AbstractVector, +) + increment!(nlp, :neval_jhess) + vals .= 0.0 + if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad + index = nlp.obj.nnzh + for i = 1:(nlp.quadcon.nquad) + qcon = nlp.quadcon.constraints[i] + if j == nlp.meta.nlin + i + view(vals, (index + 1):(index + qcon.nnzh)) .= qcon.A.vals + end + index += qcon.nnzh + end + end + if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 + MOI.eval_hessian_lagrangian( + nlp.eval, + view(vals, (nlp.obj.nnzh + nlp.quadcon.nnzh + 1):(nlp.meta.nnzh)), + x, + 0.0, + λ, + ) + nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 + end + return vals +end + function NLPModels.hprod!( nlp::MathOptNLPModel, x::AbstractVector, @@ -413,3 +445,48 @@ function NLPModels.hprod!( end return hv end + +function NLPModels.jth_hprod!( + nlp::MathOptNLPModel, + x::AbstractVector, + v::AbstractVector, + j::Integer, + hv::AbstractVector, +) + increment!(nlp, :neval_jhprod) + hv .= 0.0 + if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad + qcon = nlp.quadcon.constraints[j - nlp.meta.nlin] + coo_sym_add_mul!(qcon.A.rows, qcon.A.cols, qcon.A.vals, v, hv, 1.0) + end + if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 + MOI.eval_hessian_lagrangian_product(nlp.eval, hv, x, v, 0.0, nlp.λ) + nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 + end + return hv +end + +function NLPModels.ghjvprod!( + nlp::MathOptNLPModel, + x::AbstractVector, + g::AbstractVector, + v::AbstractVector, + ghv::AbstractVector, +) + # Don't we have a counter :neval_ghjvprod? + ghv .= 0.0 + for i in nlp.meta.nlin + 1 : nlp.meta.nlin + nlp.quadcon.nquad + qcon = nlp.quadcon.constraints[i - nlp.meta.nlin] + ghv[i] = coo_sym_dot(qcon.A.rows, qcon.A.cols, qcon.A.vals, g, v) + end + if nlp.meta.nnln > 0 + # we could store hv in the MathOptNLPModel + hv = zeros(Float64, nlp.meta.nvar) + for i in nlp.meta.nlin + nlp.quadcon.nquad + 1 : nlp.meta.ncon + jth_hprod!(nlp, x, v, i, hv) + ghv[i] = dot(g, hv) + end + end + return ghv +end From 359a27752fbea4c54e32e2d9dff904c2e2903a27 Mon Sep 17 00:00:00 2001 From: Alexis Montoison <35051714+amontoison@users.noreply.github.com> Date: Mon, 19 Aug 2024 08:35:50 -0400 Subject: [PATCH 2/7] Apply suggestions from code review Co-authored-by: Tangi Migot --- src/moi_nlp_model.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index aabee1f..b885e16 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -356,6 +356,7 @@ function NLPModels.jth_hess_coord!( vals::AbstractVector, ) increment!(nlp, :neval_jhess) + @rangecheck 1 nlp.meta.ncon j vals .= 0.0 if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad index = nlp.obj.nnzh @@ -366,8 +367,7 @@ function NLPModels.jth_hess_coord!( end index += qcon.nnzh end - end - if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + else nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian( nlp.eval, @@ -454,12 +454,12 @@ function NLPModels.jth_hprod!( hv::AbstractVector, ) increment!(nlp, :neval_jhprod) + @rangecheck 1 nlp.meta.ncon j hv .= 0.0 if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad qcon = nlp.quadcon.constraints[j - nlp.meta.nlin] coo_sym_add_mul!(qcon.A.rows, qcon.A.cols, qcon.A.vals, v, hv, 1.0) - end - if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + else nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian_product(nlp.eval, hv, x, v, 0.0, nlp.λ) nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 @@ -474,7 +474,7 @@ function NLPModels.ghjvprod!( v::AbstractVector, ghv::AbstractVector, ) - # Don't we have a counter :neval_ghjvprod? + increment!(nlp, :neval_hprod) ghv .= 0.0 for i in nlp.meta.nlin + 1 : nlp.meta.nlin + nlp.quadcon.nquad qcon = nlp.quadcon.constraints[i - nlp.meta.nlin] From fae40c8868dbd83851ce628e732edae7c5218ccf Mon Sep 17 00:00:00 2001 From: Alexis Montoison <35051714+amontoison@users.noreply.github.com> Date: Mon, 19 Aug 2024 08:39:54 -0400 Subject: [PATCH 3/7] Update nlp_consistency.jl --- test/nlp_consistency.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nlp_consistency.jl b/test/nlp_consistency.jl index a2f034f..9f57b8e 100644 --- a/test/nlp_consistency.jl +++ b/test/nlp_consistency.jl @@ -4,7 +4,7 @@ for problem in nlp_problems problem_f = eval(Symbol(lowercase(problem))) nlp_moi = MathOptNLPModel(problem_f()) nlps = [nlp_manual; nlp_moi] - consistent_nlps(nlps, linear_api = true, test_slack = false) + consistent_nlps(nlps, linear_api = true, test_slack = false, exclude = []) view_subarray_nlp(nlp_moi) end end From b2ba20309a8bdddbe9e8cbceb9c835a10527de88 Mon Sep 17 00:00:00 2001 From: Alexis Montoison <35051714+amontoison@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:55:54 -0400 Subject: [PATCH 4/7] Update src/moi_nlp_model.jl --- src/moi_nlp_model.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index b885e16..3e2e485 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -374,7 +374,7 @@ function NLPModels.jth_hess_coord!( view(vals, (nlp.obj.nnzh + nlp.quadcon.nnzh + 1):(nlp.meta.nnzh)), x, 0.0, - λ, + nlp.λ, ) nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 end From 0392b06ea0602b38f0f6bd3c468a4b789f083e81 Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Mon, 19 Aug 2024 14:26:26 -0400 Subject: [PATCH 5/7] Update moi_nlp_model.jl --- src/moi_nlp_model.jl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index 3e2e485..3a8ab60 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -7,6 +7,7 @@ mutable struct MathOptNLPModel <: AbstractNLPModel{Float64, Vector{Float64}} quadcon::QuadraticConstraints nlcon::NonLinearStructure λ::Vector{Float64} + hv::Vector{Float64} obj::Objective counters::Counters end @@ -34,7 +35,8 @@ function nlp_model(moimodel::MOI.ModelLike; hessian::Bool = true, name::String = nlp_data = _nlp_block(moimodel) nnln, nlcon, nl_lcon, nl_ucon = parser_NL(nlp_data, hessian = hessian) - λ = zeros(nnln) # Lagrange multipliers for hess_coord! and hprod! without y + λ = zeros(Float64, nnln) # Lagrange multipliers for hess_coord! and hprod! without y + hv = zeros(Float64, nvar) # workspace for ghjvprod! if nlp_data.has_objective obj = Objective("NONLINEAR", 0.0, spzeros(Float64, nvar), COO(), 0) @@ -67,7 +69,7 @@ function nlp_model(moimodel::MOI.ModelLike; hessian::Bool = true, name::String = name = name, ) - return MathOptNLPModel(meta, nlp_data.evaluator, lincon, quadcon, nlcon, λ, obj, Counters()), + return MathOptNLPModel(meta, nlp_data.evaluator, lincon, quadcon, nlcon, λ, hv, obj, Counters()), index_map end @@ -367,7 +369,8 @@ function NLPModels.jth_hess_coord!( end index += qcon.nnzh end - else + end + if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian( nlp.eval, @@ -459,7 +462,8 @@ function NLPModels.jth_hprod!( if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad qcon = nlp.quadcon.constraints[j - nlp.meta.nlin] coo_sym_add_mul!(qcon.A.rows, qcon.A.cols, qcon.A.vals, v, hv, 1.0) - else + end + if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian_product(nlp.eval, hv, x, v, 0.0, nlp.λ) nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 @@ -480,13 +484,9 @@ function NLPModels.ghjvprod!( qcon = nlp.quadcon.constraints[i - nlp.meta.nlin] ghv[i] = coo_sym_dot(qcon.A.rows, qcon.A.cols, qcon.A.vals, g, v) end - if nlp.meta.nnln > 0 - # we could store hv in the MathOptNLPModel - hv = zeros(Float64, nlp.meta.nvar) - for i in nlp.meta.nlin + nlp.quadcon.nquad + 1 : nlp.meta.ncon - jth_hprod!(nlp, x, v, i, hv) - ghv[i] = dot(g, hv) - end + for i in nlp.meta.nlin + nlp.quadcon.nquad + 1 : nlp.meta.ncon + jth_hprod!(nlp, x, v, i, nlp.hv) + ghv[i] = dot(g, nlp.hv) end return ghv end From 996780c4e2a9cd03d332ebb1f8e2bf8892847b1f Mon Sep 17 00:00:00 2001 From: Alexis Montoison Date: Wed, 21 Aug 2024 18:35:33 -0400 Subject: [PATCH 6/7] Use elseif in ghjvprod and jth_hess_coord --- src/moi_nlp_model.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index 3a8ab60..bf5314a 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -369,8 +369,7 @@ function NLPModels.jth_hess_coord!( end index += qcon.nnzh end - end - if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + elseif nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian( nlp.eval, @@ -462,8 +461,7 @@ function NLPModels.jth_hprod!( if nlp.meta.nlin + 1 ≤ j ≤ nlp.meta.nlin + nlp.quadcon.nquad qcon = nlp.quadcon.constraints[j - nlp.meta.nlin] coo_sym_add_mul!(qcon.A.rows, qcon.A.cols, qcon.A.vals, v, hv, 1.0) - end - if nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon + elseif nlp.meta.nlin + nlp.quadcon.nquad + 1 ≤ j ≤ nlp.meta.ncon nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 1.0 MOI.eval_hessian_lagrangian_product(nlp.eval, hv, x, v, 0.0, nlp.λ) nlp.λ[j - nlp.meta.nlin - nlp.quadcon.nquad] = 0.0 From 50df29861d40ff4075aa9855384c811c47954a97 Mon Sep 17 00:00:00 2001 From: Alexis Montoison <35051714+amontoison@users.noreply.github.com> Date: Sun, 1 Sep 2024 11:52:01 -0400 Subject: [PATCH 7/7] Update src/moi_nlp_model.jl Co-authored-by: Tangi Migot --- src/moi_nlp_model.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/moi_nlp_model.jl b/src/moi_nlp_model.jl index bf5314a..08fe501 100644 --- a/src/moi_nlp_model.jl +++ b/src/moi_nlp_model.jl @@ -484,6 +484,7 @@ function NLPModels.ghjvprod!( end for i in nlp.meta.nlin + nlp.quadcon.nquad + 1 : nlp.meta.ncon jth_hprod!(nlp, x, v, i, nlp.hv) + decrement!(nlp, :neval_jhprod) ghv[i] = dot(g, nlp.hv) end return ghv