Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebd73c1

Browse files
committed
fixes in canonical and canonical_test that were assuming numpy.matrix
1 parent eda91ca commit ebd73c1

File tree

2 files changed

+25
-29
lines changed

2 files changed

+25
-29
lines changed

control/canonical.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from .statesp import StateSpace
77
from .statefbk import ctrb, obsv
88

9-
from numpy import zeros, shape, poly, iscomplex, hstack, dot, transpose
9+
from numpy import zeros, zeros_like, shape, poly, iscomplex, vstack, hstack, dot, \
10+
transpose, empty
1011
from numpy.linalg import solve, matrix_rank, eig
1112

1213
__all__ = ['canonical_form', 'reachable_form', 'observable_form', 'modal_form',
@@ -70,9 +71,9 @@ def reachable_form(xsys):
7071
zsys = StateSpace(xsys)
7172

7273
# Generate the system matrices for the desired canonical form
73-
zsys.B = zeros(shape(xsys.B))
74+
zsys.B = zeros_like(xsys.B)
7475
zsys.B[0, 0] = 1.0
75-
zsys.A = zeros(shape(xsys.A))
76+
zsys.A = zeros_like(xsys.A)
7677
Apoly = poly(xsys.A) # characteristic polynomial
7778
for i in range(0, xsys.states):
7879
zsys.A[0, i] = -Apoly[i+1] / Apoly[0]
@@ -124,9 +125,9 @@ def observable_form(xsys):
124125
zsys = StateSpace(xsys)
125126

126127
# Generate the system matrices for the desired canonical form
127-
zsys.C = zeros(shape(xsys.C))
128+
zsys.C = zeros_like(xsys.C)
128129
zsys.C[0, 0] = 1
129-
zsys.A = zeros(shape(xsys.A))
130+
zsys.A = zeros_like(xsys.A)
130131
Apoly = poly(xsys.A) # characteristic polynomial
131132
for i in range(0, xsys.states):
132133
zsys.A[i, 0] = -Apoly[i+1] / Apoly[0]
@@ -144,7 +145,7 @@ def observable_form(xsys):
144145
raise ValueError("Transformation matrix singular to working precision.")
145146

146147
# Finally, compute the output matrix
147-
zsys.B = Tzx * xsys.B
148+
zsys.B = Tzx.dot(xsys.B)
148149

149150
return zsys, Tzx
150151

@@ -174,9 +175,9 @@ def modal_form(xsys):
174175
# Calculate eigenvalues and matrix of eigenvectors Tzx,
175176
eigval, eigvec = eig(xsys.A)
176177

177-
# Eigenvalues and according eigenvectors are not sorted,
178+
# Eigenvalues and corresponding eigenvectors are not sorted,
178179
# thus modal transformation is ambiguous
179-
# Sorting eigenvalues and respective vectors by largest to smallest eigenvalue
180+
# Sort eigenvalues and vectors from largest to smallest eigenvalue
180181
idx = eigval.argsort()[::-1]
181182
eigval = eigval[idx]
182183
eigvec = eigvec[:,idx]
@@ -189,23 +190,18 @@ def modal_form(xsys):
189190

190191
# Keep track of complex conjugates (need only one)
191192
lst_conjugates = []
192-
Tzx = None
193+
Tzx = empty((0, xsys.A.shape[0])) # empty zero-height row matrix
193194
for val, vec in zip(eigval, eigvec.T):
194195
if iscomplex(val):
195196
if val not in lst_conjugates:
196197
lst_conjugates.append(val.conjugate())
197-
if Tzx is not None:
198-
Tzx = hstack((Tzx, hstack((vec.real.T, vec.imag.T))))
199-
else:
200-
Tzx = hstack((vec.real.T, vec.imag.T))
198+
Tzx = vstack((Tzx, vec.real, vec.imag))
201199
else:
202200
# if conjugate has already been seen, skip this eigenvalue
203201
lst_conjugates.remove(val)
204202
else:
205-
if Tzx is not None:
206-
Tzx = hstack((Tzx, vec.real.T))
207-
else:
208-
Tzx = vec.real.T
203+
Tzx = vstack((Tzx, vec.real))
204+
Tzx = Tzx.T
209205

210206
# Generate the system matrices for the desired canonical form
211207
zsys.A = solve(Tzx, xsys.A).dot(Tzx)

control/tests/canonical_test.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ def test_reachable_form(self):
2222
D_true = 42.0
2323

2424
# Perform a coordinate transform with a random invertible matrix
25-
T_true = np.matrix([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
25+
T_true = np.array([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
2626
[-0.74855725, -0.39136285, -0.18142339, -0.50356997],
2727
[-0.40688007, 0.81416369, 0.38002113, -0.16483334],
2828
[-0.44769516, 0.15654653, -0.50060858, 0.72419146]])
29-
A = np.linalg.solve(T_true, A_true)*T_true
29+
A = np.linalg.solve(T_true, A_true).dot(T_true)
3030
B = np.linalg.solve(T_true, B_true)
31-
C = C_true*T_true
31+
C = C_true.dot(T_true)
3232
D = D_true
3333

3434
# Create a state space system and convert it to the reachable canonical form
@@ -69,11 +69,11 @@ def test_modal_form(self):
6969
D_true = 42.0
7070

7171
# Perform a coordinate transform with a random invertible matrix
72-
T_true = np.matrix([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
72+
T_true = np.array([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
7373
[-0.74855725, -0.39136285, -0.18142339, -0.50356997],
7474
[-0.40688007, 0.81416369, 0.38002113, -0.16483334],
7575
[-0.44769516, 0.15654653, -0.50060858, 0.72419146]])
76-
A = np.linalg.solve(T_true, A_true)*T_true
76+
A = np.linalg.solve(T_true, A_true).dot(T_true)
7777
B = np.linalg.solve(T_true, B_true)
7878
C = C_true*T_true
7979
D = D_true
@@ -98,9 +98,9 @@ def test_modal_form(self):
9898
C_true = np.array([[1, 0, 0, 1]])
9999
D_true = np.array([[0]])
100100

101-
A = np.linalg.solve(T_true, A_true) * T_true
101+
A = np.linalg.solve(T_true, A_true).dot(T_true)
102102
B = np.linalg.solve(T_true, B_true)
103-
C = C_true * T_true
103+
C = C_true.dot(T_true)
104104
D = D_true
105105

106106
# Create state space system and convert to modal canonical form
@@ -132,9 +132,9 @@ def test_modal_form(self):
132132
C_true = np.array([[0, 1, 0, 1]])
133133
D_true = np.array([[0]])
134134

135-
A = np.linalg.solve(T_true, A_true) * T_true
135+
A = np.linalg.solve(T_true, A_true).dot(T_true)
136136
B = np.linalg.solve(T_true, B_true)
137-
C = C_true * T_true
137+
C = C_true.dot(T_true)
138138
D = D_true
139139

140140
# Create state space system and convert to modal canonical form
@@ -173,13 +173,13 @@ def test_observable_form(self):
173173
D_true = 42.0
174174

175175
# Perform a coordinate transform with a random invertible matrix
176-
T_true = np.matrix([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
176+
T_true = np.array([[-0.27144004, -0.39933167, 0.75634684, 0.44135471],
177177
[-0.74855725, -0.39136285, -0.18142339, -0.50356997],
178178
[-0.40688007, 0.81416369, 0.38002113, -0.16483334],
179179
[-0.44769516, 0.15654653, -0.50060858, 0.72419146]])
180-
A = np.linalg.solve(T_true, A_true)*T_true
180+
A = np.linalg.solve(T_true, A_true).dot(T_true)
181181
B = np.linalg.solve(T_true, B_true)
182-
C = C_true*T_true
182+
C = C_true.dot(T_true)
183183
D = D_true
184184

185185
# Create a state space system and convert it to the observable canonical form

0 commit comments

Comments
 (0)