Skip to content

Reduce allocations by avoiding empty for default d argument #91

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions src/controller/execute.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
@doc raw"""
initstate!(mpc::PredictiveController, u, ym, d=[]) -> x̂
initstate!(mpc::PredictiveController, u, ym, d=mpc.estim.model.dop) -> x̂

Init the states of `mpc.estim` [`StateEstimator`](@ref) and warm start `mpc.ΔŨ` at zero.
"""
function initstate!(mpc::PredictiveController, u, ym, d=empty(mpc.estim.x̂0))
function initstate!(mpc::PredictiveController, u, ym, d=mpc.estim.model.dop)
mpc.ΔŨ .= 0
return initstate!(mpc.estim, u, ym, d)
end

@doc raw"""
moveinput!(mpc::PredictiveController, ry=mpc.estim.model.yop, d=[]; <keyword args>) -> u
moveinput!(
mpc::PredictiveController, ry=mpc.estim.model.yop, d=mpc.estim.model.dop;
<keyword arguments>
) -> u

Compute the optimal manipulated input value `u` for the current control period.

Expand All @@ -29,14 +32,13 @@ See also [`LinMPC`](@ref), [`ExplicitMPC`](@ref), [`NonLinMPC`](@ref).

- `mpc::PredictiveController` : solve optimization problem of `mpc`.
- `ry=mpc.estim.model.yop` : current output setpoints ``\mathbf{r_y}(k)``.
- `d=[]` : current measured disturbances ``\mathbf{d}(k)``.
- `d=mpc.estim.model.dop` : current measured disturbances ``\mathbf{d}(k)``.
- `D̂=repeat(d, mpc.Hp)` or *`Dhat`* : predicted measured disturbances ``\mathbf{D̂}``, constant
in the future by default or ``\mathbf{d̂}(k+j)=\mathbf{d}(k)`` for ``j=1`` to ``H_p``.
- `R̂y=repeat(ry, mpc.Hp)` or *`Rhaty`* : predicted output setpoints ``\mathbf{R̂_y}``, constant
in the future by default or ``\mathbf{r̂_y}(k+j)=\mathbf{r_y}(k)`` for ``j=1`` to ``H_p``.
- `R̂u=repeat(mpc.estim.model.uop, mpc.Hp)` or *`Rhatu`* : predicted manipulated input
setpoints, constant in the future by default or ``\mathbf{r̂_u}(k+j)=\mathbf{u_{op}}`` for
``j=0`` to ``H_p-1``.
- `R̂u=mpc.Uop` or *`Rhatu`* : predicted manipulated input setpoints, constant in the future
by default or ``\mathbf{r̂_u}(k+j)=\mathbf{u_{op}}`` for ``j=0`` to ``H_p-1``.
- `ym=nothing` : current measured outputs ``\mathbf{y^m}(k)``, only required if `mpc.estim`
is an [`InternalModel`](@ref).

Expand All @@ -52,10 +54,10 @@ julia> ry = [5]; u = moveinput!(mpc, ry); round.(u, digits=3)
function moveinput!(
mpc::PredictiveController,
ry::Vector = mpc.estim.model.yop,
d ::Vector = empty(mpc.estim.x̂0);
d ::Vector = mpc.estim.model.dop;
Dhat ::Vector = repeat(d, mpc.Hp),
Rhaty::Vector = repeat(ry, mpc.Hp),
Rhatu::Vector = mpc.noR̂u ? empty(mpc.estim.x̂0) : repeat(mpc.estim.model.uop, mpc.Hp),
Rhatu::Vector = mpc.Uop,
ym::Union{Vector, Nothing} = nothing,
D̂ = Dhat,
R̂y = Rhaty,
Expand Down Expand Up @@ -506,11 +508,11 @@ end
set_objective_linear_coef!(::PredictiveController, _ ) = nothing

"""
updatestate!(mpc::PredictiveController, u, ym, d=[]) -> x̂
updatestate!(mpc::PredictiveController, u, ym, d=mpc.estim.model.dop) -> x̂

