@@ -6,7 +6,6 @@ struct NonLinModel{
66 h!:: H
77 p:: P
88 solver:: DS
9- k:: Vector{Int}
109 Ts:: NT
1110 t:: Vector{NT}
1211 nu:: Int
@@ -27,7 +26,6 @@ struct NonLinModel{
2726 f!:: F , h!:: H , Ts, nu, nx, ny, nd, p:: P , solver:: DS
2827 ) where {NT<: Real , F<: Function , H<: Function , P<: Any , DS<: DiffSolver }
2928 Ts > 0 || error (" Sampling time Ts must be positive" )
30- k = [0 ]
3129 uop = zeros (NT, nu)
3230 yop = zeros (NT, ny)
3331 dop = zeros (NT, nd)
@@ -45,7 +43,7 @@ struct NonLinModel{
4543 f!, h!,
4644 p,
4745 solver,
48- k, Ts, t,
46+ Ts, t,
4947 nu, nx, ny, nd,
5048 uop, yop, dop, xop, fop,
5149 uname, yname, dname, xname,
@@ -65,18 +63,18 @@ continuous dynamics. Use `solver=nothing` for the discrete case (see Extended He
6563functions are defined as:
6664```math
6765\b egin{aligned}
68- \m athbf{ẋ}(t) &= \m athbf{f}\B ig( \m athbf{x}(t), \m athbf{u}(t), \m athbf{d}(t), \m athbf{p}(t), t \B ig) \\
69- \m athbf{y}(t) &= \m athbf{h}\B ig( \m athbf{x}(t), \m athbf{d}(t), \m athbf{p}(t), t \B ig)
66+ \m athbf{ẋ}(t) &= \m athbf{f}\B ig( \m athbf{x}(t), \m athbf{u}(t), \m athbf{d}(t), \m athbf{p} \B ig) \\
67+ \m athbf{y}(t) &= \m athbf{h}\B ig( \m athbf{x}(t), \m athbf{d}(t), \m athbf{p} \B ig)
7068\e nd{aligned}
7169```
7270where ``\m athbf{x}``, ``\m athbf{y}, ``\m athbf{u}``, ``\m athbf{d}`` and ``\m athbf{p}`` are
7371respectively the state, output, manipulated input, measured disturbance and parameter vectors,
7472and ``t`` the time in second. The functions can be implemented in two possible ways:
7573
76- 1. **Non-mutating functions** (out-of-place): define them as `f(x, u, d, p, t ) -> ẋ` and
77- `h(x, d, p, t ) -> y`. This syntax is simple and intuitive but it allocates more memory.
78- 2. **Mutating functions** (in-place): define them as `f!(ẋ, x, u, d, p, t ) -> nothing` and
79- `h!(y, x, d, p, t ) -> nothing`. This syntax reduces the allocations and potentially the
74+ 1. **Non-mutating functions** (out-of-place): define them as `f(x, u, d, p) -> ẋ` and
75+ `h(x, d, p) -> y`. This syntax is simple and intuitive but it allocates more memory.
76+ 2. **Mutating functions** (in-place): define them as `f!(ẋ, x, u, d, p) -> nothing` and
77+ `h!(y, x, d, p) -> nothing`. This syntax reduces the allocations and potentially the
8078 computational burden as well.
8179
8280`Ts` is the sampling time in second. `nu`, `nx`, `ny` and `nd` are the respective number of
@@ -85,7 +83,7 @@ is the parameters of the model passed to the two functions. It can be of any Jul
8583but use a mutable type if you want to change them later e.g.: a vector.
8684
8785!!! tip
88- Replace the `d`, `p` or `t` argument with `_` if not needed (see Examples below).
86+ Replace the `d` or `p` argument with `_` in your functions if not needed (see Examples below).
8987
9088A 4th order [`RungeKutta`](@ref) solver discretizes the differential equations by default.
9189The rest of the documentation assumes discrete dynamics since all models end up in this
@@ -100,9 +98,9 @@ See also [`LinModel`](@ref).
10098
10199# Examples
102100```jldoctest
103- julia> f!(ẋ, x, u, _ ) = (ẋ .= -0.2x .+ u; nothing);
101+ julia> f!(ẋ, x, u, _ , _ ) = (ẋ .= -0.2x .+ u; nothing);
104102
105- julia> h!(y, x, _ ) = (y .= 0.1x; nothing);
103+ julia> h!(y, x, _ , _ ) = (y .= 0.1x; nothing);
106104
107105julia> model1 = NonLinModel(f!, h!, 5.0, 1, 1, 1) # continuous dynamics
108106NonLinModel with a sample time Ts = 5.0 s, RungeKutta solver and:
@@ -111,9 +109,9 @@ NonLinModel with a sample time Ts = 5.0 s, RungeKutta solver and:
111109 1 outputs y
112110 0 measured disturbances d
113111
114- julia> f(x, u, _ ) = 0.1x + u;
112+ julia> f(x, u, _ , _ ) = 0.1x + u;
115113
116- julia> h(x, _ ) = 2x;
114+ julia> h(x, _ , _ ) = 2x;
117115
118116julia> model2 = NonLinModel(f, h, 2.0, 1, 1, 1, solver=nothing) # discrete dynamics
119117NonLinModel with a sample time Ts = 2.0 s, empty solver and:
@@ -128,16 +126,16 @@ NonLinModel with a sample time Ts = 2.0 s, empty solver and:
128126 State-space functions are similar for discrete dynamics:
129127 ```math
130128 \b egin{aligned}
131- \m athbf{x}(k+1) &= \m athbf{f}\B ig( \m athbf{x}(k), \m athbf{u}(k), \m athbf{d}(k), \m athbf{p}(k), k \B ig) \\
132- \m athbf{y}(k) &= \m athbf{h}\B ig( \m athbf{x}(k), \m athbf{d}(k), \m athbf{p}(k), k \B ig)
129+ \m athbf{x}(k+1) &= \m athbf{f}\B ig( \m athbf{x}(k), \m athbf{u}(k), \m athbf{d}(k), \m athbf{p}(k) \B ig) \\
130+ \m athbf{y}(k) &= \m athbf{h}\B ig( \m athbf{x}(k), \m athbf{d}(k), \m athbf{p}(k) \B ig)
133131 \e nd{aligned}
134132 ```
135133 with two possible implementations as well:
136134
137- 1. **Non-mutating functions**: define them as `f(x, u, d, p, k ) -> xnext` and
138- `h(x, d, p, k ) -> y`.
139- 2. **Mutating functions**: define them as `f!(xnext, x, u, d, p, k ) -> nothing` and
140- `h!(y, x, d, p, k ) -> nothing`.
135+ 1. **Non-mutating functions**: define them as `f(x, u, d, p) -> xnext` and
136+ `h(x, d, p) -> y`.
137+ 2. **Mutating functions**: define them as `f!(xnext, x, u, d, p) -> nothing` and
138+ `h!(y, x, d, p) -> nothing`.
141139"""
142140function NonLinModel {NT} (
143141 f:: Function , h:: Function , Ts:: Real , nu:: Int , nx:: Int , ny:: Int , nd:: Int = 0 ;
@@ -146,8 +144,8 @@ function NonLinModel{NT}(
146144 isnothing (solver) && (solver= EmptySolver ())
147145 ismutating_f = validate_f (NT, f)
148146 ismutating_h = validate_h (NT, h)
149- f! = ismutating_f ? f : f! (xnext, x, u, d, p, k ) = (xnext .= f (x, u, d, p, k ); nothing )
150- h! = ismutating_h ? h : h! (y, x, d, p, k ) = (y .= h (x, d, p, k ); nothing )
147+ f! = ismutating_f ? f : f! (xnext, x, u, d, p) = (xnext .= f (x, u, d, p); nothing )
148+ h! = ismutating_h ? h : h! (y, x, d, p) = (y .= h (x, d, p); nothing )
151149 f!, h! = get_solver_functions (NT, solver, f!, h!, Ts, nu, nx, ny, nd)
152150 F, H, P, DS = get_types (f!, h!, p, solver)
153151 return NonLinModel {NT, F, H, P, DS} (f!, h!, Ts, nu, nx, ny, nd, p, solver)
@@ -173,13 +171,13 @@ end
173171Validate `f` function argument signature and return `true` if it is mutating.
174172"""
175173function validate_f (NT, f)
176- ismutating = hasmethod (f, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Vector{NT}, Any, NT })
177- if ! (ismutating || hasmethod (f, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Any, NT }))
174+ ismutating = hasmethod (f, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Vector{NT}, Any})
175+ if ! (ismutating || hasmethod (f, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Any}))
178176 error (
179177 " the state function has no method with type signature " *
180- " f(x::Vector{$(NT) }, u::Vector{$(NT) }, d::Vector{$(NT) }, p::Any, t:: $(NT) ) or " *
178+ " f(x::Vector{$(NT) }, u::Vector{$(NT) }, d::Vector{$(NT) }, p::Any) or " *
181179 " mutating form f!(xnext::Vector{$(NT) }, x::Vector{$(NT) }, u::Vector{$(NT) }, " *
182- " d::Vector{$(NT) }, p::Any, t:: $(NT) )"
180+ " d::Vector{$(NT) }, p::Any)"
183181 )
184182 end
185183 return ismutating
@@ -191,12 +189,12 @@ end
191189Validate `h` function argument signature and return `true` if it is mutating.
192190"""
193191function validate_h (NT, h)
194- ismutating = hasmethod (h, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Any, NT })
195- if ! (ismutating || hasmethod (h, Tuple{Vector{NT}, Vector{NT}, Any, NT }))
192+ ismutating = hasmethod (h, Tuple{Vector{NT}, Vector{NT}, Vector{NT}, Any})
193+ if ! (ismutating || hasmethod (h, Tuple{Vector{NT}, Vector{NT}, Any}))
196194 error (
197195 " the output function has no method with type signature " *
198- " h(x::Vector{$(NT) }, d::Vector{$(NT) }, p::Any, t:: $(NT) ) or mutating form " *
199- " h!(y::Vector{$(NT) }, x::Vector{$(NT) }, d::Vector{$(NT) }, p::Any, t:: $(NT) )"
196+ " h(x::Vector{$(NT) }, d::Vector{$(NT) }, p::Any) or mutating form " *
197+ " h!(y::Vector{$(NT) }, x::Vector{$(NT) }, d::Vector{$(NT) }, p::Any)"
200198 )
201199 end
202200 return ismutating
@@ -205,11 +203,11 @@ end
205203" Do nothing if `model` is a [`NonLinModel`](@ref)."
206204steadystate! (:: SimModel , _ , _ ) = nothing
207205
208- " Call `f!(xnext0, x0, u0, d0, p, k)` with `model.f!` method for [`NonLinModel`](@ref)."
209- f! (xnext0, model:: NonLinModel , x0, u0, d0, p, k ) = model. f! (xnext0, x0, u0, d0, p, k )
206+ " Call `model. f!(xnext0, x0, u0, d0, p)` for [`NonLinModel`](@ref)."
207+ f! (xnext0, model:: NonLinModel , x0, u0, d0, p) = model. f! (xnext0, x0, u0, d0, p)
210208
211- " Call `h!(y0, x0, d0, p, k)` with `model.h` method for [`NonLinModel`](@ref)."
212- h! (y0, model:: NonLinModel , x0, d0, p, k ) = model. h! (y0, x0, d0, p, k )
209+ " Call `model. h!(y0, x0, d0, p)` for [`NonLinModel`](@ref)."
210+ h! (y0, model:: NonLinModel , x0, d0, p) = model. h! (y0, x0, d0, p)
213211
214212detailstr (model:: NonLinModel ) = " , $(typeof (model. solver). name. name) solver"
215213detailstr (:: NonLinModel{<:Real, <:Function, <:Function, <:Any, <:EmptySolver} ) = " , empty solver"
0 commit comments