526526"""
527527 addinfo!(info, mpc::NonLinMPC) -> info
528528
529- For [`NonLinMPC`](@ref), add `:sol` and the optimal economic cost `:JE`.
529+ For [`NonLinMPC`](@ref), add `:sol`, the custom nonlinear objective `:JE`, the custom
530+ constraint `:gc`, and the various derivatives.
530531"""
531532function addinfo! (info, mpc:: NonLinMPC{NT} ) where NT<: Real
532533 U, Ŷ, D̂, ŷ, d, ϵ = info[:U ], info[:Ŷ ], info[:D̂ ], info[:ŷ ], info[:d ], info[:ϵ ]
@@ -536,9 +537,99 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
536537 JE = mpc. JE (Ue, Ŷe, D̂e, mpc. p)
537538 LHS = Vector {NT} (undef, mpc. con. nc)
538539 mpc. con. gc! (LHS, Ue, Ŷe, D̂e, mpc. p, ϵ)
540+ model, optim = mpc. estim. model, mpc. optim
541+ transcription = mpc. transcription
542+ nu, ny, nx̂, nϵ = model. nu, model. ny, mpc. estim. nx̂, mpc. nϵ
543+ nk = get_nk (model, transcription)
544+ Hp, Hc = mpc. Hp, mpc. Hc
545+ ng = length (mpc. con. i_g)
546+ nc, neq = mpc. con. nc, mpc. con. neq
547+ nU, nŶ, nX̂, nK = mpc. Hp* nu, Hp* ny, Hp* nx̂, Hp* nk
548+ nΔŨ, nUe, nŶe = nu* Hc + nϵ, nU + nu, nŶ + ny
549+ ΔŨ = zeros (NT, nΔŨ)
550+ x̂0end = zeros (NT, nx̂)
551+ K0 = zeros (NT, nK)
552+ Ue, Ŷe = zeros (NT, nUe), zeros (NT, nŶe)
553+ U0, Ŷ0 = zeros (NT, nU), zeros (NT, nŶ)
554+ Û0, X̂0 = zeros (NT, nU), zeros (NT, nX̂)
555+ gc, g = zeros (NT, nc), zeros (NT, ng)
556+ geq = zeros (NT, neq)
557+ J_cache = (
558+ Cache (ΔŨ), Cache (x̂0end), Cache (Ue), Cache (Ŷe), Cache (U0), Cache (Ŷ0),
559+ Cache (Û0), Cache (K0), Cache (X̂0),
560+ Cache (gc), Cache (g), Cache (geq),
561+ )
562+ function J! (Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq)
563+ update_predictions! (ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃)
564+ return obj_nonlinprog! (Ŷ0, U0, mpc, model, Ue, Ŷe, ΔŨ)
565+ end
566+ if ! isnothing (mpc. hessian)
567+ _, ∇J, ∇²J = value_gradient_and_hessian (J!, mpc. hessian, mpc. Z̃, J_cache... )
568+ else
569+ ∇J, ∇²J = gradient (J!, mpc. gradient, mpc. Z̃, J_cache... ), nothing
570+ end
571+ JNT = typeof (mpc. optim). parameters[1 ]
572+ nonlin_constraints = JuMP. all_constraints (
573+ optim, JuMP. Vector{JuMP. VariableRef}, MOI. VectorNonlinearOracle{JNT}
574+ )
575+ g_con, geq_func = nonlin_constraints
576+ λ, λeq = JuMP. dual .(g_con), JuMP. dual .(geq_func)
577+ display (λ)
578+ display (λeq)
579+ g_cache = (
580+ Cache (ΔŨ), Cache (x̂0end), Cache (Ue), Cache (Ŷe), Cache (U0), Cache (Ŷ0),
581+ Cache (Û0), Cache (K0), Cache (X̂0),
582+ Cache (gc), Cache (geq),
583+ )
584+ function g! (g, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, geq)
585+ update_predictions! (ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃)
586+ return nothing
587+ end
588+ ∇g = jacobian (g!, g, mpc. jacobian, mpc. Z̃, g_cache... )
589+ #=
590+ if !isnothing(mpc.hessian)
591+ function ℓ_g(Z̃, λ, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, geq, g)
592+ update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃)
593+ return dot(λ, g)
594+ end
595+ ∇²g_cache = (
596+ Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
597+ Cache(Û0), Cache(K0), Cache(X̂0),
598+ Cache(gc), Cache(geq), Cache(g)
599+ )
600+ ∇²ℓg = hessian(ℓ_g, mpc.hessian, mpc.Z̃, Constant(λ), ∇²g_cache...)
601+ else
602+ ∇²ℓg = nothing
603+ end
604+ =# ∇²ℓg = nothing # TODO : delete this line when enabling the above block
605+ geq_cache = (
606+ Cache (ΔŨ), Cache (x̂0end), Cache (Ue), Cache (Ŷe), Cache (U0), Cache (Ŷ0),
607+ Cache (Û0), Cache (K0), Cache (X̂0),
608+ Cache (gc), Cache (g)
609+ )
610+ function geq! (geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g)
611+ update_predictions! (ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃)
612+ return nothing
613+ end
614+ ∇geq = jacobian (geq!, geq, mpc. jacobian, mpc. Z̃, geq_cache... )
615+ ∇²ℓgeq = nothing # TODO : implement later
616+
539617 info[:JE ] = JE
540618 info[:gc ] = LHS
619+ info[:∇J ] = ∇J
620+ info[:∇²J ] = ∇²J
621+ info[:∇g ] = ∇g
622+ info[:∇²ℓg ] = ∇²ℓg
623+ info[:∇geq ] = ∇geq
624+ info[:∇²ℓgeq ] = ∇²ℓgeq
541625 info[:sol ] = JuMP. solution_summary (mpc. optim, verbose= true )
626+ # --- non-Unicode fields ---
627+ info[:nablaJ ] = ∇J
628+ info[:nabla2J ] = ∇²J
629+ info[:nablag ] = ∇g
630+ info[:nabla2lg ] = ∇²ℓg
631+ info[:nablageq ] = ∇geq
632+ info[:nabla2lgeq ] = ∇²ℓgeq
542633 return info
543634end
544635
0 commit comments