@@ -64,6 +64,12 @@ function Base.promote_rule(::Type{NamedStateSpace{TE, StateSpace{TE, T1}}}, ::Ty
6464 NamedStateSpace{TE, StateSpace{TE, promote_type (T1,eltype (MT))}}
6565end
6666
67+ function Base. promote_rule (:: Type{U} , :: Type{NamedStateSpace{T, S}} ) where
68+ {T, TF, U<: TransferFunction{<:Any, TF} , S<: AbstractStateSpace{T} }
69+ inner = promote_type (U,S)
70+ NamedStateSpace{T, inner}
71+ end
72+
6773
6874
6975function Base. convert (:: Type{NamedStateSpace{T, S}} , s:: U ) where {T, S <: AbstractStateSpace , U <: AbstractStateSpace }
@@ -82,6 +88,11 @@ function Base.convert(::Type{NamedStateSpace{T, S}}, s::NamedStateSpace{T, U}) w
8288 NamedStateSpace {T,typeof(sys)} (sys, s. x, s. u, s. y, s. name)
8389end
8490
91+ function Base. convert (:: Type{NamedStateSpace{T, S}} , s:: U ) where {T, S <: AbstractStateSpace , U <: TransferFunction }
92+ s2 = Base. convert (S, s)
93+ named_ss (s2, x = gensym (" x" ), u = gensym (" u" ), y = gensym (" y" ))
94+ end
95+
8596# function Base.convert(::Type{TransferFunction{TE, S}}, s::U) where {TE, S, U <: NamedStateSpace{TE}}
8697# convert(TransferFunction{TE, S}, s.sys)
8798# end
@@ -288,6 +299,34 @@ function Base.:*(s1::NamedStateSpace{T, S}, s2::Number) where {T <: CS.TimeEvolu
288299 )
289300end
290301
302+ function Base.:* (s1:: AbstractMatrix , s2:: NamedStateSpace{T, S} ) where {T <: CS.TimeEvolution , S}
303+ if isdiag (s1)
304+ return NamedStateSpace {T,S} (
305+ s1* s2. sys,
306+ s2. x,
307+ s2. u,
308+ [Symbol (string (y)* " _scaled" ) for y in s2. y],
309+ isempty (s2. name) ? " " : s2. name* " _scaled" ,
310+ )
311+ else
312+ return * (promote (s1, s2)... )
313+ end
314+ end
315+
316+ function Base.:* (s1:: NamedStateSpace{T, S} , s2:: AbstractMatrix ) where {T <: CS.TimeEvolution , S}
317+ if isdiag (s2)
318+ return NamedStateSpace {T,S} (
319+ s1. sys* s2,
320+ s1. x,
321+ [Symbol (string (u)* " _scaled" ) for u in s1. u],
322+ s1. y,
323+ isempty (s1. name) ? " " : s1. name* " _scaled" ,
324+ )
325+ else
326+ return * (promote (s1, s2)... )
327+ end
328+ end
329+
291330function Base.:/ (s:: NamedStateSpace{T, S} , n:: Number ) where {T <: CS.TimeEvolution , S}
292331 s* (1 / n)
293332end
324363"""
325364 measure(s::NamedStateSpace, names)
326365
327- Return a system with specified states as measurement outputs.
366+ Return a system with specified state variables as measurement outputs.
367+
368+ See also [`add_output`](@ref).
328369"""
329370function measure (s:: NamedStateSpace , names)
330371 inds = names2indices (names, s. x)
@@ -801,6 +842,27 @@ function CS.append(systems::NamedStateSpace...; kwargs...)
801842end
802843
803844
845+ """
846+ add_output(sys::NamedStateSpace, C2::AbstractArray, D2 = 0; y)
847+
848+ Add outputs to `sys` corresponding to the output matrix `C2` and the feedthrough matrix `D2` to the system `sys`.
849+
850+ # Arguments:
851+ - `y`: The names used for the new outputs. If not provided, the names will be generated automatically.
852+
853+ See also [`measure`](@ref) for a simpler way to output state variables.
854+ """
855+ function CS. add_output (sys:: NamedStateSpace , C2:: AbstractArray , D2= 0 ; y = [Symbol (" y_$i " ) for i in (1 : size (C2, 1 )) .+ sys. ny])
856+ T = promote_type (CS. numeric_type (sys), eltype (C2), eltype (D2))
857+ A,B,C,D = ssdata (sys)
858+ D3 = D2 == 0 ? zeros (T, size (C2, 1 ), sys. nu) : D2
859+ x = sys. x
860+ u = sys. u
861+ y = [sys. y; y]
862+ named_ss (ss (A, B, [C; C2], [D; D3]), sys. timeevol; x, u, y)
863+ end
864+
865+
804866function CS. minreal (sys:: NamedStateSpace , args... ; kwargs... )
805867 msys = minreal (sys. sys, args... ; kwargs... )
806868 named_ss (msys; sys. u, sys. y, sys. name)
0 commit comments