Skip to content

Commit fd15f6a

Browse files
authored
Merge pull request #279 from JuliaControl/nonzero_operator_hessian
debug: only fills non-zero in `∇²f` of `@operator`
2 parents 01bf244 + a3cfbd4 commit fd15f6a

File tree

4 files changed

+26
-19
lines changed

4 files changed

+26
-19
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ModelPredictiveControl"
22
uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c"
3-
version = "1.13.0"
3+
version = "1.13.1"
44
authors = ["Francis Gagnon"]
55

66
[deps]

src/controller/nonlinmpc.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J
651651
if !isnothing(hess)
652652
∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict)
653653
∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃)
654+
∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J))
654655
end
655656
update_objective! = if !isnothing(hess)
656657
function (J, ∇J, ∇²J, Z̃_J, Z̃_arg)
@@ -715,7 +716,7 @@ function get_nonlinobj_op(mpc::NonLinMPC, optim::JuMP.GenericModel{JNT}) where J
715716
else # multivariate syntax (see JuMP.@operator doc):
716717
function (∇²J_arg::AbstractMatrix{T}, Z̃_arg::Vararg{T, N}) where {N, T<:Real}
717718
update_objective!(J, ∇J, ∇²J, Z̃_J, Z̃_arg)
718-
return fill_lowertriangle!(∇²J_arg, ∇²J)
719+
return fill_diffstructure!(∇²J_arg, ∇²J, ∇²J_structure)
719720
end
720721
end
721722
if !isnothing(hess)
@@ -807,13 +808,13 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
807808
end
808809
function ∇gi_func!(∇gi_arg, Z̃_arg)
809810
update_con!(gi, ∇gi, Z̃_∇gi, Z̃_arg)
810-
return diffmat2vec!(∇gi_arg, ∇gi, ∇gi_structure)
811+
return fill_diffstructure!(∇gi_arg, ∇gi, ∇gi_structure)
811812
end
812813
function ∇²gi_func!(∇²ℓ_arg, Z̃_arg, λ_arg)
813814
Z̃_∇gi .= Z̃_arg
814815
λi .= λ_arg
815816
hessian!(ℓ_gi, ∇²ℓ_gi, ∇²gi_prep, hess, Z̃_∇gi, Constant(λi), ∇²gi_cache...)
816-
return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure)
817+
return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure)
817818
end
818819
gi_min = fill(-myInf, ngi)
819820
gi_max = zeros(JNT, ngi)
@@ -870,13 +871,13 @@ function get_nonlincon_oracle(mpc::NonLinMPC, ::JuMP.GenericModel{JNT}) where JN
870871
end
871872
function ∇geq_func!(∇geq_arg, Z̃_arg)
872873
update_con_eq!(geq, ∇geq, Z̃_∇geq, Z̃_arg)
873-
return diffmat2vec!(∇geq_arg, ∇geq, ∇geq_structure)
874+
return fill_diffstructure!(∇geq_arg, ∇geq, ∇geq_structure)
874875
end
875876
function ∇²geq_func!(∇²ℓ_arg, Z̃_arg, λ_arg)
876877
Z̃_∇geq .= Z̃_arg
877878
λeq .= λ_arg
878879
hessian!(ℓ_geq, ∇²ℓ_geq, ∇²geq_prep, hess, Z̃_∇geq, Constant(λeq), ∇²geq_cache...)
879-
return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_geq, ∇²geq_structure)
880+
return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_geq, ∇²geq_structure)
880881
end
881882
geq_min = geq_max = zeros(JNT, neq)
882883
geq_oracle = MOI.VectorNonlinearOracle(;

src/estimator/mhe/construct.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,7 @@ function get_nonlinobj_op(
13951395
∇²J_prep = prepare_hessian(J!, hess, Z̃_J, J_cache...; strict)
13961396
estim.Nk[] = 0
13971397
∇²J = init_diffmat(JNT, hess, ∇²J_prep, nZ̃, nZ̃)
1398+
∇²J_structure = lowertriangle_indices(init_diffstructure(∇²J))
13981399
end
13991400
update_objective! = if !isnothing(hess)
14001401
function (J, ∇J, ∇²J, Z̃_∇J, Z̃_arg)
@@ -1439,7 +1440,7 @@ function get_nonlinobj_op(
14391440
end
14401441
function ∇²J_func!(∇²J_arg::AbstractMatrix{T}, Z̃_arg::Vararg{T, N}) where {N, T<:Real}
14411442
update_objective!(J, ∇J, ∇²J, Z̃_J, Z̃_arg)
1442-
return fill_lowertriangle!(∇²J_arg, ∇²J)
1443+
return fill_diffstructure!(∇²J_arg, ∇²J, ∇²J_structure)
14431444
end
14441445
if !isnothing(hess)
14451446
@operator(optim, J_op, nZ̃, J_func, ∇J_func!, ∇²J_func!)
@@ -1525,13 +1526,13 @@ function get_nonlincon_oracle(
15251526
end
15261527
function ∇gi_func!(∇gi_arg, Z̃_arg)
15271528
update_con!(gi, ∇gi, Z̃_∇gi, Z̃_arg)
1528-
return diffmat2vec!(∇gi_arg, ∇gi, ∇gi_structure)
1529+
return fill_diffstructure!(∇gi_arg, ∇gi, ∇gi_structure)
15291530
end
15301531
function ∇²gi_func!(∇²ℓ_arg, Z̃_arg, λ_arg)
15311532
Z̃_∇gi .= Z̃_arg
15321533
λi .= λ_arg
15331534
hessian!(ℓ_gi, ∇²ℓ_gi, ∇²gi_prep, hess, Z̃_∇gi, Constant(λi), ∇²gi_cache...)
1534-
return diffmat2vec!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure)
1535+
return fill_diffstructure!(∇²ℓ_arg, ∇²ℓ_gi, ∇²gi_structure)
15351536
end
15361537
gi_min = fill(-myInf, ngi)
15371538
gi_max = zeros(JNT, ngi)

src/general.jl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,26 @@ function lowertriangle_indices(i_vec::Vector{Tuple{Int, Int}})
7676
return [(i,j) for (i,j) in i_vec if i j]
7777
end
7878

79-
"Fill the lower triangular part of A in-place with the corresponding part in B."
80-
function fill_lowertriangle!(A::AbstractMatrix, B::AbstractMatrix)
81-
for j in axes(A, 2), i in axes(A, 1)
82-
(i j) && (A[i, j] = B[i, j])
79+
"Store the diff. matrix `A` in the vector `v` with list of nonzero indices `i_vec`."
80+
function fill_diffstructure!(
81+
v::AbstractVector, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}}
82+
)
83+
for i in eachindex(i_vec)
84+
i_A, j_A = i_vec[i]
85+
v[i] = A[i_A, j_A]
8386
end
84-
return A
87+
return v
8588
end
8689

87-
"Store the diff. matrix `A` in the vector `v` with list of nonzero indices `i_vec`"
88-
function diffmat2vec!(v::AbstractVector, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}})
89-
for i in eachindex(v)
90+
"Store the diff. matrix `A` in the matrix `T` with list of nonzero indices `i_vec`."
91+
function fill_diffstructure!(
92+
T::AbstractMatrix, A::AbstractMatrix, i_vec::Vector{Tuple{Int, Int}}
93+
)
94+
for i in eachindex(i_vec)
9095
i_A, j_A = i_vec[i]
91-
v[i] = A[i_A, j_A]
96+
T[i_A, j_A] = A[i_A, j_A]
9297
end
93-
return v
98+
return T
9499
end
95100

96101
backend_str(backend::AbstractADType) = string(nameof(typeof(backend)))

0 commit comments

Comments
 (0)