88from numpy .linalg import solve
99from scipy .linalg import eigvals , block_diag
1010from control import matlab
11- from control .statesp import StateSpace , _convertToStateSpace
12- from control .xferfcn import TransferFunction
11+ from control .statesp import StateSpace , _convertToStateSpace , tf2ss
12+ from control .xferfcn import TransferFunction , ss2tf
1313from control .lti import evalfr
1414from control .exception import slycot_check
1515
@@ -20,23 +20,53 @@ class TestStateSpace(unittest.TestCase):
2020 def setUp (self ):
2121 """Set up a MIMO system to test operations on."""
2222
23- A = [[- 3. , 4. , 2. ], [- 1. , - 3. , 0. ], [2. , 5. , 3. ]]
24- B = [[1. , 4. ], [- 3. , - 3. ], [- 2. , 1. ]]
25- C = [[4. , 2. , - 3. ], [1. , 4. , 3. ]]
26- D = [[- 2. , 4. ], [0. , 1. ]]
27-
28- a = [[4. , 1. ], [2. , - 3 ]]
29- b = [[5. , 2. ], [- 3. , - 3. ]]
30- c = [[2. , - 4 ], [0. , 1. ]]
31- d = [[3. , 2. ], [1. , - 1. ]]
32-
33- self .sys1 = StateSpace (A , B , C , D )
34- self .sys2 = StateSpace (a , b , c , d )
23+ # sys1: 3-states square system (2 inputs x 2 outputs)
24+ A322 = [[- 3. , 4. , 2. ],
25+ [- 1. , - 3. , 0. ],
26+ [2. , 5. , 3. ]]
27+ B322 = [[1. , 4. ],
28+ [- 3. , - 3. ],
29+ [- 2. , 1. ]]
30+ C322 = [[4. , 2. , - 3. ],
31+ [1. , 4. , 3. ]]
32+ D322 = [[- 2. , 4. ],
33+ [0. , 1. ]]
34+ self .sys322 = StateSpace (A322 , B322 , C322 , D322 )
35+
36+ # sys1: 2-states square system (2 inputs x 2 outputs)
37+ A222 = [[4. , 1. ],
38+ [2. , - 3 ]]
39+ B222 = [[5. , 2. ],
40+ [- 3. , - 3. ]]
41+ C222 = [[2. , - 4 ],
42+ [0. , 1. ]]
43+ D222 = [[3. , 2. ],
44+ [1. , - 1. ]]
45+ self .sys222 = StateSpace (A222 , B222 , C222 , D222 )
46+
47+ # sys3: 6 states non square system (2 inputs x 3 outputs)
48+ A623 = np .array ([[1 , 0 , 0 , 0 , 0 , 0 ],
49+ [0 , 1 , 0 , 0 , 0 , 0 ],
50+ [0 , 0 , 3 , 0 , 0 , 0 ],
51+ [0 , 0 , 0 , - 4 , 0 , 0 ],
52+ [0 , 0 , 0 , 0 , - 1 , 0 ],
53+ [0 , 0 , 0 , 0 , 0 , 3 ]])
54+ B623 = np .array ([[0 , - 1 ],
55+ [- 1 , 0 ],
56+ [1 , - 1 ],
57+ [0 , 0 ],
58+ [0 , 1 ],
59+ [- 1 , - 1 ]])
60+ C623 = np .array ([[1 , 0 , 0 , 1 , 0 , 0 ],
61+ [0 , 1 , 0 , 1 , 0 , 1 ],
62+ [0 , 0 , 1 , 0 , 0 , 1 ]])
63+ D623 = np .zeros ((3 , 2 ))
64+ self .sys623 = StateSpace (A623 , B623 , C623 , D623 )
3565
3666 def test_pole (self ):
3767 """Evaluate the poles of a MIMO system."""
3868
39- p = np .sort (self .sys1 .pole ())
69+ p = np .sort (self .sys322 .pole ())
4070 true_p = np .sort ([3.34747678408874 ,
4171 - 3.17373839204437 + 1.47492908003839j ,
4272 - 3.17373839204437 - 1.47492908003839j ])
@@ -49,35 +79,43 @@ def test_zero_empty(self):
4979 np .testing .assert_array_equal (sys .zero (), np .array ([]))
5080
5181 @unittest .skipIf (not slycot_check (), "slycot not installed" )
52- def test_zero_mimo_non_square (self ):
53- """Evaluate the zeros of a MIMO system."""
82+ def test_zero_siso (self ):
83+ """Evaluate the zeros of a SISO system."""
84+ # extract only first input / first output system of sys222. This system is denoted sys111
85+ # or tf111
86+ tf111 = ss2tf (self .sys222 )
87+ sys111 = tf2ss (tf111 [0 , 0 ])
88+
89+ # compute zeros as root of the characteristic polynomial at the numerator of tf111
90+ # this method is simple and assumed as valid in this test
91+ true_z = np .sort (tf111 [0 , 0 ].zero ())
92+ # Compute the zeros through ab08nd, which is tested here
93+ z = np .sort (sys111 .zero ())
94+
95+ np .testing .assert_almost_equal (true_z , z )
96+
97+ @unittest .skipIf (not slycot_check (), "slycot not installed" )
98+ def test_zero_mimo_sys322_square (self ):
99+ """Evaluate the zeros of a square MIMO system."""
54100
55- z = np .sort (self .sys1 .zero ())
101+ z = np .sort (self .sys322 .zero ())
56102 true_z = np .sort ([44.41465 , - 0.490252 , - 5.924398 ])
103+ np .testing .assert_array_almost_equal (z , true_z )
104+
105+ @unittest .skipIf (not slycot_check (), "slycot not installed" )
106+ def test_zero_mimo_sys222_square (self ):
107+ """Evaluate the zeros of a square MIMO system."""
57108
109+ z = np .sort (self .sys222 .zero ())
110+ true_z = np .sort ([- 10.568501 , 3.368501 ])
58111 np .testing .assert_array_almost_equal (z , true_z )
59112
60- A = np .array ([[1 , 0 , 0 , 0 , 0 , 0 ],
61- [0 , 1 , 0 , 0 , 0 , 0 ],
62- [0 , 0 , 3 , 0 , 0 , 0 ],
63- [0 , 0 , 0 , - 4 , 0 , 0 ],
64- [0 , 0 , 0 , 0 , - 1 , 0 ],
65- [0 , 0 , 0 , 0 , 0 , 3 ]])
66- B = np .array ([[0 , - 1 ],
67- [- 1 , 0 ],
68- [1 , - 1 ],
69- [0 , 0 ],
70- [0 , 1 ],
71- [- 1 , - 1 ]])
72- C = np .array ([[1 , 0 , 0 , 1 , 0 , 0 ],
73- [0 , 1 , 0 , 1 , 0 , 1 ],
74- [0 , 0 , 1 , 0 , 0 , 1 ]])
75- D = np .zeros ((3 , 2 ))
76- sys = StateSpace (A , B , C , D )
113+ @unittest .skipIf (not slycot_check (), "slycot not installed" )
114+ def test_zero_mimo_sys623_non_square (self ):
115+ """Evaluate the zeros of a non square MIMO system."""
77116
78- z = np .sort (sys .zero ())
117+ z = np .sort (self . sys623 .zero ())
79118 true_z = np .sort ([2. , - 1. ])
80-
81119 np .testing .assert_array_almost_equal (z , true_z )
82120
83121 def test_add_ss (self ):
@@ -89,7 +127,7 @@ def test_add_ss(self):
89127 C = [[4. , 2. , - 3. , 2. , - 4. ], [1. , 4. , 3. , 0. , 1. ]]
90128 D = [[1. , 6. ], [1. , 0. ]]
91129
92- sys = self .sys1 + self .sys2
130+ sys = self .sys322 + self .sys222
93131
94132 np .testing .assert_array_almost_equal (sys .A , A )
95133 np .testing .assert_array_almost_equal (sys .B , B )
@@ -105,7 +143,7 @@ def test_subtract_ss(self):
105143 C = [[4. , 2. , - 3. , - 2. , 4. ], [1. , 4. , 3. , 0. , - 1. ]]
106144 D = [[- 5. , 2. ], [- 1. , 2. ]]
107145
108- sys = self .sys1 - self .sys2
146+ sys = self .sys322 - self .sys222
109147
110148 np .testing .assert_array_almost_equal (sys .A , A )
111149 np .testing .assert_array_almost_equal (sys .B , B )
@@ -121,7 +159,7 @@ def test_multiply_ss(self):
121159 C = [[- 4. , 12. , 4. , 2. , - 3. ], [0. , 1. , 1. , 4. , 3. ]]
122160 D = [[- 2. , - 8. ], [1. , - 1. ]]
123161
124- sys = self .sys1 * self .sys2
162+ sys = self .sys322 * self .sys222
125163
126164 np .testing .assert_array_almost_equal (sys .A , A )
127165 np .testing .assert_array_almost_equal (sys .B , B )
0 commit comments