11module OptimizationMadNLP
22
33using OptimizationBase
4+ using OptimizationBase: MinSense, MaxSense, DEFAULT_CALLBACK
45using MadNLP
56using NLPModels
67using SparseArrays
78
89export MadNLPOptimizer
910
10- struct NLPModelsAdaptor{C, T} <: NLPModels.AbstractNLPModel{T, Vector{T}}
11+ struct NLPModelsAdaptor{C, T, HB } <: NLPModels.AbstractNLPModel{T, Vector{T}}
1112 cache:: C
1213 meta:: NLPModels.NLPModelMeta{T, Vector{T}}
1314 counters:: NLPModels.Counters
@@ -16,7 +17,7 @@ struct NLPModelsAdaptor{C, T} <: NLPModels.AbstractNLPModel{T, Vector{T}}
1617 jac_buffer:: AbstractMatrix{T}
1718 hess_rows:: Vector{Int}
1819 hess_cols:: Vector{Int}
19- hess_buffer:: AbstractMatrix {T}
20+ hess_buffer:: HB # Can be Vector{T} or Matrix {T}
2021end
2122
2223function _enumerate_dense_structure (ncon, nvar)
@@ -79,11 +80,13 @@ function NLPModelsAdaptor(
7980 lower_mask = I .>= J
8081 hess_rows = I[lower_mask]
8182 hess_cols = J[lower_mask]
82- hess_buffer = similar (hess_proto)
83+ # Create a values buffer matching the number of lower triangle elements
84+ hess_buffer = zeros (T, sum (lower_mask))
8385 elseif ! isnothing (hess_proto)
8486 # Dense Hessian
8587 n = size (hess_proto, 1 )
8688 hess_rows, hess_cols = _enumerate_lower_triangle (n)
89+ # For dense, store the full matrix but we'll extract values later
8790 hess_buffer = similar (hess_proto)
8891 else
8992 # No prototype - create dense structure
@@ -92,7 +95,7 @@ function NLPModelsAdaptor(
9295 hess_buffer = zeros (T, n, n)
9396 end
9497
95- return NLPModelsAdaptor {C, T} (cache, meta, counters,
98+ return NLPModelsAdaptor {C, T, typeof(hess_buffer) } (cache, meta, counters,
9699 jac_rows, jac_cols, jac_buffer,
97100 hess_rows, hess_cols, hess_buffer)
98101end
@@ -152,7 +155,13 @@ function NLPModels.hess_coord!(
152155 nlp:: NLPModelsAdaptor , x, y, H:: AbstractVector ; obj_weight = 1.0 )
153156 if ! isnothing (nlp. cache. f. lag_h)
154157 # Use Lagrangian Hessian directly
155- nlp. cache. f. lag_h (nlp. hess_buffer, x, obj_weight, y)
158+ if nlp. hess_buffer isa AbstractVector
159+ # For sparse prototypes, hess_buffer is already a values vector
160+ nlp. cache. f. lag_h (nlp. hess_buffer, x, obj_weight, y)
161+ else
162+ # For dense matrices, we need to pass the full matrix and extract values
163+ nlp. cache. f. lag_h (nlp. hess_buffer, x, obj_weight, y)
164+ end
156165 else
157166 # Manual computation: objective + constraint Hessians
158167 nlp. cache. f. hess (nlp. hess_buffer, x)
@@ -169,9 +178,15 @@ function NLPModels.hess_coord!(
169178 end
170179
171180 if ! isempty (H)
172- # Extract lower triangle values
173- for (idx, (i, j)) in enumerate (zip (nlp. hess_rows, nlp. hess_cols))
174- H[idx] = nlp. hess_buffer[i, j]
181+ # Extract values depending on buffer type
182+ if nlp. hess_buffer isa AbstractVector
183+ # For sparse, hess_buffer already contains just the values
184+ copyto! (H, nlp. hess_buffer)
185+ else
186+ # For dense matrices, extract lower triangle values
187+ for (idx, (i, j)) in enumerate (zip (nlp. hess_rows, nlp. hess_cols))
188+ H[idx] = nlp. hess_buffer[i, j]
189+ end
175190 end
176191 end
177192
@@ -255,11 +270,12 @@ function map_madnlp_status(status::MadNLP.Status)
255270 end
256271end
257272
258- function _get_nnzj (f)
273+ function _get_nnzj (f, ncon, nvar )
259274 jac_prototype = f. cons_jac_prototype
260275
261276 if isnothing (jac_prototype)
262- return 0
277+ # No prototype - assume dense structure if there are constraints
278+ return ncon > 0 ? ncon * nvar : 0
263279 elseif jac_prototype isa SparseMatrixCSC
264280 nnz (jac_prototype)
265281 else
@@ -311,15 +327,15 @@ function __map_optimizer_args(cache,
311327 meta = NLPModels. NLPModelMeta (
312328 nvar;
313329 ncon,
314- nnzj = _get_nnzj (cache. f),
330+ nnzj = _get_nnzj (cache. f, ncon, nvar ),
315331 nnzh = _get_nnzh (cache. f, ncon, nvar),
316332 x0 = cache. u0,
317333 y0 = zeros (eltype (cache. u0), ncon),
318334 lvar,
319335 uvar,
320336 lcon,
321337 ucon,
322- minimize = cache. sense == MinSense
338+ minimize = cache. sense != = MaxSense # Default to minimization when sense is nothing or MinSense
323339 )
324340
325341 nlp = NLPModelsAdaptor (cache, meta, NLPModels. Counters ())
0 commit comments