Skip to content

Commit 4ea21f2

Browse files
committed
changed: exclude Infs in inequality constraints of getinfo and NonLinMPC
1 parent 4be6029 commit 4ea21f2

3 files changed

Lines changed: 23 additions & 21 deletions

File tree

src/controller/execute.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ Lastly, the following fields are also available for [`NonLinMPC`](@ref) only:
122122
- `:∇geq` or *`:nablageq`* : optimal Jacobian of the equality constraint, ``\mathbf{\nabla g_{eq}}``
123123
- `:∇²ℓgeq` or *`:nabla2lgeq`* : optimal Hessian of the equality Lagrangian, ``\mathbf{\nabla^2}\ell_{\mathbf{g_{eq}}}``
124124
125+
Note that the inequality constraint vectors and matrices only include the non-`Inf` values.
126+
125127
# Examples
126128
```jldoctest
127129
julia> mpc = LinMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1, Hc=1);

src/controller/nonlinmpc.jl

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -566,18 +566,19 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
566566
nu, ny, nx̂, nϵ = model.nu, model.ny, mpc.estim.nx̂, mpc.
567567
nk = get_nk(model, transcription)
568568
Hp, Hc = mpc.Hp, mpc.Hc
569-
ng = length(con.i_g)
569+
i_g = findall(mpc.con.i_g) # convert to non-logical indices for non-allocating @views
570+
ng, ngi = length(mpc.con.i_g), sum(mpc.con.i_g)
570571
nc, neq = con.nc, con.neq
571572
nU, nŶ, nX̂, nK = mpc.Hp*nu, Hp*ny, Hp*nx̂, Hp*nk
572573
nΔŨ, nUe, nŶe = nu*Hc + nϵ, nU + nu, nŶ + ny
573574
ΔŨ = zeros(NT, nΔŨ)
574575
x̂0end = zeros(NT, nx̂)
575576
K = zeros(NT, nK)
576-
Ue, Ŷe = zeros(NT, nUe), zeros(NT, nŶe)
577-
U0, Ŷ0 = zeros(NT, nU), zeros(NT, nŶ)
578-
Û0, X̂0 = zeros(NT, nU), zeros(NT, nX̂)
579-
gc, g = zeros(NT, nc), zeros(NT, ng)
580-
geq = zeros(NT, neq)
577+
Ue, Ŷe = zeros(NT, nUe), zeros(NT, nŶe)
578+
U0, Ŷ0 = zeros(NT, nU), zeros(NT, nŶ)
579+
Û0, X̂0 = zeros(NT, nU), zeros(NT, nX̂)
580+
gc, g = zeros(NT, nc), zeros(NT, ng)
581+
gi, geq = zeros(NT, ngi), zeros(NT, neq)
581582
J_cache = (
582583
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
583584
Cache(Û0), Cache(K), Cache(X̂0),
@@ -593,19 +594,18 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
593594
∇J, ∇²J = gradient(J!, mpc.gradient, mpc.Z̃, J_cache...), nothing
594595
end
595596
# --- inequality constraint derivatives ---
596-
old_i_g = copy(con.i_g)
597-
con.i_g .= 1 # temporarily set all constraints as finite so g is entirely computed
598597
∇g_cache = (
599598
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
600599
Cache(Û0), Cache(K), Cache(X̂0),
601-
Cache(gc), Cache(geq),
600+
Cache(gc), Cache(geq), Cache(g)
602601
)
603-
function g!(g, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq)
602+
function gi!(gi, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g)
604603
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
604+
gi .= @views g[i_g]
605605
return nothing
606606
end
607-
g, ∇g = value_and_jacobian(g!, g, mpc.jacobian, mpc.Z̃, ∇g_cache...)
608-
if !isnothing(mpc.hessian) && any(old_i_g)
607+
g, ∇g = value_and_jacobian(gi!, gi, mpc.jacobian, mpc.Z̃, ∇g_cache...)
608+
if !isnothing(mpc.hessian) && ngi > 0
609609
nonlincon = optim[:nonlinconstraint]
610610
λi = try
611611
JuMP.get_attribute(nonlincon, MOI.LagrangeMultiplier())
@@ -615,27 +615,25 @@ function addinfo!(info, mpc::NonLinMPC{NT}) where NT<:Real
615615
"The optimizer does not support retrieving optimal Hessian of the Lagrangian.\n"*
616616
"Its nonzero coefficients will be random values.", maxlog=1
617617
)
618-
rand(sum(old_i_g))
618+
rand(ngi)
619619
else
620620
rethrow()
621621
end
622622
end
623-
λ = zeros(NT, ng)
624-
λ[old_i_g] = λi
625-
∇²g_cache = (
623+
∇²gi_cache = (
626624
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),
627625
Cache(Û0), Cache(K), Cache(X̂0),
628-
Cache(gc), Cache(geq), Cache(g)
626+
Cache(gc), Cache(geq), Cache(g), Cache(gi)
629627
)
630-
function ℓ_g(Z̃, λ, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g)
628+
function ℓ_gi(Z̃, λi, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, geq, g, gi)
631629
update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K, X̂0, gc, g, geq, mpc, Z̃)
632-
return dot(λ, g)
630+
gi .= @views g[i_g]
631+
return dot(λi, gi)
633632
end
634-
∇²ℓg = hessian(ℓ_g, mpc.hessian, mpc.Z̃, Constant(λ), ∇²g_cache...)
633+
∇²ℓg = hessian(ℓ_gi, mpc.hessian, mpc.Z̃, Constant(λi), ∇²gi_cache...)
635634
else
636635
∇²ℓg = nothing
637636
end
638-
con.i_g .= old_i_g # restore original finite/infinite constraint indices
639637
# --- equality constraint derivatives ---
640638
geq_cache = (
641639
Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0),

src/estimator/mhe/execute.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ For [`NonLinModel`](@ref), it also includes the following fields:
102102
- `:∇g` or *`:nablag`* : optimal Jacobian of the inequality constraint, ``\mathbf{\nabla g}``
103103
- `:∇²ℓg` or *`:nabla2lg`* : optimal Hessian of the inequality Lagrangian, ``\mathbf{\nabla^2}\ell_{\mathbf{g}}``
104104
105+
Note that the inequality constraint vectors and matrices only include the non-`Inf` values.
106+
105107
# Examples
106108
```jldoctest
107109
julia> model = LinModel(ss(1.0, 1.0, 1.0, 0, 5.0));

0 commit comments

Comments
 (0)