Call [`updatestate!`](@ref) on `mpc.estim` [`StateEstimator`](@ref).
"""
function updatestate!(mpc::PredictiveController, u, ym, d=empty(mpc.estim.x̂0))
function updatestate!(mpc::PredictiveController, u, ym, d=mpc.estim.model.dop)
return updatestate!(mpc.estim, u, ym, d)
end
updatestate!(::PredictiveController, _ ) = throw(ArgumentError("missing measured outputs ym"))
Expand Down
14 changes: 7 additions & 7 deletions src/estimator/execute.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ end


@doc raw"""
initstate!(estim::StateEstimator, u, ym, d=[]) -> x̂
initstate!(estim::StateEstimator, u, ym, d=estim.model.dop) -> x̂

Init `estim.x̂0` states from current inputs `u`, measured outputs `ym` and disturbances `d`.

Expand Down Expand Up @@ -111,7 +111,7 @@ julia> evaloutput(estim) ≈ y
true
```
"""
function initstate!(estim::StateEstimator, u, ym, d=empty(estim.x̂0))
function initstate!(estim::StateEstimator, u, ym, d=estim.model.dop)
# --- validate arguments ---
validate_args(estim, u, ym, d)
# --- init state estimate ----
Expand Down Expand Up @@ -161,7 +161,7 @@ Left `estim.x̂0` estimate unchanged if `model` is not a [`LinModel`](@ref).
init_estimate!(::StateEstimator, ::SimModel, _ , _ , _ ) = nothing

@doc raw"""
evaloutput(estim::StateEstimator, d=[]) -> ŷ
evaloutput(estim::StateEstimator, d=estim.model.dop) -> ŷ

Evaluate `StateEstimator` outputs `ŷ` from `estim.x̂0` states and disturbances `d`.

Expand All @@ -176,7 +176,7 @@ julia> ŷ = evaloutput(kf)
20.0
```
"""
function evaloutput(estim::StateEstimator{NT}, d=empty(estim.x̂0)) where NT <: Real
function evaloutput(estim::StateEstimator{NT}, d=estim.model.dop) where NT <: Real
validate_args(estim.model, d)
ŷ0 = Vector{NT}(undef, estim.model.ny)
d0 = d - estim.model.dop
Expand All @@ -187,10 +187,10 @@ function evaloutput(estim::StateEstimator{NT}, d=empty(estim.x̂0)) where NT <:
end

"Functor allowing callable `StateEstimator` object as an alias for `evaloutput`."
(estim::StateEstimator)(d=empty(estim.x̂0)) = evaloutput(estim, d)
(estim::StateEstimator)(d=estim.model.dop) = evaloutput(estim, d)

@doc raw"""
updatestate!(estim::StateEstimator, u, ym, d=[]) -> x̂
updatestate!(estim::StateEstimator, u, ym, d=estim.model.dop) -> x̂

Update `estim.x̂0` estimate with current inputs `u`, measured outputs `ym` and dist. `d`.

