From 8dbcdec48bc662827ab0ebd2b8d0d4d0e6225d3e Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 5 Nov 2025 09:06:12 -0500 Subject: [PATCH 1/3] =?UTF-8?q?debug:=20only=20fills=20non-zero=20in=20`?= =?UTF-8?q?=E2=88=87=C2=B2f`=20of=20`@operator`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/nonlinmpc.jl | 12 +++++++----- src/estimator/mhe/construct.jl | 7 ++++--- src/general.jl | 19 ++++++++++++++++--- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index 6f244b44f..eed9c4ec4 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -651,6 +651,7 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J if !isnothing(hess) ∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict) ∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃) + ∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J)) end update_objective! = if !isnothing(hess) function (J, ∇J, ∇²J, Z̃_J, Z̃_arg) @@ -715,7 +716,8 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J else # multivariate syntax (see JuMP.@operator doc): function (∇²J_arg::AbstractMatrix{T}, Z̃_arg::Vararg{T, N}) where {N, T<:Real} update_objective!(J, ∇J, ∇²J, Z̃_J, Z̃_arg) - return fill_lowertriangle!(∇²J_arg, ∇²J) + #println(typeof(∇²J_arg)) + return fill_diffstructure!(∇²J_arg, ∇²J, ∇²J_structure) end end if !isnothing(hess) @@ -807,13 +809,13 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN end function ∇gi_func!(∇gi_arg, Z̃_arg) update_con!(gi, ∇gi, Z̃_∇gi, Z̃_arg) - return diffmat2vec!(∇gi_arg, ∇gi, ∇gi_structure) + return fill_diffstructure!(∇gi_arg, ∇gi, ∇gi_structure) end function ∇²gi_func!(∇²ℓ_arg, Z̃_arg, λ_arg) Z̃_∇gi .= Z̃_arg λi .= λ_arg hessian!(ℓ_gi, ∇²ℓ_gi, ∇²gi_prep, hess, Z̃_∇gi, Constant(λi), ∇²gi_cache...) - return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure) + return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure) end gi_min = fill(-myInf, ngi) gi_max = zeros(JNT, ngi) @@ -870,13 +872,13 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN end function ∇geq_func!(∇geq_arg, Z̃_arg) update_con_eq!(geq, ∇geq, Z̃_∇geq, Z̃_arg) - return diffmat2vec!(∇geq_arg, ∇geq, ∇geq_structure) + return fill_diffstructure!(∇geq_arg, ∇geq, ∇geq_structure) end function ∇²geq_func!(∇²ℓ_arg, Z̃_arg, λ_arg) Z̃_∇geq .= Z̃_arg λeq .= λ_arg hessian!(ℓ_geq, ∇²ℓ_geq, ∇²geq_prep, hess, Z̃_∇geq, Constant(λeq), ∇²geq_cache...) - return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_geq, ∇²geq_structure) + return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_geq, ∇²geq_structure) end geq_min = geq_max = zeros(JNT, neq) geq_oracle = MOI.VectorNonlinearOracle(; diff --git a/src/estimator/mhe/construct.jl b/src/estimator/mhe/construct.jl index c9085fe68..6069b6ea4 100644 --- a/src/estimator/mhe/construct.jl +++ b/src/estimator/mhe/construct.jl @@ -1395,6 +1395,7 @@ function get_nonlinobj_op( ∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict) estim.Nk[] = 0 ∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃) + ∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J)) end update_objective! = if !isnothing(hess) function (J, ∇J, ∇²J, Z̃_∇J, Z̃_arg) @@ -1439,7 +1440,7 @@ function get_nonlinobj_op( end function ∇²J_func!(∇²J_arg::AbstractMatrix{T}, Z̃_arg::Vararg{T, N}) where {N, T<:Real} update_objective!(J, ∇J, ∇²J, Z̃_J, Z̃_arg) - return fill_lowertriangle!(∇²J_arg, ∇²J) + return fill_diffstructure!(∇²J_arg, ∇²J, ∇²J_structure) end if !isnothing(hess) @operator(optim, J_op, nZ̃, J_func, ∇J_func!, ∇²J_func!) @@ -1525,13 +1526,13 @@ function get_nonlincon_oracle( end function ∇gi_func!(∇gi_arg, Z̃_arg) update_con!(gi, ∇gi, Z̃_∇gi, Z̃_arg) - return diffmat2vec!(∇gi_arg, ∇gi, ∇gi_structure) + return fill_diffstructure!(∇gi_arg, ∇gi, ∇gi_structure) end function ∇²gi_func!(∇²ℓ_arg, Z̃_arg, λ_arg) Z̃_∇gi .= Z̃_arg λi .= λ_arg hessian!(ℓ_gi, ∇²ℓ_gi, ∇²gi_prep, hess, Z̃_∇gi, Constant(λi), ∇²gi_cache...) - return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure) + return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure) end gi_min = fill(-myInf, ngi) gi_max = zeros(JNT, ngi) diff --git a/src/general.jl b/src/general.jl index 6845de7da..64770b5cc 100644 --- a/src/general.jl +++ b/src/general.jl @@ -84,15 +84,28 @@ function fill_lowertriangle!(A::AbstractMatrix, B::AbstractMatrix) return A end -"Store the diff. matrix `A` in the vector `v` with list of nonzero indices `i_vec`" -function diffmat2vec!(v::AbstractVector, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}}) - for i in eachindex(v) +"Store the diff. matrix `A` in the vector `v` with list of nonzero indices `i_vec`." +function fill_diffstructure!( + v::AbstractVector, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}} +) + for i in eachindex(i_vec) i_A, j_A = i_vec[i] v[i] = A[i_A, j_A] end return v end +"Store the diff. matrix `A` in the matrix `T` with list of nonzero indices `i_vec`." +function fill_diffstructure!( + T::AbstractMatrix, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}} +) + for i in eachindex(i_vec) + i_A, j_A = i_vec[i] + T[i_A, j_A] = A[i_A, j_A] + end + return T +end + backend_str(backend::AbstractADType) = string(nameof(typeof(backend))) backend_str(backend::Nothing) = "nothing" function backend_str(backend::AutoSparse) From 12f90c6bd60a5f45f811514a9d1365f91ab288f0 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 5 Nov 2025 09:10:40 -0500 Subject: [PATCH 2/3] removed: useless `println` --- src/controller/nonlinmpc.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index eed9c4ec4..e622e9965 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -716,7 +716,6 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J else # multivariate syntax (see JuMP.@operator doc): function (∇²J_arg::AbstractMatrix{T}, Z̃_arg::Vararg{T, N}) where {N, T<:Real} update_objective!(J, ∇J, ∇²J, Z̃_J, Z̃_arg) - #println(typeof(∇²J_arg)) return fill_diffstructure!(∇²J_arg, ∇²J, ∇²J_structure) end end From a3cfbd4324a63ee5c42eafb7c8465ee760585875 Mon Sep 17 00:00:00 2001 From: franckgaga Date: Wed, 5 Nov 2025 09:39:40 -0500 Subject: [PATCH 3/3] bump --- Project.toml | 2 +- src/general.jl | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Project.toml b/Project.toml index 9447b49a6..9634f41de 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ModelPredictiveControl" uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c" -version = "1.13.0" +version = "1.13.1" authors = ["Francis Gagnon"] [deps] diff --git a/src/general.jl b/src/general.jl index 64770b5cc..3972d6c32 100644 --- a/src/general.jl +++ b/src/general.jl @@ -76,14 +76,6 @@ function lowertriangle_indices(i_vec::Vector{Tuple{Int, Int}}) return [(i,j) for (i,j) in i_vec if i ≥ j] end -"Fill the lower triangular part of A in-place with the corresponding part in B." -function fill_lowertriangle!(A::AbstractMatrix, B::AbstractMatrix) - for j in axes(A, 2), i in axes(A, 1) - (i ≥ j) && (A[i, j] = B[i, j]) - end - return A -end - "Store the diff. matrix `A` in the vector `v` with list of nonzero indices `i_vec`." function fill_diffstructure!( v::AbstractVector, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}}