@@ -606,15 +606,15 @@ function setnonlincon!(
606606) where JNT<: Real
607607 optim, con = estim. optim, estim. con
608608 Z̃var = optim[:Z̃var ]
609- nonlin_constraints = all_constraints (optim, NonlinearExpr, MOI. LessThan{JNT})
610- map (con_ref -> JuMP. delete (optim, con_ref), JuMP . nonlin_constraints)
609+ nonlin_constraints = JuMP . all_constraints (optim, JuMP . NonlinearExpr, MOI. LessThan{JNT})
610+ map (con_ref -> JuMP. delete (optim, con_ref), nonlin_constraints)
611611 for i in findall (.! isinf .(con. X̂0min))
612612 gfunc_i = optim[Symbol (" g_X̂0min_$(i) " )]
613- JuMP . @constraint (optim, gfunc_i (Z̃var... ) <= 0 )
613+ @constraint (optim, gfunc_i (Z̃var... ) <= 0 )
614614 end
615615 for i in findall (.! isinf .(con. X̂0max))
616616 gfunc_i = optim[Symbol (" g_X̂0max_$(i) " )]
617- JuMP . @constraint (optim, gfunc_i (Z̃var... ) <= 0 )
617+ @constraint (optim, gfunc_i (Z̃var... ) <= 0 )
618618 end
619619 for i in findall (.! isinf .(con. V̂min))
620620 gfunc_i = optim[Symbol (" g_V̂min_$(i) " )]
@@ -1082,28 +1082,90 @@ function init_optimization!(
10821082 if length (con. i_g) ≠ 0
10831083 for i in eachindex (con. X̂0min)
10841084 name = Symbol (" g_X̂0min_$i " )
1085- optim[name] = add_nonlinear_operator (optim, nZ̃, gfunc[i]; name)
1085+ optim[name] = JuMP. add_nonlinear_operator (
1086+ optim, nZ̃, gfunc[i]; name
1087+ )
10861088 end
10871089 i_end_X̂min = nX̂
10881090 for i in eachindex (con. X̂0max)
10891091 name = Symbol (" g_X̂0max_$i " )
1090- optim[name] = add_nonlinear_operator (optim, nZ̃, gfunc[i_end_X̂min + i]; name)
1092+ optim[name] = JuMP. add_nonlinear_operator (
1093+ optim, nZ̃, gfunc[i_end_X̂min + i]; name
1094+ )
10911095 end
10921096 i_end_X̂max = 2 * nX̂
10931097 for i in eachindex (con. V̂min)
10941098 name = Symbol (" g_V̂min_$i " )
1095- optim[name] = add_nonlinear_operator (optim, nZ̃, gfunc[i_end_X̂max + i]; name)
1099+ optim[name] = JuMP. add_nonlinear_operator (
1100+ optim, nZ̃, gfunc[i_end_X̂max + i]; name
1101+ )
10961102 end
10971103 i_end_V̂min = 2 * nX̂ + nV̂
10981104 for i in eachindex (con. V̂max)
10991105 name = Symbol (" g_V̂max_$i " )
1100- optim[name] = add_nonlinear_operator (optim, nZ̃, gfunc[i_end_V̂min + i]; name)
1106+ optim[name] = JuMP. add_nonlinear_operator (
1107+ optim, nZ̃, gfunc[i_end_V̂min + i]; name
1108+ )
11011109 end
11021110 end
11031111 return nothing
11041112end
11051113
11061114
1115+ """
1116+ get_optim_functions(estim::MovingHorizonEstimator, ::JuMP.GenericModel) -> Jfunc, gfunc
1117+
1118+ Get the objective `Jfunc` and constraints `gfunc` functions for [`MovingHorizonEstimator`](@ref).
1119+
1120+ Inspired from: [User-defined operators with vector outputs](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/tips_and_tricks/#User-defined-operators-with-vector-outputs)
1121+ """
1122+ function get_optim_functions (
1123+ estim:: MovingHorizonEstimator , :: JuMP.GenericModel{JNT}
1124+ ) where {JNT <: Real }
1125+ model, con = estim. model, estim. con
1126+ nx̂, nym, nŷ, nu, He = estim. nx̂, estim. nym, model. ny, model. nu, estim. He
1127+ nV̂, nX̂, ng, nZ̃ = He* nym, He* nx̂, length (con. i_g), length (estim. Z̃)
1128+ Nc = nZ̃ + 3
1129+ Z̃_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nZ̃), Nc)
1130+ V̂_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nV̂), Nc)
1131+ g_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, ng), Nc)
1132+ X̂_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nX̂), Nc)
1133+ x̄_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nx̂), Nc)
1134+ û_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nu), Nc)
1135+ ŷ_cache:: DiffCache{Vector{JNT}, Vector{JNT}} = DiffCache (zeros (JNT, nŷ), Nc)
1136+ function Jfunc (Z̃tup:: T... ):: T where {T <: Real }
1137+ Z̃1 = Z̃tup[begin ]
1138+ Z̃, g = get_tmp (Z̃_cache, Z̃1), get_tmp (g_cache, Z̃1)
1139+ for i in eachindex (Z̃tup)
1140+ Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1141+ end
1142+ V̂, X̂ = get_tmp (V̂_cache, Z̃1), get_tmp (X̂_cache, Z̃1)
1143+ û, ŷ = get_tmp (û_cache, Z̃1), get_tmp (ŷ_cache, Z̃1)
1144+ V̂, X̂ = predict! (V̂, X̂, û, ŷ, estim, model, Z̃)
1145+ g = get_tmp (g_cache, Z̃1)
1146+ g = con_nonlinprog! (g, estim, model, X̂, V̂, Z̃)
1147+ x̄ = get_tmp (x̄_cache, Z̃1)
1148+ return obj_nonlinprog! (x̄, estim, model, V̂, Z̃):: T
1149+ end
1150+ function gfunc_i (i, Z̃tup:: NTuple{N, T} ):: T where {N, T <: Real }
1151+ Z̃1 = Z̃tup[begin ]
1152+ Z̃, g = get_tmp (Z̃_cache, Z̃1), get_tmp (g_cache, Z̃1)
1153+ if any (new != = old for (new, old) in zip (Z̃tup, Z̃)) # new Z̃tup, update predictions:
1154+ V̂, X̂ = get_tmp (V̂_cache, Z̃1), get_tmp (X̂_cache, Z̃1)
1155+ û, ŷ = get_tmp (û_cache, Z̃1), get_tmp (ŷ_cache, Z̃1)
1156+ for i in eachindex (Z̃tup)
1157+ Z̃[i] = Z̃tup[i] # Z̃ .= Z̃tup seems to produce a type instability
1158+ end
1159+ V̂, X̂ = predict! (V̂, X̂, û, ŷ, estim, model, Z̃)
1160+ g = con_nonlinprog! (g, estim, model, X̂, V̂, Z̃)
1161+ end
1162+ return g[i]
1163+ end
1164+ gfunc = [(Z̃... ) -> gfunc_i (i, Z̃) for i in 1 : ng]
1165+ return Jfunc, gfunc
1166+ end
1167+
1168+
11071169"""
11081170 get_optim_functions(estim::MovingHorizonEstimator, ::JuMP.GenericModel) -> Jfunc, gfunc
11091171
0 commit comments