@@ -22,24 +22,18 @@ Append systems in block diagonal form
2222"""
2323function append (systems:: (ST where ST<:AbstractStateSpace) ...)
2424 ST = promote_type (typeof .(systems)... )
25- Ts = systems[1 ]. Ts
26- if ! all (s. Ts == Ts for s in systems)
27- error (" Sampling time mismatch" )
28- end
25+ timeevol = common_timeevol (systems... )
2926 A = blockdiag ([s. A for s in systems]. .. )
3027 B = blockdiag ([s. B for s in systems]. .. )
3128 C = blockdiag ([s. C for s in systems]. .. )
3229 D = blockdiag ([s. D for s in systems]. .. )
33- return ST (A, B, C, D, Ts )
30+ return ST (A, B, C, D, timeevol )
3431end
3532
3633function append (systems:: TransferFunction... )
37- Ts = systems[1 ]. Ts
38- if ! all (s. Ts == Ts for s in systems)
39- error (" Sampling time mismatch" )
40- end
34+ timeevol = common_timeevol (systems... )
4135 mat = blockdiag ([s. matrix for s in systems]. .. )
42- return TransferFunction (mat, Ts )
36+ return TransferFunction (mat, timeevol )
4337end
4438
4539append (systems:: LTISystem... ) = append (promote (systems... )... )
@@ -64,16 +58,12 @@ function Base.vcat(systems::ST...) where ST <: AbstractStateSpace
6458 if ! all (s. nu == nu for s in systems)
6559 error (" All systems must have same input dimension" )
6660 end
67- Ts = systems[1 ]. Ts
68- if ! all (s. Ts == Ts for s in systems)
69- error (" Sampling time mismatch" )
70- end
7161 A = blockdiag ([s. A for s in systems]. .. )
7262 B = vcat ([s. B for s in systems]. .. )
7363 C = blockdiag ([s. C for s in systems]. .. )
7464 D = vcat ([s. D for s in systems]. .. )
75-
76- return ST (A, B, C, D, Ts )
65+ timeevol = common_timeevol (systems ... )
66+ return ST (A, B, C, D, timeevol )
7767end
7868
7969function Base. vcat (systems:: TransferFunction... )
@@ -82,12 +72,10 @@ function Base.vcat(systems::TransferFunction...)
8272 if ! all (s. nu == nu for s in systems)
8373 error (" All systems must have same input dimension" )
8474 end
85- Ts = systems[1 ]. Ts
86- if ! all (s. Ts == Ts for s in systems)
87- error (" Sampling time mismatch" )
88- end
75+ timeevol = common_timeevol (systems... )
8976 mat = vcat ([s. matrix for s in systems]. .. )
90- return TransferFunction (mat, Ts)
77+
78+ return TransferFunction (mat, timeevol)
9179end
9280
9381Base. vcat (systems:: LTISystem... ) = vcat (promote (systems... )... )
@@ -98,16 +86,13 @@ function Base.hcat(systems::ST...) where ST <: AbstractStateSpace
9886 if ! all (s. ny == ny for s in systems)
9987 error (" All systems must have same output dimension" )
10088 end
101- Ts = systems[1 ]. Ts
102- if ! all (s. Ts == Ts for s in systems)
103- error (" Sampling time mismatch" )
104- end
89+ timeevol = common_timeevol (systems... )
10590 A = blockdiag ([s. A for s in systems]. .. )
10691 B = blockdiag ([s. B for s in systems]. .. )
10792 C = hcat ([s. C for s in systems]. .. )
10893 D = hcat ([s. D for s in systems]. .. )
10994
110- return ST (A, B, C, D, Ts )
95+ return ST (A, B, C, D, timeevol )
11196end
11297
11398function Base. hcat (systems:: TransferFunction... )
@@ -116,12 +101,10 @@ function Base.hcat(systems::TransferFunction...)
116101 if ! all (s. ny == ny for s in systems)
117102 error (" All systems must have same output dimension" )
118103 end
119- Ts = systems[1 ]. Ts
120- if ! all (s. Ts == Ts for s in systems)
121- error (" Sampling time mismatch" )
122- end
104+ timeevol = common_timeevol (systems... )
123105 mat = hcat ([s. matrix for s in systems]. .. )
124- return TransferFunction (mat, Ts)
106+
107+ return TransferFunction (mat, timeevol)
125108end
126109
127110Base. hcat (systems:: LTISystem... ) = hcat (promote (systems... )... )
@@ -139,52 +122,15 @@ function Base.typed_hcat(::Type{T}, X...) where {T<:LTISystem}
139122 hcat (convert .(T, X)... )
140123end
141124# Ambiguity
142- Base. typed_hcat (:: Type{T} , X:: Number... ) where {T<: LTISystem , N} = hcat (convert .(T, X)... )
125+ Base. typed_hcat (:: Type{S} , X:: Number... ) where {S<: LTISystem } = hcat (convert .(S, X)... )
126+ Base. typed_hcat (:: Type{S} , X:: Union{AbstractArray{<:Number,1}, AbstractArray{<:Number,2}} ...) where {S<: LTISystem } = hcat (convert .(S, X)... )
143127
144128# Catch special cases where inv(sys) might not be possible after promotion, like improper tf
145129function / (sys1:: Union{StateSpace,AbstractStateSpace} , sys2:: LTISystem )
146130 sys1new, sys2new = promote (sys1, 1 / sys2)
147131 return sys1new* sys2new
148132end
149133
150- # function hvcat(rows::Tuple{Vararg{Int}}, systems::Union{Number,AbstractVecOrMat{<:Number},LTISystem}...)
151- # T = Base.promote_typeof(systems...)
152- # nbr = length(rows) # number of block rows
153- # rs = Array{T,1}(nbr)
154- # a = 1
155- # for i = 1:nbr
156- # rs[i] = hcat(convert.(T,systems[a:a-1+rows[i]])...)
157- # a += rows[i]
158- # end
159- # vcat(rs...)
160- # end
161-
162- # function _get_common_sampling_time(sys_vec::Union{AbstractVector{LTISystem},AbstractVecOrMat{<:Number},Number})
163- # Ts = -1.0 # Initalize corresponding to undefined sampling time
164- #
165- # for sys in sys_vec
166- # if !all(s.Ts == Ts for s in systems])
167- # error("Sampling time mismatch")
168- # end
169- # end
170- #
171- # end
172-
173-
174- # function Base.hcat{T<:Number}(systems::Union{T,AbstractVecOrMat{T},TransferFunction}...)
175- # S = promote_type(map(e->typeof(e),systems)...) # TODO : Should be simplified
176- #
177- # idx_first_tf = findfirst(e -> isa(e, TransferFunction), systems)
178- # Ts = sys_tuple[idx_first_tf].Ts
179- #
180- # if S <: TransferFunction
181- # hcat(map(e->convert(TransferFunction,e),systems)...)
182- # else
183- # cat(2,systems...)
184- # end
185- # end
186-
187-
188134blockdiag (mats:: AbstractMatrix... ) = blockdiag (promote (mats... )... )
189135
190136function blockdiag (mats:: AbstractMatrix{T} ...) where T
@@ -214,16 +160,16 @@ feedback(L::TransferFunction) = L/(1+L)
214160feedback (P1:: TransferFunction , P2:: TransferFunction ) = P1/ (1 + P1* P2)
215161
216162# Efficient implementations
217- function feedback (L:: TransferFunction{T} ) where T<: SisoRational
163+ function feedback (L:: TransferFunction{<:TimeEvolution, T} ) where T<: SisoRational
218164 if size (L) != (1 ,1 )
219165 error (" MIMO TransferFunction feedback isn't implemented, use L/(1+L)" )
220166 end
221167 P = numpoly (L)
222168 Q = denpoly (L)
223- tf (P, P+ Q, L. Ts )
169+ tf (P, P+ Q, L. timeevol )
224170end
225171
226- function feedback (L:: TransferFunction{T} ) where {T<: SisoZpk }
172+ function feedback (L:: TransferFunction{TE, T} ) where {TE <: TimeEvolution , T<: SisoZpk }
227173 if size (L) != (1 ,1 )
228174 error (" MIMO TransferFunction feedback isn't implemented, use L/(1+L)" )
229175 end
@@ -233,7 +179,7 @@ function feedback(L::TransferFunction{T}) where {T<:SisoZpk}
233179 kden = denpol[end ] # Get coeff of s^n
234180 # Create siso system
235181 sisozpk = T (L. matrix[1 ]. z, roots (denpol), k/ kden)
236- return TransferFunction {T} (fill (sisozpk,1 ,1 ), L. Ts )
182+ return TransferFunction {TE, T} (fill (sisozpk,1 ,1 ), L. timeevol )
237183end
238184
239185"""
@@ -255,17 +201,13 @@ function feedback(sys::Union{StateSpace, DelayLtiSystem})
255201end
256202
257203function feedback (sys1:: StateSpace ,sys2:: StateSpace )
258- if sys1. Ts != sys2. Ts # FIXME : replace with common_sample_time
259- error (" Sampling time mismatch" )
260- end
261-
204+ timeevol = common_timeevol (sys1,sys2)
262205 ! (iszero (sys1. D) || iszero (sys2. D)) && error (" There cannot be a direct term (D) in both sys1 and sys2" )
263206 A = [sys1. A+ sys1. B* (- sys2. D)* sys1. C sys1. B* (- sys2. C);
264207 sys2. B* sys1. C sys2. A+ sys2. B* sys1. D* (- sys2. C)]
265208 B = [sys1. B; sys2. B* sys1. D]
266209 C = [sys1. C sys1. D* (- sys2. C)]
267-
268- ss (A, B, C, sys1. D, sys1. Ts)
210+ ss (A, B, C, sys1. D, timeevol)
269211end
270212
271213
@@ -288,9 +230,7 @@ See Zhou etc. for similar (somewhat less symmetric) formulas.
288230 U1= :, Y1= :, U2= :, Y2= :, W1= :, Z1= :, W2= Int[], Z2= Int[],
289231 Wperm= :, Zperm= :, pos_feedback:: Bool = false )
290232
291- if sys1. Ts != sys2. Ts # FIXME : replace with common_sample_time
292- error (" Sampling time mismatch" )
293- end
233+ timeevol = common_timeevol (sys1,sys2)
294234
295235 if ! (isa (Y1, Colon) || allunique (Y1)); @warn " Connecting single output to multiple inputs Y1=$Y1 " ; end
296236 if ! (isa (Y2, Colon) || allunique (Y2)); @warn " Connecting single output to multiple inputs Y2=$Y2 " ; end
@@ -359,7 +299,7 @@ See Zhou etc. for similar (somewhat less symmetric) formulas.
359299 s2_D12* R2* s1_D21 s2_D11 + α* s2_D12* R2* s1_D22* s2_D21]
360300 end
361301
362- return StateSpace (A, B[:, Wperm], C[Zperm,:], D[Zperm, Wperm], sys1 . Ts )
302+ return StateSpace (A, B[:, Wperm], C[Zperm,:], D[Zperm, Wperm], timeevol )
363303end
364304
365305
369309"""
370310function feedback2dof (P:: TransferFunction ,R,S,T)
371311 ! issiso (P) && error (" Feedback not implemented for MIMO systems" )
372- tf (conv (poly2vec (numpoly (P)[1 ]),T),zpconv (poly2vec (denpoly (P)[1 ]),R,poly2vec (numpoly (P)[1 ]),S))
312+ tf (conv (poly2vec (numpoly (P)[1 ]),T),zpconv (poly2vec (denpoly (P)[1 ]),R,poly2vec (numpoly (P)[1 ]),S), P . timeevol )
373313end
374314
375315feedback2dof (B,A,R,S,T) = tf (conv (B,T),zpconv (A,R,B,S))
0 commit comments