19
19
# Base.convert(::Type{<:TransferFunction{<:SisoRational}}, b::Number) = tf(b)
20
20
# Base.convert(::Type{<:TransferFunction{<:SisoZpk}}, b::Number) = zpk(b)
21
21
#
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))
26
26
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}
28
28
(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))
34
34
end
35
35
36
36
# 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 )))
43
45
#
44
46
# Base.convert(::Type{TransferFunction{Continuous,<:SisoRational{T}}}, b::Number) where {T} = tf(T(b), Continuous())
45
47
# Base.convert(::Type{TransferFunction{Continuous,<:SisoZpk{T, TR}}}, b::Number) where {T, TR} = zpk(T(b), Continuous())
46
48
# Base.convert(::Type{StateSpace{Continuous,T, MT}}, b::Number) where {T, MT} = convert(StateSpace{Continuous,T, MT}, fill(b, (1,1)))
47
49
48
- #
49
- # Base.convert(::Type{<:TransferFunction{<:SisoZpk}}, s::TransferFunction) = zpk(s)
50
- # Base.convert(::Type{<:TransferFunction{<:SisoRational}}, s::TransferFunction) = tf(s)
51
-
52
- #
53
50
# function Base.convert{T<:Real,S<:TransferFunction}(::Type{S}, b::VecOrMat{T})
54
51
# r = Matrix{S}(size(b,2),1)
55
52
# for j=1:size(b,2)
@@ -64,16 +61,16 @@ function convert(::Type{TransferFunction{TE,S}}, G::TransferFunction) where {TE,
64
61
return TransferFunction {TE,eltype(Gnew_matrix)} (Gnew_matrix, TE (G. timeevol))
65
62
end
66
63
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}
69
66
return sys
70
67
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))
72
69
end
73
70
end
74
71
75
72
# 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} =
77
74
HeteroStateSpace {TE1,AT,BT,CT,DT} (s. A,s. B,s. C,s. D,TE1 (s. timeevol))
78
75
79
76
Base. convert (:: Type{HeteroStateSpace} , s:: StateSpace ) = HeteroStateSpace (s)
@@ -84,45 +81,41 @@ Base.convert(::Type{StateSpace}, s::HeteroStateSpace{Continuous}) = StateSpace(s
84
81
function Base. convert (:: Type{StateSpace} , G:: TransferFunction{TE,<:SisoTf{T0}} ) where {TE,T0<: Number }
85
82
86
83
T = Base. promote_op (/ ,T0,T0)
87
- convert (StateSpace{TE,T,Matrix{T} }, G)
84
+ convert (StateSpace{TE,T}, G)
88
85
end
89
86
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 }
92
88
if ! isproper (G)
93
89
error (" System is improper, a state-space representation is impossible" )
94
90
end
95
91
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]
122
115
end
123
116
end
124
117
# 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))
126
119
end
127
120
128
121
siso_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))
131
124
function siso_tf_to_ss (T:: Type , f:: SisoRational )
132
125
133
126
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
136
129
num = num0 / den0[1 ]
137
130
den = den0 / den0[1 ]
138
131
@@ -141,22 +134,22 @@ function siso_tf_to_ss(T::Type, f::SisoRational)
141
134
# Get numerator coefficient of the same order as the denominator
142
135
bN = length (num) == N+ 1 ? num[1 ] : 0
143
136
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 ) )
148
141
else
149
- A = diagm (1 => fill ( one (T) , N- 1 ))
142
+ A = diagm (1 => ones (T , N- 1 ))
150
143
A[end , :] .= - reverse (den)[1 : end - 1 ]
151
144
152
- B = fill ( zero (T), N, 1 )
145
+ B = zeros (T, ( N, 1 ) )
153
146
B[end ] = one (T)
154
147
155
- C = fill ( zero (T), 1 , N)
148
+ C = zeros (T, ( 1 , N) )
156
149
C[1 : min (N, length (num))] = reverse (num)[1 : min (N, length (num))]
157
150
C[:] -= bN * reverse (den)[1 : end - 1 ] # Can index into polynomials at greater inddices than their length
158
151
end
159
- D = fill (bN, 1 , 1 )
152
+ D = fill (bN, ( 1 , 1 ) )
160
153
161
154
return A, B, C, D
162
155
end
0 commit comments