-
Notifications
You must be signed in to change notification settings - Fork 58
Open
Description
See this discussion: JuliaControl/ModelPredictiveControl.jl#275
Currently we recreate the problem if things are modified:
Ipopt.jl/ext/IpoptMathOptInterfaceExt/MOI_wrapper.jl
Lines 1204 to 1288 in 3a7aed2
| function _setup_model(model::Optimizer) | |
| vars = MOI.get(model.variables, MOI.ListOfVariableIndices()) | |
| if isempty(vars) | |
| # Don't attempt to create a problem because Ipopt will error. | |
| model.invalid_model = true | |
| return | |
| end | |
| if model.nlp_model !== nothing | |
| model.nlp_data = MOI.NLPBlockData( | |
| MOI.Nonlinear.Evaluator(model.nlp_model, model.ad_backend, vars), | |
| ) | |
| end | |
| has_quadratic_constraints = | |
| any(isequal(_kFunctionTypeScalarQuadratic), model.qp_data.function_type) | |
| has_nlp_constraints = | |
| !isempty(model.nlp_data.constraint_bounds) || | |
| !isempty(model.vector_nonlinear_oracle_constraints) | |
| has_hessian = :Hess in MOI.features_available(model.nlp_data.evaluator) | |
| for (_, s) in model.vector_nonlinear_oracle_constraints | |
| if s.set.eval_hessian_lagrangian === nothing | |
| has_hessian = false | |
| break | |
| end | |
| end | |
| init_feat = [:Grad] | |
| if has_hessian | |
| push!(init_feat, :Hess) | |
| end | |
| if has_nlp_constraints | |
| push!(init_feat, :Jac) | |
| end | |
| MOI.initialize(model.nlp_data.evaluator, init_feat) | |
| jacobian_sparsity = MOI.jacobian_structure(model) | |
| hessian_sparsity = if has_hessian | |
| MOI.hessian_lagrangian_structure(model) | |
| else | |
| Tuple{Int,Int}[] | |
| end | |
| eval_f_cb(x) = MOI.eval_objective(model, x) | |
| eval_grad_f_cb(x, grad_f) = MOI.eval_objective_gradient(model, grad_f, x) | |
| eval_g_cb(x, g) = MOI.eval_constraint(model, g, x) | |
| function eval_jac_g_cb(x, rows, cols, values) | |
| if values === nothing | |
| for i in 1:length(jacobian_sparsity) | |
| rows[i], cols[i] = jacobian_sparsity[i] | |
| end | |
| else | |
| MOI.eval_constraint_jacobian(model, values, x) | |
| end | |
| return | |
| end | |
| function eval_h_cb(x, rows, cols, obj_factor, lambda, values) | |
| if values === nothing | |
| for i in 1:length(hessian_sparsity) | |
| rows[i], cols[i] = hessian_sparsity[i] | |
| end | |
| else | |
| MOI.eval_hessian_lagrangian(model, values, x, obj_factor, lambda) | |
| end | |
| return | |
| end | |
| g_L, g_U = copy(model.qp_data.g_L), copy(model.qp_data.g_U) | |
| for (_, s) in model.vector_nonlinear_oracle_constraints | |
| append!(g_L, s.set.l) | |
| append!(g_U, s.set.u) | |
| end | |
| for bound in model.nlp_data.constraint_bounds | |
| push!(g_L, bound.lower) | |
| push!(g_U, bound.upper) | |
| end | |
| model.inner = Ipopt.CreateIpoptProblem( | |
| length(vars), | |
| model.variables.lower, | |
| model.variables.upper, | |
| length(g_L), | |
| g_L, | |
| g_U, | |
| length(jacobian_sparsity), | |
| length(hessian_sparsity), | |
| eval_f_cb, | |
| eval_g_cb, | |
| eval_grad_f_cb, | |
| eval_jac_g_cb, | |
| has_hessian ? eval_h_cb : nothing, | |
| ) |
but we need to re-initialize the AD engine only if the scalar nonlinear stuff has changed. We could skip most of _setup_model and just call a new CreateIpoptProblem with the new bounds.
amontoisonfranckgaga
Metadata
Metadata
Assignees
Labels
No labels