Skip to content

Commit 336eaf3

Browse files
authored
Merge pull request #215 from JuliaControl/debug_hermitian_weights
debug: support `Hermitian` weights in `PredictiveController`
2 parents 61de78d + debae4d commit 336eaf3

File tree

6 files changed

+28
-25
lines changed

6 files changed

+28
-25
lines changed

src/controller/construct.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,13 @@ struct ControllerWeights{
5353
iszero_E::Bool
5454
isinf_C ::Bool
5555
function ControllerWeights{NT}(
56-
model, Hp, Hc, M_Hp::MW, N_Hc::NW, L_Hp::LW, Cwt=Inf, Ewt=0
56+
M_Hp::MW, N_Hc::NW, L_Hp::LW, Cwt, Ewt
5757
) where {
5858
NT<:Real,
5959
MW<:AbstractMatrix{NT},
6060
NW<:AbstractMatrix{NT},
6161
LW<:AbstractMatrix{NT}
6262
}
63-
validate_weights(model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
6463
nΔU = size(N_Hc, 1)
6564
C = Cwt
6665
isinf_C = isinf(C)
@@ -87,11 +86,12 @@ struct ControllerWeights{
8786
end
8887
end
8988

90-
"Outer constructor to convert weight matrix number type to `NT` if necessary."
91-
function ControllerWeights{NT}(
92-
model, Hp, Hc, M_Hp::MW, N_Hc::NW, L_Hp::LW, Cwt=Inf, Ewt=0
93-
) where {NT<:Real, MW<:AbstractMatrix, NW<:AbstractMatrix, LW<:AbstractMatrix}
94-
return ControllerWeights{NT}(model, Hp, Hc, NT.(M_Hp), NT.(N_Hc), NT.(L_Hp), Cwt, Ewt)
89+
"Outer constructor to validate and convert weight matrices if necessary."
90+
function ControllerWeights(
91+
model::SimModel{NT}, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt=Inf, Ewt=0
92+
) where {NT<:Real}
93+
validate_weights(model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
94+
return ControllerWeights{NT}(NT.(M_Hp), NT.(N_Hc), NT.(L_Hp), Cwt, Ewt)
9595
end
9696

9797
"Include all the data for the constraints of [`PredictiveController`](@ref)"

src/controller/explicitmpc.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ function ExplicitMPC(
169169
end
170170
nb = move_blocking(Hp, Hc)
171171
Hc = get_Hc(nb)
172-
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp)
172+
weights = ControllerWeights(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp)
173173
return ExplicitMPC{NT}(estim, Hp, Hc, nb, weights)
174174
end
175175

src/controller/linmpc.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ function LinMPC(
270270
end
271271
nb = move_blocking(Hp, Hc)
272272
Hc = get_Hc(nb)
273-
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt)
273+
weights = ControllerWeights(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt)
274274
return LinMPC{NT}(estim, Hp, Hc, nb, weights, transcription, optim)
275275
end
276276

src/controller/nonlinmpc.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ function NonLinMPC(
372372
Hc = get_Hc(nb)
373373
validate_JE(NT, JE)
374374
gc! = get_mutating_gc(NT, gc)
375-
weights = ControllerWeights{NT}(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
375+
weights = ControllerWeights(estim.model, Hp, Hc, M_Hp, N_Hc, L_Hp, Cwt, Ewt)
376376
return NonLinMPC{NT}(
377377
estim, Hp, Hc, nb, weights, JE, gc!, nc, p, transcription, optim, gradient, jacobian
378378
)

src/general.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ isdifferent(x, y) = any(xi !== yi for (xi, yi) in zip(x, y))
6565

6666
"Generate a block diagonal matrix repeating `n` times the matrix `A`."
6767
repeatdiag(A, n::Int) = kron(I(n), A)
68+
function repeatdiag(A::Hermitian{NT, Diagonal{NT, Vector{NT}}}, n::Int) where {NT<:Real}
69+
return Hermitian(repeatdiag(A.data, n), :L) # to return hermitian of a `Diagonal`
70+
end
6871

6972
"In-place version of `repeat` but for vectors only."
7073
function repeat!(Y::Vector, a::Vector, n::Int)

test/3_test_predictive_control.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
mpc9 = LinMPC(model, nint_u=[1, 1], nint_ym=[0, 0])
3030
@test mpc9.estim.nint_u == [1, 1]
3131
@test mpc9.estim.nint_ym == [0, 0]
32-
mpc10 = LinMPC(model, M_Hp=diagm(collect(1.01:0.01:1.2)))
33-
@test mpc10.weights.M_Hp diagm(collect(1.01:0.01:1.2))
32+
mpc10 = LinMPC(model, M_Hp=Hermitian(diagm(1.01:0.01:1.2), :L))
33+
@test mpc10.weights.M_Hp diagm(1.01:0.01:1.2)
3434
@test mpc10.weights.M_Hp isa Hermitian{Float64, Matrix{Float64}}
35-
mpc11 = LinMPC(model, N_Hc=diagm([0.1,0.11,0.12,0.13]), Cwt=Inf)
35+
mpc11 = LinMPC(model, N_Hc=Hermitian(diagm([0.1,0.11,0.12,0.13]), :L), Cwt=Inf)
3636
@test mpc11.weights.Ñ_Hc diagm([0.1,0.11,0.12,0.13])
3737
@test mpc11.weights.Ñ_Hc isa Hermitian{Float64, Matrix{Float64}}
38-
mcp12 = LinMPC(model, L_Hp=diagm(collect(0.001:0.001:0.02)))
39-
@test mcp12.weights.L_Hp diagm(collect(0.001:0.001:0.02))
38+
mcp12 = LinMPC(model, L_Hp=Hermitian(diagm(0.001:0.001:0.02), :L))
39+
@test mcp12.weights.L_Hp diagm(0.001:0.001:0.02)
4040
@test mcp12.weights.L_Hp isa Hermitian{Float64, Matrix{Float64}}
4141
model2 = LinModel{Float32}(0.5*ones(1,1), ones(1,1), ones(1,1), zeros(1,0), zeros(1,0), 1.0)
4242
mpc13 = LinMPC(model2)
@@ -463,14 +463,14 @@ end
463463
mpc9 = ExplicitMPC(model, nint_u=[1, 1], nint_ym=[0, 0])
464464
@test mpc9.estim.nint_u == [1, 1]
465465
@test mpc9.estim.nint_ym == [0, 0]
466-
mpc10 = ExplicitMPC(model, M_Hp=diagm(collect(1.01:0.01:1.2)))
467-
@test mpc10.weights.M_Hp diagm(collect(1.01:0.01:1.2))
466+
mpc10 = ExplicitMPC(model, M_Hp=Hermitian(diagm(1.01:0.01:1.2), :L))
467+
@test mpc10.weights.M_Hp diagm(1.01:0.01:1.2)
468468
@test mpc10.weights.M_Hp isa Hermitian{Float64, Matrix{Float64}}
469-
mpc11 = ExplicitMPC(model, N_Hc=diagm([0.1,0.11,0.12,0.13]))
469+
mpc11 = ExplicitMPC(model, N_Hc=Hermitian(diagm([0.1,0.11,0.12,0.13]), :L))
470470
@test mpc11.weights.Ñ_Hc diagm([0.1,0.11,0.12,0.13])
471471
@test mpc11.weights.Ñ_Hc isa Hermitian{Float64, Matrix{Float64}}
472-
mcp12 = ExplicitMPC(model, L_Hp=diagm(collect(0.001:0.001:0.02)))
473-
@test mcp12.weights.L_Hp diagm(collect(0.001:0.001:0.02))
472+
mcp12 = ExplicitMPC(model, L_Hp=Hermitian(diagm(0.001:0.001:0.02), :L))
473+
@test mcp12.weights.L_Hp diagm(0.001:0.001:0.02)
474474
@test mcp12.weights.L_Hp isa Hermitian{Float64, Matrix{Float64}}
475475
model2 = LinModel{Float32}(0.5*ones(1,1), ones(1,1), ones(1,1), zeros(1,0), zeros(1,0), 1.0)
476476
mpc13 = ExplicitMPC(model2)
@@ -671,14 +671,14 @@ end
671671
nmpc11 = NonLinMPC(nonlinmodel, Hp=15, nint_u=[1, 1], nint_ym=[0, 0])
672672
@test nmpc11.estim.nint_u == [1, 1]
673673
@test nmpc11.estim.nint_ym == [0, 0]
674-
nmpc12 = NonLinMPC(nonlinmodel, Hp=10, M_Hp=diagm(collect(1.01:0.01:1.2)))
675-
@test nmpc12.weights.M_Hp diagm(collect(1.01:0.01:1.2))
674+
nmpc12 = NonLinMPC(nonlinmodel, Hp=10, M_Hp=Hermitian(diagm(1.01:0.01:1.2), :L))
675+
@test nmpc12.weights.M_Hp diagm(1.01:0.01:1.2)
676676
@test nmpc12.weights.M_Hp isa Hermitian{Float64, Matrix{Float64}}
677-
nmpc13 = NonLinMPC(nonlinmodel, Hp=10, N_Hc=diagm([0.1,0.11,0.12,0.13]), Cwt=Inf)
677+
nmpc13 = NonLinMPC(nonlinmodel, Hp=10, N_Hc=Hermitian(diagm([0.1,0.11,0.12,0.13]), :L), Cwt=Inf)
678678
@test nmpc13.weights.Ñ_Hc diagm([0.1,0.11,0.12,0.13])
679679
@test nmpc13.weights.Ñ_Hc isa Hermitian{Float64, Matrix{Float64}}
680-
nmcp14 = NonLinMPC(nonlinmodel, Hp=10, L_Hp=diagm(collect(0.001:0.001:0.02)))
681-
@test nmcp14.weights.L_Hp diagm(collect(0.001:0.001:0.02))
680+
nmcp14 = NonLinMPC(nonlinmodel, Hp=10, L_Hp=Hermitian(diagm(0.001:0.001:0.02), :L))
681+
@test nmcp14.weights.L_Hp diagm(0.001:0.001:0.02)
682682
@test nmcp14.weights.L_Hp isa Hermitian{Float64, Matrix{Float64}}
683683
nmpc15 = NonLinMPC(nonlinmodel, Hp=10, gc=(Ue,Ŷe,D̂e,p,ϵ)-> [p*dot(Ue,Ŷe)+sum(D̂e)+ϵ], nc=1, p=10)
684684
LHS = zeros(1)

0 commit comments

Comments
 (0)