diff --git a/Project.toml b/Project.toml index f26bc20..195b73a 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843" ADNLPModels = "0.8.13" KNITRO = "1.1.0" LinearAlgebra = "1.10" -NLPModels = "0.21.5" +NLPModels = "0.21.6" NLPModelsModifiers = "0.7" SolverCore = "0.3" Test = "1.10" diff --git a/docs/src/tutorial.md b/docs/src/tutorial.md index c427739..2f249d7 100644 --- a/docs/src/tutorial.md +++ b/docs/src/tutorial.md @@ -200,3 +200,16 @@ contour!(range(18, 60, step=0.1), range(40_000, 180_000, step=1.0), f, levels=[0 ``` ![](assets/ex3.png) + +## Example: Using L-BFGS (limited-memory) Hessian approximation with KNITRO + +You can call KNITRO with the L-BFGS Hessian approximation by passing the following options: + +```julia +stats_knitro = knitro(nlp, + hessopt=6, + lmsize=10) +``` + +This will use the L-BFGS method for Hessian approximation with a history size of 10. +Note that these options are used by default in `NLPModelsKnitro.jl` if `nlp.meta.hess_available` is `false`. diff --git a/src/nlp.jl b/src/nlp.jl index 0d02bd8..ba2c697 100644 --- a/src/nlp.jl +++ b/src/nlp.jl @@ -5,6 +5,7 @@ function KnitroSolver( linear_api::Bool = true, kwargs..., ) + @assert nlp.meta.grad_available && (nlp.meta.ncon == 0 || nlp.meta.jac_available) n, m = nlp.meta.nvar, nlp.meta.ncon kc = KNITRO.KN_new() @@ -91,7 +92,12 @@ function KnitroSolver( else jrows, jcols = jac_structure(nlp) end - hrows, hcols = hess_structure(nlp) + + if nlp.meta.hess_available + hrows, hcols = hess_structure(nlp) + else + hrows, hcols = Int[], Int[] + end # define evaluation callback function evalAll(kc, cb, evalRequest, evalResult, userParams) @@ -175,8 +181,14 @@ function KnitroSolver( hessIndexVars2 = convert(Vector{Int32}, hrows .- 1), ) - # specify that we are able to provide the Hessian without including the objective - KNITRO.KN_set_int_param(kc, KNITRO.KN_PARAM_HESSIAN_NO_F, KNITRO.KN_HESSIAN_NO_F_ALLOW) + # Use L-BFGS if the sparse hessian of the Lagrangian is not available + if !nlp.meta.hess_available + KNITRO.KN_set_int_param_by_name(kc, "hessopt", 6) + KNITRO.KN_set_int_param_by_name(kc, "lmsize", 10) + else + # specify that we are able to provide the Hessian without including the objective + KNITRO.KN_set_int_param(kc, KNITRO.KN_PARAM_HESSIAN_NO_F, KNITRO.KN_HESSIAN_NO_F_ALLOW) + end # pass options to KNITRO for (k, v) in kwargs