@@ -9,9 +9,9 @@ or with UniformScalings is also supported.
99Series coupling with a constant is equivalent to elementwise multiplication of
1010the transfer function matrix with the constant.
1111"""
12- series (sys1:: DescriptorStateSpace , sys2:: DescriptorStateSpace ) = sys2* sys1
13- series (sys1:: DescriptorStateSpace , sys2:: Union{AbstractNumOrArray,UniformScaling} ) = sys2* sys1
14- series (sys1:: Union{AbstractNumOrArray,UniformScaling} , sys2:: DescriptorStateSpace ) = sys2* sys1
12+ series (sys1:: DSTYPE , sys2:: DSTYPE ) = sys2* sys1
13+ series (sys1:: DSTYPE , sys2:: Union{AbstractNumOrArray,UniformScaling} ) = sys2* sys1
14+ series (sys1:: Union{AbstractNumOrArray,UniformScaling} , sys2:: DSTYPE ) = sys2* sys1
1515
1616"""
1717 sys = parallel(sys1, sys2)
@@ -24,9 +24,9 @@ or with UniformScalings is also supported.
2424Parallel coupling with a constant is equivalent to elementwise parallel coupling of
2525the transfer function matrix with the constant.
2626"""
27- parallel (sys1:: DescriptorStateSpace , sys2:: DescriptorStateSpace ) = sys1 + sys2
28- parallel (sys1:: DescriptorStateSpace , sys2:: Union{AbstractNumOrArray,UniformScaling} ) = sys1 + sys2
29- parallel (sys1:: Union{AbstractNumOrArray,UniformScaling} ,sys2:: DescriptorStateSpace ) = sys1 + sys2
27+ parallel (sys1:: DSTYPE , sys2:: DSTYPE ) = sys1 + sys2
28+ parallel (sys1:: DSTYPE , sys2:: Union{AbstractNumOrArray,UniformScaling} ) = sys1 + sys2
29+ parallel (sys1:: Union{AbstractNumOrArray,UniformScaling} ,sys2:: DSTYPE ) = sys1 + sys2
3030"""
3131 sys = append(systems...)
3232
@@ -35,7 +35,7 @@ of individual systems. This corresponds to the block diagonal concatenation of
3535their transfer function matrices.
3636Appending systems with constant matrices, vectors or scalars or with UniformScalings is also supported.
3737"""
38- function append (systems:: DescriptorStateSpace ... )
38+ function append (systems:: DSTYPE ... )
3939 T = promote_type (eltype .(systems)... )
4040 Ts = systems[1 ]. Ts
4141 if ! all (s. Ts == Ts for s in systems)
@@ -54,11 +54,14 @@ function append(systems::DescriptorStateSpace...)
5454 B = blockdiag ([s. B for s in systems]. .. )
5555 C = blockdiag ([s. C for s in systems]. .. )
5656 D = blockdiag ([s. D for s in systems]. .. )
57- return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
57+ if issparse (A)
58+ return SparseDescriptorStateSpace {T} (A, E, B, C, D, Ts)
59+ else
60+ return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
61+ end
5862end
5963
60-
61- function append (A:: Union{DescriptorStateSpace,AbstractNumOrArray,UniformScaling} ...)
64+ function append (A:: Union{DSTYPE,AbstractNumOrArray,UniformScaling} ...)
6265 for a in A
6366 isa (a, UniformScaling) && @warn " All UniformScaling objects in append are set to scalars"
6467 require_one_based_indexing (a)
9598# return DescriptorStateSpace{T}(A, E, B, C, D, Ts)
9699# end
97100
98- function hcat (SYS1:: DescriptorStateSpace{T1} , SYS2:: DescriptorStateSpace{T2} ) where {T1<: Number , T2<: Number }
101+ # function hcat(SYS1::DescriptorStateSpace{T1}, SYS2::DescriptorStateSpace{T2}) where {T1<:Number, T2<:Number}
102+ # #function hcat(SYS1 :: DescriptorStateSpace, SYS2 :: DescriptorStateSpace)
103+ # ny = SYS1.ny
104+ # ny == size(SYS2, 1) || error("The systems must have the same output dimension")
105+ # #T = promote_type(eltype(SYS1), eltype(SYS2))
106+ # T = promote_type(T1, T2)
107+ # #TE = promote_type(TE1, TE2)
108+ # TE1 = typeof(SYS1.E)
109+ # TE2 = typeof(SYS2.E)
110+ # TE = promote_Etype(T, TE1, TE2)
111+ # Ts = promote_Ts(SYS1.Ts, SYS2.Ts)
112+
113+ # A = blockdiag(T.(SYS1.A), T.(SYS2.A))
114+
115+ # local E::TE
116+ # if SYS1.E === I && SYS2.E === I
117+ # #if SYS1.E == I && SYS2.E == I
118+ # E = I
119+ # elseif SYS1.E == I || SYS2.E == I
120+ # blockdims = [size(SYS1.A,1), size(SYS2.A,1)]
121+ # E = sblockdiag(blockdims, SYS1.E == I ? SYS1.E : T.(SYS1.E), SYS2.E == I ? SYS2.E : T.(SYS2.E))
122+ # else
123+ # E = blockdiag(T.(SYS1.E), T.(SYS2.E))
124+ # end
125+ # B = blockdiag(T.(SYS1.B), T.(SYS2.B))
126+ # C = [ T.(SYS1.C) T.(SYS2.C)]
127+ # D = [ T.(SYS1.D) T.(SYS2.D)]
128+ # return DescriptorStateSpace{T}(A, E, B, C, D, Ts)
129+ # end
130+ function hcat (SYS1:: DSTYPE{T1} , SYS2:: DSTYPE{T2} ) where {T1<: Number , T2<: Number }
99131# function hcat(SYS1 :: DescriptorStateSpace, SYS2 :: DescriptorStateSpace)
100132 ny = SYS1. ny
101133 ny == size (SYS2, 1 ) || error (" The systems must have the same output dimension" )
@@ -122,17 +154,24 @@ function hcat(SYS1::DescriptorStateSpace{T1}, SYS2::DescriptorStateSpace{T2}) wh
122154 B = blockdiag (T .(SYS1. B), T .(SYS2. B))
123155 C = [ T .(SYS1. C) T .(SYS2. C)]
124156 D = [ T .(SYS1. D) T .(SYS2. D)]
125- return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
157+ # return DescriptorStateSpace{T}(A, E, B, C, D, Ts)
158+ if issparse (A)
159+ return SparseDescriptorStateSpace {T} (A, E, B, C, D, Ts)
160+ else
161+ return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
162+ end
163+
126164end
127- hcat (SYS :: DescriptorStateSpace{T} , MAT :: Union{Number, AbstractVecOrMat{<:Number}} ) where {T} = hcat (SYS,dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts))
128- hcat (MAT :: Union{Number, AbstractVecOrMat{<:Number}} , SYS :: DescriptorStateSpace{T} ) where {T} = hcat (dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts),SYS)
129- hcat (SYS :: DescriptorStateSpace , MAT :: UniformScaling ) = hcat (SYS,dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. ny,SYS. ny),Ts= SYS. Ts))
130- hcat (MAT :: UniformScaling , SYS :: DescriptorStateSpace ) = hcat (dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. ny,SYS. ny),Ts= SYS. Ts),SYS)
131165
132- function isadss (DST :: Union{DescriptorStateSpace,AbstractNumOrArray,UniformScaling} ...)
166+ hcat (SYS :: DSTYPE{T} , MAT :: Union{Number, AbstractVecOrMat{<:Number}} ) where {T} = hcat (SYS,dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts))
167+ hcat (MAT :: Union{Number, AbstractVecOrMat{<:Number}} , SYS :: DSTYPE{T} ) where {T} = hcat (dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts),SYS)
168+ hcat (SYS :: DSTYPE , MAT :: UniformScaling ) = hcat (SYS,dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. ny,SYS. ny),Ts= SYS. Ts))
169+ hcat (MAT :: UniformScaling , SYS :: DSTYPE ) = hcat (dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. ny,SYS. ny),Ts= SYS. Ts),SYS)
170+
171+ function isadss (DST :: Union{DSTYPE,AbstractNumOrArray,UniformScaling} ...)
133172 # pick the index i of first system
134173 for i = 1 : length (DST)
135- DST[i] isa DescriptorStateSpace && (return i)
174+ DST[i] isa DSTYPE && (return i)
136175 end
137176 # set index to 0 if no system is present
138177 return 0
@@ -149,8 +188,8 @@ concatenation of their transfer function matrices.
149188Concatenation of systems with constant matrices, vectors, or scalars having the same row dimensions
150189or with UniformScalings is also supported.
151190"""
152- horzcat (systems:: Union{DescriptorStateSpace ,AbstractNumOrArray,UniformScaling} ...) = hcat (systems... )
153- function Base. hcat (systems:: DescriptorStateSpace ... )
191+ horzcat (systems:: Union{DSTYPE ,AbstractNumOrArray,UniformScaling} ...) = hcat (systems... )
192+ function Base. hcat (systems:: DSTYPE ... )
154193 # Perform checks
155194 T = promote_type (eltype .(systems)... )
156195 Ts = systems[1 ]. Ts
@@ -170,7 +209,11 @@ function Base.hcat(systems::DescriptorStateSpace...)
170209 C = hcat ([s. C for s in systems]. .. )
171210 D = hcat ([s. D for s in systems]. .. )
172211
173- return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
212+ if issparse (A)
213+ return SparseDescriptorStateSpace {T} (A, E, B, C, D, Ts)
214+ else
215+ return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
216+ end
174217end
175218
176219"""
@@ -184,9 +227,9 @@ concatenation of their transfer function matrices.
184227Concatenation of systems with constant matrices, vectors, or scalars having the same column dimensions
185228or with UniformScalings is also supported.
186229"""
187- vertcat (systems:: Union{DescriptorStateSpace ,AbstractNumOrArray,UniformScaling} ...) = vcat (systems... )
230+ vertcat (systems:: Union{DSTYPE ,AbstractNumOrArray,UniformScaling} ...) = vcat (systems... )
188231
189- function Base. vcat (systems:: DescriptorStateSpace ... )
232+ function Base. vcat (systems:: DSTYPE ... )
190233 # Perform checks
191234 T = promote_type (eltype .(systems)... )
192235 Ts = systems[1 ]. Ts
@@ -205,7 +248,11 @@ function Base.vcat(systems::DescriptorStateSpace...)
205248 B = vcat ([s. B for s in systems]. .. )
206249 C = blockdiag ([s. C for s in systems]. .. )
207250 D = vcat ([s. D for s in systems]. .. )
208- return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
251+ if issparse (A)
252+ return SparseDescriptorStateSpace {T} (A, E, B, C, D, Ts)
253+ else
254+ return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
255+ end
209256end
210257
211258# function vcat(SYS1::DescriptorStateSpace{T1, TE1}, SYS2::DescriptorStateSpace{T2, TE2}) where {T1<:Number, TE1<:ETYPE, T2<:Number, TE2<:ETYPE}
236283# return DescriptorStateSpace{T}(A, E, B, C, D, Ts)
237284# end
238285
239- function vcat (SYS1:: DescriptorStateSpace {T1} , SYS2:: DescriptorStateSpace {T2} ) where {T1<: Number , T2<: Number }
286+ function vcat (SYS1:: DSTYPE {T1} , SYS2:: DSTYPE {T2} ) where {T1<: Number , T2<: Number }
240287# function vcat(SYS1 :: DescriptorStateSpace, SYS2 :: DescriptorStateSpace)
241288 nu = SYS1. nu
242289 nu == size (SYS2, 2 ) || error (" The systems must have the same input dimension" )
@@ -263,18 +310,22 @@ function vcat(SYS1::DescriptorStateSpace{T1}, SYS2::DescriptorStateSpace{T2}) wh
263310 C = blockdiag (T .(SYS1. C), T .(SYS2. C))
264311 B = [ T .(SYS1. B); T .(SYS2. B)]
265312 D = [ T .(SYS1. D); T .(SYS2. D)]
266- return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
313+ if issparse (A)
314+ return SparseDescriptorStateSpace {T} (A, E, B, C, D, Ts)
315+ else
316+ return DescriptorStateSpace {T} (A, E, B, C, D, Ts)
317+ end
267318end
268319
269- vcat (SYS :: DescriptorStateSpace {T} , MAT :: Union{Number, AbstractVecOrMat{<:Number}} ) where {T} = vcat (SYS,dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts))
270- vcat (MAT :: Union{Number, AbstractVecOrMat{<:Number}} , SYS :: DescriptorStateSpace {T} ) where {T} = vcat (dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts),SYS)
271- vcat (SYS :: DescriptorStateSpace , MAT :: UniformScaling ) = vcat (SYS,dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. nu,SYS. nu),Ts= SYS. Ts))
272- vcat (MAT :: UniformScaling , SYS :: DescriptorStateSpace ) = vcat (dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. nu,SYS. nu),Ts= SYS. Ts),SYS)
320+ vcat (SYS :: DSTYPE {T} , MAT :: Union{Number, AbstractVecOrMat{<:Number}} ) where {T} = vcat (SYS,dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts))
321+ vcat (MAT :: Union{Number, AbstractVecOrMat{<:Number}} , SYS :: DSTYPE {T} ) where {T} = vcat (dss (promote_type (T,eltype (MAT)).(MAT),Ts= SYS. Ts),SYS)
322+ vcat (SYS :: DSTYPE , MAT :: UniformScaling ) = vcat (SYS,dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. nu,SYS. nu),Ts= SYS. Ts))
323+ vcat (MAT :: UniformScaling , SYS :: DSTYPE ) = vcat (dss (Matrix {promote_type(eltype(SYS),eltype(MAT))} (MAT,SYS. nu,SYS. nu),Ts= SYS. Ts),SYS)
273324
274325for (f, _f, dim, name) in ((:hcat , :_hcat , 1 , " rows" ), (:vcat , :_vcat , 2 , " cols" ))
275326 @eval begin
276- @inline $ f (A:: Union{DescriptorStateSpace , AbstractVecOrMat,UniformScaling,Number} ...) = $ _f (A... )
277- function $_f (A:: Union{DescriptorStateSpace , AbstractVecOrMat,UniformScaling,Number} ...)
327+ @inline $ f (A:: Union{DSTYPE , AbstractVecOrMat,UniformScaling,Number} ...) = $ _f (A... )
328+ function $_f (A:: Union{DSTYPE , AbstractVecOrMat,UniformScaling,Number} ...)
278329 n = - 1
279330 for a in A
280331 if ! isa (a, UniformScaling)
@@ -287,7 +338,7 @@ for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols"
287338 end
288339 end
289340 n == - 1 && throw (ArgumentError ($ (" $f of only UniformScaling objects cannot determine the matrix size" )))
290- if isnothing (findfirst (a -> isa (a, DescriptorStateSpace ), A))
341+ if isnothing (findfirst (a -> isa (a, DSTYPE ), A))
291342 # @warn "Type piracy in $(string($f)): to be fixed in Julia 1.8 (make an issue otherwise)"
292343 # alleviate type piracy problematic
293344 n == 1 && (A = promote_to_arrays (A... )) # convert all scalars to vectors
@@ -300,7 +351,7 @@ for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols"
300351 end
301352end
302353
303- function Base. hvcat (rows :: Tuple{Vararg{Int}} , DST :: DescriptorStateSpace ... )
354+ function Base. hvcat (rows :: Tuple{Vararg{Int}} , DST :: DSTYPE ... )
304355 j2 = rows[1 ]
305356 sys = hcat (DST[1 : j2]. .. )
306357 for i = 2 : length (rows)
313364
314365
315366# function Base.hvcat(rows::Tuple{Vararg{Int}}, A::Union{DescriptorStateSpace, AbstractVecOrMat{<:Number}, Number, UniformScaling}...)
316- Base. hvcat (rows:: Tuple{Vararg{Int}} , A:: Union{DescriptorStateSpace , AbstractVecOrMat, UniformScaling, Number} ...) = _hvcat (rows, A... )
317- function _hvcat (rows:: Tuple{Vararg{Int}} , A:: Union{DescriptorStateSpace , AbstractVecOrMat, UniformScaling, Number} ...)
367+ Base. hvcat (rows:: Tuple{Vararg{Int}} , A:: Union{DSTYPE , AbstractVecOrMat, UniformScaling, Number} ...) = _hvcat (rows, A... )
368+ function _hvcat (rows:: Tuple{Vararg{Int}} , A:: Union{DSTYPE , AbstractVecOrMat, UniformScaling, Number} ...)
318369 require_one_based_indexing (A... )
319370 nr = length (rows)
320371 sum (rows) == length (A) || throw (ArgumentError (" mismatch between row sizes and number of arguments" ))
@@ -368,7 +419,7 @@ function _hvcat(rows::Tuple{Vararg{Int}}, A::Union{DescriptorStateSpace, Abstrac
368419 j += rows[i]
369420 end
370421 end
371- if isnothing (findfirst (a -> isa (a, DescriptorStateSpace ), A))
422+ if isnothing (findfirst (a -> isa (a, DSTYPE ), A))
372423 # alleviate type piracy problematic
373424 # convert all scalars to vectors: not needed in Julia 1.8
374425 # @warn "Type piracy in hvcat: to be fixed in Julia 1.8 (make an issue otherwise)"
384435# promotion to systems of constant matrices, vectors, scalars and UniformScalings
385436promote_to_system_ (n:: Int , :: Type{T} , J:: UniformScaling , Ts:: Real ) where {T} = dss (copyto! (Matrix {T} (undef, n,n), J), Ts = Ts)
386437promote_to_system_ (n:: Int , :: Type{T} , A:: AbstractNumOrArray , Ts:: Real ) where {T} = dss (to_matrix (T,A), Ts = Ts)
387- promote_to_system_ (n:: Int , :: Type{T} , A:: DescriptorStateSpace , Ts:: Real ) where {T} = T == eltype (A) ? A : dss (dssdata (T,A)... , Ts = Ts)
438+ # promote_to_system_(n::Int, ::Type{T}, A::DescriptorStateSpace, Ts::Real) where {T} = T == eltype(A) ? A : dss(dssdata(T,A)..., Ts = Ts)
439+ promote_to_system_ (n:: Int , :: Type{T} , A:: DSTYPE , Ts:: Real ) where {T} = T == eltype (A) ? A : dss (dssdata (T,A)... , Ts = Ts)
388440promote_to_systems (Ts:: Real , n, k, :: Type ) = ()
389441promote_to_systems (Ts:: Real , n, k, :: Type{T} , A) where {T} = (promote_to_system_ (n[k], T, A, Ts),)
390442promote_to_systems (Ts:: Real , n, k, :: Type{T} , A, B) where {T} =
@@ -407,11 +459,11 @@ function promote_to_arrays(A...)
407459end
408460
409461
410- function promote_system_SamplingTime (A:: Union{DescriptorStateSpace ,AbstractNumOrArray,UniformScaling} ...)
462+ function promote_system_SamplingTime (A:: Union{DSTYPE ,AbstractNumOrArray,UniformScaling} ...)
411463 # pick and check the common sampling time
412464 Ts = nothing
413465 for a in A
414- typeof (a) <: DescriptorStateSpace && (isnothing (Ts) ? Ts = a. Ts : Ts = promote_Ts (Ts,a. Ts))
466+ typeof (a) <: DSTYPE && (isnothing (Ts) ? Ts = a. Ts : Ts = promote_Ts (Ts,a. Ts))
415467 end
416468 return isnothing (Ts) ? (return 0 ) : (return Ts) # for systems use Ts = 0 as defualt
417469end
0 commit comments