1313from control .lti import evalfr
1414from control .exception import slycot_check
1515
16+
1617class TestStateSpace (unittest .TestCase ):
1718 """Tests for the StateSpace class."""
1819
@@ -37,14 +38,14 @@ def testPole(self):
3738
3839 p = np .sort (self .sys1 .pole ())
3940 true_p = np .sort ([3.34747678408874 ,
40- - 3.17373839204437 + 1.47492908003839j ,
41- - 3.17373839204437 - 1.47492908003839j ])
41+ - 3.17373839204437 + 1.47492908003839j ,
42+ - 3.17373839204437 - 1.47492908003839j ])
4243
4344 np .testing .assert_array_almost_equal (p , true_p )
4445
4546 def testEmptyZero (self ):
4647 """Test to make sure zero() works with no zeros in system"""
47- sys = _convertToStateSpace (TransferFunction ([1 ], [1 ,2 , 1 ]))
48+ sys = _convertToStateSpace (TransferFunction ([1 ], [1 , 2 , 1 ]))
4849 np .testing .assert_array_equal (sys .zero (), np .array ([]))
4950
5051 @unittest .skipIf (not slycot_check (), "slycot not installed" )
@@ -59,19 +60,19 @@ def testMIMOZero_nonsquare(self):
5960 A = np .array ([[1 , 0 , 0 , 0 , 0 , 0 ],
6061 [0 , 1 , 0 , 0 , 0 , 0 ],
6162 [0 , 0 , 3 , 0 , 0 , 0 ],
62- [0 , 0 , 0 ,- 4 , 0 , 0 ],
63- [0 , 0 , 0 , 0 ,- 1 , 0 ],
63+ [0 , 0 , 0 , - 4 , 0 , 0 ],
64+ [0 , 0 , 0 , 0 , - 1 , 0 ],
6465 [0 , 0 , 0 , 0 , 0 , 3 ]])
65- B = np .array ([[0 ,- 1 ],
66- [- 1 ,0 ],
67- [1 ,- 1 ],
66+ B = np .array ([[0 , - 1 ],
67+ [- 1 , 0 ],
68+ [1 , - 1 ],
6869 [0 , 0 ],
6970 [0 , 1 ],
70- [- 1 ,- 1 ]])
71+ [- 1 , - 1 ]])
7172 C = np .array ([[1 , 0 , 0 , 1 , 0 , 0 ],
7273 [0 , 1 , 0 , 1 , 0 , 1 ],
7374 [0 , 0 , 1 , 0 , 0 , 1 ]])
74- D = np .zeros ((3 ,2 ))
75+ D = np .zeros ((3 , 2 ))
7576 sys = StateSpace (A , B , C , D )
7677
7778 z = np .sort (sys .zero ())
@@ -151,7 +152,7 @@ def testEvalFr(self):
151152 # Set up warnings filter to only show warnings in control module
152153 warnings .filterwarnings ("ignore" )
153154 warnings .filterwarnings ("always" , module = "control" )
154-
155+
155156 # Make sure that we get a pending deprecation warning
156157 sys .evalfr (1. )
157158 assert len (w ) == 1
@@ -186,13 +187,13 @@ def testFreqResp(self):
186187 @unittest .skipIf (not slycot_check (), "slycot not installed" )
187188 def testMinreal (self ):
188189 """Test a minreal model reduction"""
189- #A = [-2, 0.5, 0; 0.5, -0.3, 0; 0, 0, -0.1]
190+ # A = [-2, 0.5, 0; 0.5, -0.3, 0; 0, 0, -0.1]
190191 A = [[- 2 , 0.5 , 0 ], [0.5 , - 0.3 , 0 ], [0 , 0 , - 0.1 ]]
191- #B = [0.3, -1.3; 0.1, 0; 1, 0]
192+ # B = [0.3, -1.3; 0.1, 0; 1, 0]
192193 B = [[0.3 , - 1.3 ], [0.1 , 0. ], [1.0 , 0.0 ]]
193- #C = [0, 0.1, 0; -0.3, -0.2, 0]
194+ # C = [0, 0.1, 0; -0.3, -0.2, 0]
194195 C = [[0. , 0.1 , 0.0 ], [- 0.3 , - 0.2 , 0.0 ]]
195- #D = [0 -0.8; -0.3 0]
196+ # D = [0 -0.8; -0.3 0]
196197 D = [[0. , - 0.8 ], [- 0.3 , 0. ]]
197198 # sys = ss(A, B, C, D)
198199
@@ -235,47 +236,46 @@ def testAppendTF(self):
235236 C1 = [[0. , 0.1 , 0.0 ], [- 0.3 , - 0.2 , 0.0 ]]
236237 D1 = [[0. , - 0.8 ], [- 0.3 , 0. ]]
237238 s = TransferFunction ([1 , 0 ], [1 ])
238- h = 1 / ( s + 1 ) / ( s + 2 )
239+ h = 1 / ( s + 1 ) / ( s + 2 )
239240 sys1 = StateSpace (A1 , B1 , C1 , D1 )
240241 sys2 = _convertToStateSpace (h )
241242 sys3c = sys1 .append (sys2 )
242- np .testing .assert_array_almost_equal (sys1 .A , sys3c .A [:3 ,:3 ])
243- np .testing .assert_array_almost_equal (sys1 .B , sys3c .B [:3 ,:2 ])
244- np .testing .assert_array_almost_equal (sys1 .C , sys3c .C [:2 ,:3 ])
245- np .testing .assert_array_almost_equal (sys1 .D , sys3c .D [:2 ,:2 ])
246- np .testing .assert_array_almost_equal (sys2 .A , sys3c .A [3 :,3 :])
247- np .testing .assert_array_almost_equal (sys2 .B , sys3c .B [3 :,2 :])
248- np .testing .assert_array_almost_equal (sys2 .C , sys3c .C [2 :,3 :])
249- np .testing .assert_array_almost_equal (sys2 .D , sys3c .D [2 :,2 :])
250- np .testing .assert_array_almost_equal (sys3c .A [:3 ,3 :], np .zeros ( (3 , 2 )) )
251- np .testing .assert_array_almost_equal (sys3c .A [3 :,:3 ], np .zeros ( (2 , 3 )) )
252-
243+ np .testing .assert_array_almost_equal (sys1 .A , sys3c .A [:3 , :3 ])
244+ np .testing .assert_array_almost_equal (sys1 .B , sys3c .B [:3 , :2 ])
245+ np .testing .assert_array_almost_equal (sys1 .C , sys3c .C [:2 , :3 ])
246+ np .testing .assert_array_almost_equal (sys1 .D , sys3c .D [:2 , :2 ])
247+ np .testing .assert_array_almost_equal (sys2 .A , sys3c .A [3 :, 3 :])
248+ np .testing .assert_array_almost_equal (sys2 .B , sys3c .B [3 :, 2 :])
249+ np .testing .assert_array_almost_equal (sys2 .C , sys3c .C [2 :, 3 :])
250+ np .testing .assert_array_almost_equal (sys2 .D , sys3c .D [2 :, 2 :])
251+ np .testing .assert_array_almost_equal (sys3c .A [:3 , 3 :], np .zeros ((3 , 2 )))
252+ np .testing .assert_array_almost_equal (sys3c .A [3 :, :3 ], np .zeros ((2 , 3 )))
253253
254254 def testArrayAccessSS (self ):
255255
256256 sys1 = StateSpace ([[1. , 2. ], [3. , 4. ]],
257- [[5. , 6. ], [6. , 8. ]],
258- [[9. , 10. ], [11. , 12. ]],
259- [[13. , 14. ], [15. , 16. ]], 1 )
257+ [[5. , 6. ], [6. , 8. ]],
258+ [[9. , 10. ], [11. , 12. ]],
259+ [[13. , 14. ], [15. , 16. ]], 1 )
260260
261- sys1_11 = sys1 [0 ,1 ]
261+ sys1_11 = sys1 [0 , 1 ]
262262 np .testing .assert_array_almost_equal (sys1_11 .A ,
263- sys1 .A )
263+ sys1 .A )
264264 np .testing .assert_array_almost_equal (sys1_11 .B ,
265- sys1 .B [:,1 ])
265+ sys1 .B [:, 1 ])
266266 np .testing .assert_array_almost_equal (sys1_11 .C ,
267- sys1 .C [0 ,:])
267+ sys1 .C [0 , :])
268268 np .testing .assert_array_almost_equal (sys1_11 .D ,
269- sys1 .D [0 ,1 ])
269+ sys1 .D [0 , 1 ])
270270
271271 assert sys1 .dt == sys1_11 .dt
272272
273273 def test_dcgain_cont (self ):
274274 """Test DC gain for continuous-time state-space systems"""
275- sys = StateSpace (- 2. ,6. ,5. ,0 )
275+ sys = StateSpace (- 2. , 6. , 5. , 0 )
276276 np .testing .assert_equal (sys .dcgain (), 15. )
277277
278- sys2 = StateSpace (- 2 , [6. , 4. ], [[5. ],[7. ],[11 ]], np .zeros ((3 ,2 )))
278+ sys2 = StateSpace (- 2 , [6. , 4. ], [[5. ], [7. ], [11 ]], np .zeros ((3 , 2 )))
279279 expected = np .array ([[15. , 10. ], [21. , 14. ], [33. , 22. ]])
280280 np .testing .assert_array_equal (sys2 .dcgain (), expected )
281281
@@ -305,113 +305,109 @@ def test_dcgain_integrator(self):
305305 # the SISO case is also tested in test_dc_gain_{cont,discr}
306306 import itertools
307307 # iterate over input and output sizes, and continuous (dt=None) and discrete (dt=True) time
308- for inputs ,outputs ,dt in itertools .product (range (1 ,6 ),range (1 ,6 ),[None ,True ]):
309- states = max (inputs ,outputs )
308+ for inputs , outputs , dt in itertools .product (range (1 , 6 ), range (1 , 6 ), [None , True ]):
309+ states = max (inputs , outputs )
310310
311311 # a matrix that is singular at DC, and has no "useless" states as in _remove_useless_states
312- a = np .triu (np .tile (2 ,(states ,states )))
312+ a = np .triu (np .tile (2 , (states , states )))
313313 # eigenvalues all +2, except for ...
314- a [0 ,0 ] = 0 if dt is None else 1
315- b = np .eye (max (inputs ,states ))[:states ,:inputs ]
316- c = np .eye (max (outputs ,states ))[:outputs ,:states ]
317- d = np .zeros ((outputs ,inputs ))
318- sys = StateSpace (a ,b , c , d , dt )
319- dc = np .squeeze (np .tile (np .nan ,(outputs ,inputs )))
314+ a [0 , 0 ] = 0 if dt is None else 1
315+ b = np .eye (max (inputs , states ))[:states , :inputs ]
316+ c = np .eye (max (outputs , states ))[:outputs , :states ]
317+ d = np .zeros ((outputs , inputs ))
318+ sys = StateSpace (a , b , c , d , dt )
319+ dc = np .squeeze (np .tile (np .nan , (outputs , inputs )))
320320 np .testing .assert_array_equal (dc , sys .dcgain ())
321321
322-
323322 def test_scalarStaticGain (self ):
324323 """Regression: can we create a scalar static gain?"""
325- g1 = StateSpace ([],[],[],[2 ])
326- g2 = StateSpace ([],[],[],[3 ])
324+ g1 = StateSpace ([], [], [], [2 ])
325+ g2 = StateSpace ([], [], [], [3 ])
327326
328327 # make sure StateSpace internals, specifically ABC matrix
329328 # sizes, are OK for LTI operations
330- g3 = g1 * g2
331- self .assertEqual (6 , g3 .D [0 ,0 ])
332- g4 = g1 + g2
333- self .assertEqual (5 , g4 .D [0 ,0 ])
329+ g3 = g1 * g2
330+ self .assertEqual (6 , g3 .D [0 , 0 ])
331+ g4 = g1 + g2
332+ self .assertEqual (5 , g4 .D [0 , 0 ])
334333 g5 = g1 .feedback (g2 )
335- self .assertAlmostEqual (2. / 7 , g5 .D [0 ,0 ])
334+ self .assertAlmostEqual (2. / 7 , g5 .D [0 , 0 ])
336335 g6 = g1 .append (g2 )
337- np .testing .assert_array_equal (np .diag ([2 ,3 ]),g6 .D )
336+ np .testing .assert_array_equal (np .diag ([2 , 3 ]), g6 .D )
338337
339338 def test_matrixStaticGain (self ):
340339 """Regression: can we create matrix static gains?"""
341- d1 = np .matrix ([[1 ,2 , 3 ],[4 ,5 , 6 ]])
342- d2 = np .matrix ([[7 ,8 ],[9 ,10 ],[11 ,12 ]])
343- g1 = StateSpace ([],[],[],d1 )
340+ d1 = np .matrix ([[1 , 2 , 3 ], [4 , 5 , 6 ]])
341+ d2 = np .matrix ([[7 , 8 ], [9 , 10 ], [11 , 12 ]])
342+ g1 = StateSpace ([], [], [], d1 )
344343
345344 # _remove_useless_states was making A = [[0]]
346- self .assertEqual ((0 ,0 ), g1 .A .shape )
345+ self .assertEqual ((0 , 0 ), g1 .A .shape )
347346
348- g2 = StateSpace ([],[],[],d2 )
349- g3 = StateSpace ([],[],[],d2 .T )
347+ g2 = StateSpace ([], [], [], d2 )
348+ g3 = StateSpace ([], [], [], d2 .T )
350349
351- h1 = g1 * g2
352- np .testing .assert_array_equal (d1 * d2 , h1 .D )
353- h2 = g1 + g3
354- np .testing .assert_array_equal (d1 + d2 .T , h2 .D )
350+ h1 = g1 * g2
351+ np .testing .assert_array_equal (d1 * d2 , h1 .D )
352+ h2 = g1 + g3
353+ np .testing .assert_array_equal (d1 + d2 .T , h2 .D )
355354 h3 = g1 .feedback (g2 )
356- np .testing .assert_array_almost_equal (solve (np .eye (2 )+ d1 * d2 ,d1 ), h3 .D )
355+ np .testing .assert_array_almost_equal (
356+ solve (np .eye (2 ) + d1 * d2 , d1 ), h3 .D )
357357 h4 = g1 .append (g2 )
358- np .testing .assert_array_equal (block_diag (d1 ,d2 ),h4 .D )
359-
358+ np .testing .assert_array_equal (block_diag (d1 , d2 ), h4 .D )
360359
361360 def test_remove_useless_states (self ):
362361 """Regression: _remove_useless_states gives correct ABC sizes"""
363- g1 = StateSpace (np .zeros ((3 ,3 )),
364- np .zeros ((3 ,4 )),
365- np .zeros ((5 ,3 )),
366- np .zeros ((5 ,4 )))
367- self .assertEqual ((0 ,0 ), g1 .A .shape )
368- self .assertEqual ((0 ,4 ), g1 .B .shape )
369- self .assertEqual ((5 ,0 ), g1 .C .shape )
370- self .assertEqual ((5 ,4 ), g1 .D .shape )
362+ g1 = StateSpace (np .zeros ((3 , 3 )),
363+ np .zeros ((3 , 4 )),
364+ np .zeros ((5 , 3 )),
365+ np .zeros ((5 , 4 )))
366+ self .assertEqual ((0 , 0 ), g1 .A .shape )
367+ self .assertEqual ((0 , 4 ), g1 .B .shape )
368+ self .assertEqual ((5 , 0 ), g1 .C .shape )
369+ self .assertEqual ((5 , 4 ), g1 .D .shape )
371370 self .assertEqual (0 , g1 .states )
372371
373-
374372 def test_BadEmptyMatrices (self ):
375373 """Mismatched ABCD matrices when some are empty"""
376- self .assertRaises (ValueError ,StateSpace , [1 ], [], [], [1 ])
377- self .assertRaises (ValueError ,StateSpace , [1 ], [1 ], [], [1 ])
378- self .assertRaises (ValueError ,StateSpace , [1 ], [], [1 ], [1 ])
379- self .assertRaises (ValueError ,StateSpace , [], [1 ], [], [1 ])
380- self .assertRaises (ValueError ,StateSpace , [], [1 ], [1 ], [1 ])
381- self .assertRaises (ValueError ,StateSpace , [], [], [1 ], [1 ])
382- self .assertRaises (ValueError ,StateSpace , [1 ], [1 ], [1 ], [])
383-
374+ self .assertRaises (ValueError , StateSpace , [1 ], [], [], [1 ])
375+ self .assertRaises (ValueError , StateSpace , [1 ], [1 ], [], [1 ])
376+ self .assertRaises (ValueError , StateSpace , [1 ], [], [1 ], [1 ])
377+ self .assertRaises (ValueError , StateSpace , [], [1 ], [], [1 ])
378+ self .assertRaises (ValueError , StateSpace , [], [1 ], [1 ], [1 ])
379+ self .assertRaises (ValueError , StateSpace , [], [], [1 ], [1 ])
380+ self .assertRaises (ValueError , StateSpace , [1 ], [1 ], [1 ], [])
384381
385382 def test_minrealStaticGain (self ):
386383 """Regression: minreal on static gain was failing"""
387- g1 = StateSpace ([],[],[],[1 ])
384+ g1 = StateSpace ([], [], [], [1 ])
388385 g2 = g1 .minreal ()
389386 np .testing .assert_array_equal (g1 .A , g2 .A )
390387 np .testing .assert_array_equal (g1 .B , g2 .B )
391388 np .testing .assert_array_equal (g1 .C , g2 .C )
392389 np .testing .assert_array_equal (g1 .D , g2 .D )
393390
394-
395391 def test_Empty (self ):
396392 """Regression: can we create an empty StateSpace object?"""
397- g1 = StateSpace ([],[],[],[])
398- self .assertEqual (0 ,g1 .states )
399- self .assertEqual (0 ,g1 .inputs )
400- self .assertEqual (0 ,g1 .outputs )
401-
393+ g1 = StateSpace ([], [], [], [])
394+ self .assertEqual (0 , g1 .states )
395+ self .assertEqual (0 , g1 .inputs )
396+ self .assertEqual (0 , g1 .outputs )
402397
403398 def test_MatrixToStateSpace (self ):
404399 """_convertToStateSpace(matrix) gives ss([],[],[],D)"""
405- D = np .matrix ([[1 ,2 , 3 ],[4 ,5 , 6 ]])
400+ D = np .matrix ([[1 , 2 , 3 ], [4 , 5 , 6 ]])
406401 g = _convertToStateSpace (D )
402+
407403 def empty (shape ):
408404 m = np .matrix ([])
409405 m .shape = shape
410406 return m
411- np .testing .assert_array_equal (empty ((0 ,0 )), g .A )
412- np .testing .assert_array_equal (empty ((0 ,D .shape [1 ])), g .B )
413- np .testing .assert_array_equal (empty ((D .shape [0 ],0 )), g .C )
414- np .testing .assert_array_equal (D ,g .D )
407+ np .testing .assert_array_equal (empty ((0 , 0 )), g .A )
408+ np .testing .assert_array_equal (empty ((0 , D .shape [1 ])), g .B )
409+ np .testing .assert_array_equal (empty ((D .shape [0 ], 0 )), g .C )
410+ np .testing .assert_array_equal (D , g .D )
415411
416412
417413class TestRss (unittest .TestCase ):
@@ -448,6 +444,7 @@ def testPole(self):
448444 for z in p :
449445 self .assertTrue (z .real < 0 )
450446
447+
451448class TestDrss (unittest .TestCase ):
452449 """These are tests for the proper functionality of statesp.drss."""
453450
@@ -482,15 +479,14 @@ def testPole(self):
482479 for z in p :
483480 self .assertTrue (abs (z ) < 1 )
484481
485-
486482 def testPoleStatic (self ):
487483 """Regression: pole() of static gain is empty array"""
488484 np .testing .assert_array_equal (np .array ([]),
489- StateSpace ([],[],[],[[1 ]]).pole ())
485+ StateSpace ([], [], [], [[1 ]]).pole ())
490486
491487
492488def suite ():
493- return unittest .TestLoader ().loadTestsFromTestCase (TestStateSpace )
489+ return unittest .TestLoader ().loadTestsFromTestCase (TestStateSpace )
494490
495491
496492if __name__ == "__main__" :
0 commit comments