diff --git a/README.md b/README.md index 930fe50f..1368a61b 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,10 @@ Attribute | Type | Notes `jfree` | `Vector{Int}` | indices of "free" constraints (there shouldn't be any) `jinf` | `Vector{Int}` | indices of the visibly infeasible constraints `nnzo` | `Int ` | number of nonzeros in the gradient -`nnzj` | `Int ` | number of nonzeros in the sparse Jacobian `nnzh` | `Int ` | number of nonzeros in the sparse Hessian +`nnzj` | `Int ` | number of nonzeros in the sparse Jacobian +`lin_nnzj` | `Int ` | number of nonzeros in the linear part of sparse Jacobian +`nln_nnzj` | `Int ` | number of nonzeros in the nonlinear part of sparse Jacobian `minimize` | `Bool ` | true if `optimize == minimize` `islp` | `Bool ` | true if the problem is a linear program `name` | `String` | problem name diff --git a/src/nlp/api.jl b/src/nlp/api.jl index 4ba6bc60..46812e8e 100644 --- a/src/nlp/api.jl +++ b/src/nlp/api.jl @@ -1344,6 +1344,30 @@ function hess_op!( return LinearOperator{T}(nlp.meta.nvar, nlp.meta.nvar, true, true, prod!, prod!, prod!) end +""" + varscale(model::AbstractNLPModel) + +Return a vector containing the scaling factors for each variable in the model. +This is typically used to normalize variables for numerical stability in solvers. + +By default, the scaling is model-dependent. If not overridden by the model, a vector of ones +is returned. Inspired by the AMPL scaling conventions. +""" function varscale end + +""" + lagscale(model::AbstractNLPModel) + +Return a vector of scaling factors for the Lagrange multipliers associated with constraints. +This can be used to improve numerical stability or condition number when solving KKT systems. +""" function lagscale end + +""" + conscale(model::AbstractNLPModel) + +Return a vector of constraint scaling factors for the model. +These are typically used to normalize constraints to have similar magnitudes and improve +convergence behavior in nonlinear solvers. +""" function conscale end diff --git a/src/nlp/show.jl b/src/nlp/show.jl index 7970e4be..ecc6f8c7 100644 --- a/src/nlp/show.jl +++ b/src/nlp/show.jl @@ -68,7 +68,7 @@ end Describe `meta` for the `show` function. """ -function lines_of_description(m::AbstractNLPModelMeta) +function lines_of_description(m::M) where {M <: AbstractNLPModelMeta} V = [ length(m.ifree), length(m.ilow), @@ -93,8 +93,22 @@ function lines_of_description(m::AbstractNLPModelMeta) V = [sum(V); V] S = ["All constraints", "free", "lower", "upper", "low/upp", "fixed", "infeas"] conlines = lines_of_hist(S, V) - push!(conlines, histline("linear", m.nlin, m.ncon), histline("nonlinear", m.nnln, m.ncon)) - push!(conlines, sparsityline("nnzj", m.nnzj, m.nvar * m.ncon)) + + append!( + conlines, + [ + histline("linear", m.nlin, m.ncon), + histline("nonlinear", m.nnln, m.ncon), + sparsityline("nnzj", m.nnzj, m.nvar * m.ncon), + ], + ) + + if :lin_nnzj in fieldnames(M) + push!(conlines, sparsityline("lin_nnzj", m.lin_nnzj, m.nlin * m.nvar)) + end + if :nln_nnzj in fieldnames(M) + push!(conlines, sparsityline("nln_nnzj", m.nln_nnzj, m.nnln * m.nvar)) + end append!(varlines, repeat([" "^length(varlines[1])], length(conlines) - length(varlines))) lines = varlines .* conlines diff --git a/test/nlp/show.jl b/test/nlp/show.jl index 9ce7e6f3..281b9614 100644 --- a/test/nlp/show.jl +++ b/test/nlp/show.jl @@ -16,6 +16,8 @@ nnzh: ( 33.33% sparsity) 2 linear: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 nonlinear: ██████████⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 1 nnzj: ( 0.00% sparsity) 4 + lin_nnzj: ( 0.00% sparsity) 2 + nln_nnzj: ( 0.00% sparsity) 2 Counters: obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 grad: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 cons: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 @@ -39,7 +41,9 @@ fixed: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 fixed: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 nnzh: ( 0.00% sparsity) 1 linear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 - nonlinear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 - nnzj: (------% sparsity)\n\n""" + nonlinear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 + nnzj: (------% sparsity) + lin_nnzj: (------% sparsity) + nln_nnzj: (------% sparsity)\n\n""" @test strip.(split(chomp(showed), "\n")) == strip.(split(chomp(expected), "\n")) end diff --git a/test/nls/show.jl b/test/nls/show.jl index 62766237..6f25aaab 100644 --- a/test/nls/show.jl +++ b/test/nls/show.jl @@ -16,6 +16,8 @@ nnzh: ( 0.00% sparsity) 3 linear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 nonlinear: ████████████████████ 3 nnzj: ( 0.00% sparsity) 6 + lin_nnzj: (------% sparsity) + nln_nnzj: ( 0.00% sparsity) 6 Counters: obj: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 grad: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 cons: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0