Expand All @@ -207,7 +207,7 @@ julia> x̂ = updatestate!(kf, [1], [0]) # x̂[2] is the integrator state (nint_y
0.0
```
"""
function updatestate!(estim::StateEstimator, u, ym, d=empty(estim.x̂0))
function updatestate!(estim::StateEstimator, u, ym, d=estim.model.dop)
validate_args(estim, u, ym, d)
u0, ym0, d0 = remove_op!(estim, u, ym, d)
x̂0next = update_estimate!(estim, u0, ym0, d0)
Expand Down
4 changes: 2 additions & 2 deletions src/predictive_control.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Abstract supertype of all predictive controllers.

---

(mpc::PredictiveController)(ry, d=[]; kwargs...) -> u
(mpc::PredictiveController)(ry, d=mpc.estim.model.dop; kwargs...) -> u

Functor allowing callable `PredictiveController` object as an alias for [`moveinput!`](@ref).

Expand Down Expand Up @@ -42,7 +42,7 @@ end
"Functor allowing callable `PredictiveController` object as an alias for `moveinput!`."
function (mpc::PredictiveController)(
ry::Vector = mpc.estim.model.yop,
d ::Vector = empty(mpc.estim.x̂0);
d ::Vector = mpc.estim.model.dop;
kwargs...
)
return moveinput!(mpc, ry, d; kwargs...)
Expand Down
16 changes: 8 additions & 8 deletions src/sim_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Abstract supertype of [`LinModel`](@ref) and [`NonLinModel`](@ref) types.

---

(model::SimModel)(d=[]) -> y
(model::SimModel)(d=model.dop) -> y

Functor allowing callable `SimModel` object as an alias for [`evaloutput`](@ref).

Expand Down Expand Up @@ -160,7 +160,7 @@ end
detailstr(model::SimModel) = ""

@doc raw"""
initstate!(model::SimModel, u, d=[]) -> x
initstate!(model::SimModel, u, d=model.dop) -> x

Init `model.x0` with manipulated inputs `u` and measured disturbances `d` steady-state.

Expand All @@ -182,7 +182,7 @@ julia> x ≈ updatestate!(model, u)
true
```
"""
function initstate!(model::SimModel, u, d=empty(model.x0))
function initstate!(model::SimModel, u, d=model.dop)
validate_args(model::SimModel, d, u)
u0, d0 = u - model.uop, d - model.dop
steadystate!(model, u0, d0)
Expand All @@ -191,7 +191,7 @@ function initstate!(model::SimModel, u, d=empty(model.x0))
end

"""
updatestate!(model::SimModel, u, d=[]) -> x
updatestate!(model::SimModel, u, d=model.dop) -> x

Update `model.x0` states with current inputs `u` and measured disturbances `d`.

Expand All @@ -204,7 +204,7 @@ julia> x = updatestate!(model, [1])
1.0
```
"""
function updatestate!(model::SimModel{NT}, u, d=empty(model.x0)) where NT <: Real
function updatestate!(model::SimModel{NT}, u, d=model.dop) where NT <: Real
validate_args(model::SimModel, d, u)
xnext0 = Vector{NT}(undef, model.nx)
u0, d0 = u - model.uop, d - model.dop
Expand All @@ -217,7 +217,7 @@ function updatestate!(model::SimModel{NT}, u, d=empty(model.x0)) where NT <: Rea
end

"""
evaloutput(model::SimModel, d=[]) -> y
evaloutput(model::SimModel, d=model.dop) -> y

Evaluate `SimModel` outputs `y` from `model.x0` states and measured disturbances `d`.

Expand All @@ -232,7 +232,7 @@ julia> y = evaloutput(model)
20.0
```
"""
function evaloutput(model::SimModel{NT}, d=empty(model.x0)) where NT <: Real
function evaloutput(model::SimModel{NT}, d=model.dop) where NT <: Real
validate_args(model, d)
y0 = Vector{NT}(undef, model.ny)
d0 = d - model.dop
Expand Down Expand Up @@ -262,7 +262,7 @@ to_mat(A::Real, dims...) = fill(A, dims)


"Functor allowing callable `SimModel` object as an alias for `evaloutput`."
(model::SimModel)(d=empty(model.x0)) = evaloutput(model::SimModel, d)
(model::SimModel)(d=model.dop) = evaloutput(model::SimModel, d)

include("model/linmodel.jl")
include("model/solver.jl")
Expand Down
2 changes: 1 addition & 1 deletion src/state_estim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Abstract supertype of all state estimators.

---

(estim::StateEstimator)(d=[]) -> ŷ
(estim::StateEstimator)(d=estim.model.dop) -> ŷ

Functor allowing callable `StateEstimator` object as an alias for [`evaloutput`](@ref).

Expand Down
Loading