1919# Base.convert(::Type{<:TransferFunction{<:SisoRational}}, b::Number) = tf(b)
2020# Base.convert(::Type{<:TransferFunction{<:SisoZpk}}, b::Number) = zpk(b)
2121#
22- Base. convert (:: Type{TransferFunction{TE,SisoZpk{T1, TR1}}} , b :: AbstractMatrix{T2} ) where {TE, T1, TR1, T2<: Number } =
23- zpk (T1 .(b ), undef_sampletime (TE))
24- Base. convert (:: Type{TransferFunction{TE,SisoRational{T1}}} , b :: AbstractMatrix{T2} ) where {TE, T1, T2<: Number } =
25- tf (T1 .(b ), undef_sampletime (TE))
22+ Base. convert (:: Type{TransferFunction{TE,SisoZpk{T1, TR1}}} , D :: AbstractMatrix{T2} ) where {TE, T1, TR1, T2<: Number } =
23+ zpk (convert (Matrix{T1}, D ), undef_sampletime (TE))
24+ Base. convert (:: Type{TransferFunction{TE,SisoRational{T1}}} , D :: AbstractMatrix{T2} ) where {TE, T1, T2<: Number } =
25+ tf (Matrix {T1} (D ), undef_sampletime (TE))
2626
27- function convert (:: Type{StateSpace{TE,T,MT }} , D:: AbstractMatrix{<:Number} ) where {TE,T, MT }
27+ function convert (:: Type{StateSpace{TE,T}} , D:: AbstractMatrix{<:Number} ) where {TE,T}
2828 (ny, nu) = size (D)
29- A = MT ( fill (zero (T), (0 ,0 ) ))
30- B = MT ( fill (zero (T), (0 ,nu) ))
31- C = MT ( fill (zero (T), (ny,0 ) ))
32- D = convert (MT , D)
33- return StateSpace {TE,T,MT } (A,B,C,D,undef_sampletime (TE))
29+ A = fill (zero (T), (0 ,0 ))
30+ B = fill (zero (T), (0 ,nu))
31+ C = fill (zero (T), (ny,0 ))
32+ D = convert (Matrix{T} , D)
33+ return StateSpace {TE,T} (A,B,C,D,undef_sampletime (TE))
3434end
3535
3636# TODO We still dont have TransferFunction{..}(number/array) constructors
37- Base. convert (:: Type{TransferFunction{TE,SisoRational{T}}} , b:: Number ) where {TE, T} =
38- tf (T (b), undef_sampletime (TE))
39- Base. convert (:: Type{TransferFunction{TE,SisoZpk{T,TR}}} , b:: Number ) where {TE, T, TR} =
40- zpk (T (b), undef_sampletime (TE))
41- Base. convert (:: Type{StateSpace{TE,T,MT}} , b:: Number ) where {TE, T, MT} =
42- convert (StateSpace{TE,T,MT}, fill (b, (1 ,1 )))
37+ Base. convert (:: Type{TransferFunction{TE,SisoRational{T}}} , d:: Number ) where {TE, T} =
38+ tf (T (d), undef_sampletime (TE))
39+
40+ Base. convert (:: Type{TransferFunction{TE,SisoZpk{T,TR}}} , d:: Number ) where {TE, T, TR} =
41+ zpk (T (d), undef_sampletime (TE))
42+
43+ Base. convert (:: Type{StateSpace{TE,T}} , d:: Number ) where {TE, T} =
44+ convert (StateSpace{TE,T}, fill (d, (1 ,1 )))
4345#
4446# Base.convert(::Type{TransferFunction{Continuous,<:SisoRational{T}}}, b::Number) where {T} = tf(T(b), Continuous())
4547# Base.convert(::Type{TransferFunction{Continuous,<:SisoZpk{T, TR}}}, b::Number) where {T, TR} = zpk(T(b), Continuous())
4648# Base.convert(::Type{StateSpace{Continuous,T, MT}}, b::Number) where {T, MT} = convert(StateSpace{Continuous,T, MT}, fill(b, (1,1)))
4749
48- #
49- # Base.convert(::Type{<:TransferFunction{<:SisoZpk}}, s::TransferFunction) = zpk(s)
50- # Base.convert(::Type{<:TransferFunction{<:SisoRational}}, s::TransferFunction) = tf(s)
51-
52- #
5350# function Base.convert{T<:Real,S<:TransferFunction}(::Type{S}, b::VecOrMat{T})
5451# r = Matrix{S}(size(b,2),1)
5552# for j=1:size(b,2)
@@ -64,16 +61,16 @@ function convert(::Type{TransferFunction{TE,S}}, G::TransferFunction) where {TE,
6461 return TransferFunction {TE,eltype(Gnew_matrix)} (Gnew_matrix, TE (G. timeevol))
6562end
6663
67- function convert (:: Type{S} , sys:: AbstractStateSpace ) where {T, MT, TE, S <: StateSpace{TE,T,MT} }
68- if sys isa S
64+ function convert (:: Type{StateSpace{TE,T}} , sys:: AbstractStateSpace ) where {TE, T }
65+ if sys isa StateSpace{TE, T}
6966 return sys
7067 else
71- return StateSpace {TE, T,MT } (convert (MT , sys. A), convert (MT , sys. B), convert (MT , sys. C), convert (MT , sys. D), TE (sys. timeevol))
68+ return StateSpace {TE, T} (convert (Matrix{T} , sys. A), convert (Matrix{T} , sys. B), convert (Matrix{T} , sys. C), convert (Matrix{T} , sys. D), TE (sys. timeevol))
7269 end
7370end
7471
7572# TODO Maybe add convert on matrices
76- Base. convert (:: Type{HeteroStateSpace{TE1,AT,BT,CT,DT}} , s:: StateSpace{TE2,T,MT } ) where {TE1,TE2,T,MT ,AT,BT,CT,DT} =
73+ Base. convert (:: Type{HeteroStateSpace{TE1,AT,BT,CT,DT}} , s:: StateSpace{TE2,T} ) where {TE1,TE2,T,AT,BT,CT,DT} =
7774 HeteroStateSpace {TE1,AT,BT,CT,DT} (s. A,s. B,s. C,s. D,TE1 (s. timeevol))
7875
7976Base. convert (:: Type{HeteroStateSpace} , s:: StateSpace ) = HeteroStateSpace (s)
@@ -84,45 +81,41 @@ Base.convert(::Type{StateSpace}, s::HeteroStateSpace{Continuous}) = StateSpace(s
8481function Base. convert (:: Type{StateSpace} , G:: TransferFunction{TE,<:SisoTf{T0}} ) where {TE,T0<: Number }
8582
8683 T = Base. promote_op (/ ,T0,T0)
87- convert (StateSpace{TE,T,Matrix{T} }, G)
84+ convert (StateSpace{TE,T}, G)
8885end
8986
90-
91- function Base. convert (:: Type{StateSpace{TE,T,MT}} , G:: TransferFunction ) where {TE,T<: Number , MT<: AbstractArray{T} }
87+ function Base. convert (:: Type{StateSpace{TE,T}} , G:: TransferFunction ) where {TE,T<: Number }
9288 if ! isproper (G)
9389 error (" System is improper, a state-space representation is impossible" )
9490 end
9591
96- # TODO : These are added due to scoped for blocks, but is a hack. This
97- # could be much cleaner.
98- # T = Base.promote_op(/, T0, T0)
99-
100- Ac = Bc = Cc = Dc = A = B = C = D = Array {T} (undef, 0 , 0 )
101- for i= 1 : ninputs (G)
102- for j= 1 : noutputs (G)
103- a, b, c, d = siso_tf_to_ss (T, G. matrix[j, i])
104- if j > 1
105- # vcat
106- Ac = blockdiag (Ac, a)
107- Bc = vcat (Bc, b)
108- Cc = blockdiag (Cc, c)
109- Dc = vcat (Dc, d)
110- else
111- Ac, Bc, Cc, Dc = a, b, c, d
112- end
113- end
114- if i > 1
115- # hcat
116- A = blockdiag (A, Ac)
117- B = blockdiag (B, Bc)
118- C = hcat (C, Cc)
119- D = hcat (D, Dc)
120- else
121- A, B, C, D = Ac, Bc, Cc, Dc
92+ ny, nu = size (G)
93+
94+ # A, B, C, D matrices for each element of the transfer function matrix
95+ abcd_vec = [siso_tf_to_ss (T, g) for g in G. matrix[:]]
96+
97+ # Number of states for each transfer function element realization
98+ nvec = [size (abcd[1 ], 1 ) for abcd in abcd_vec]
99+ ntot = sum (nvec)
100+
101+ A = zeros (T, (ntot, ntot))
102+ B = zeros (T, (ntot, nu))
103+ C = zeros (T, (ny, ntot))
104+ D = zeros (T, (ny, nu))
105+
106+ inds = - 1 : 0
107+ for j= 1 : nu
108+ for i= 1 : ny
109+ k = (j- 1 )* ny + i
110+
111+ # states correpsonding to the transfer function element (i,j)
112+ inds = (inds. stop+ 1 ): (inds. stop+ nvec[k])
113+
114+ A[inds,inds], B[inds,j: j], C[i: i,inds], D[i: i,j: j] = abcd_vec[k]
122115 end
123116 end
124117 # A, B, C = balance_statespace(A, B, C)[1:3] NOTE: Use balance?
125- return StateSpace {TE,T,MT } (A, B, C, D, TE (G. timeevol))
118+ return StateSpace {TE,T} (A, B, C, D, TE (G. timeevol))
126119end
127120
128121siso_tf_to_ss (T:: Type , f:: SisoTf ) = siso_tf_to_ss (T, convert (SisoRational, f))
@@ -131,8 +124,8 @@ siso_tf_to_ss(T::Type, f::SisoTf) = siso_tf_to_ss(T, convert(SisoRational, f))
131124function siso_tf_to_ss (T:: Type , f:: SisoRational )
132125
133126 num0, den0 = numvec (f), denvec (f)
134- # Normalize the numerator and denominator,
135- # To allow realization of transfer functions that are proper, but now strictly proper
127+ # Normalize the numerator and denominator to allow realization of transfer functions
128+ # that are proper, but not strictly proper
136129 num = num0 / den0[1 ]
137130 den = den0 / den0[1 ]
138131
@@ -141,22 +134,22 @@ function siso_tf_to_ss(T::Type, f::SisoRational)
141134 # Get numerator coefficient of the same order as the denominator
142135 bN = length (num) == N+ 1 ? num[1 ] : 0
143136
144- if N== 0 # || num == zero(Polynomial{T})
145- A = fill ( zero (T), 0 , 0 )
146- B = fill ( zero (T), 0 , 1 )
147- C = fill ( zero (T), 1 , 0 )
137+ if N == 0 # || num == zero(Polynomial{T})
138+ A = zeros (T, ( 0 , 0 ) )
139+ B = zeros (T, ( 0 , 1 ) )
140+ C = zeros (T, ( 1 , 0 ) )
148141 else
149- A = diagm (1 => fill ( one (T) , N- 1 ))
142+ A = diagm (1 => ones (T , N- 1 ))
150143 A[end , :] .= - reverse (den)[1 : end - 1 ]
151144
152- B = fill ( zero (T), N, 1 )
145+ B = zeros (T, ( N, 1 ) )
153146 B[end ] = one (T)
154147
155- C = fill ( zero (T), 1 , N)
148+ C = zeros (T, ( 1 , N) )
156149 C[1 : min (N, length (num))] = reverse (num)[1 : min (N, length (num))]
157150 C[:] -= bN * reverse (den)[1 : end - 1 ] # Can index into polynomials at greater inddices than their length
158151 end
159- D = fill (bN, 1 , 1 )
152+ D = fill (bN, ( 1 , 1 ) )
160153
161154 return A, B, C, D
162155end
0 commit comments