@@ -345,16 +345,18 @@ def test_DLQR_4args(self, matarrayin, matarrayout):
345345 K , S , poles = dlqr (A , B , Q , R )
346346 self .check_DLQR (K , S , poles , Q , R )
347347
348- def test_lqr_badmethod (self ):
348+ @pytest .mark .parametrize ("cdlqr" , [lqr , dlqr ])
349+ def test_lqr_badmethod (self , cdlqr ):
349350 A , B , Q , R = 0 , 1 , 10 , 2
350351 with pytest .raises (ControlArgument , match = "Unknown method" ):
351- K , S , poles = lqr (A , B , Q , R , method = 'nosuchmethod' )
352+ K , S , poles = cdlqr (A , B , Q , R , method = 'nosuchmethod' )
352353
353- def test_lqr_slycot_not_installed (self ):
354+ @pytest .mark .parametrize ("cdlqr" , [lqr , dlqr ])
355+ def test_lqr_slycot_not_installed (self , cdlqr ):
354356 A , B , Q , R = 0 , 1 , 10 , 2
355357 if not slycot_check ():
356358 with pytest .raises (ControlSlycot , match = "Can't find slycot" ):
357- K , S , poles = lqr (A , B , Q , R , method = 'slycot' )
359+ K , S , poles = cdlqr (A , B , Q , R , method = 'slycot' )
358360
359361 @pytest .mark .xfail (reason = "warning not implemented" )
360362 def testLQR_warning (self ):
@@ -375,37 +377,49 @@ def testLQR_warning(self):
375377 with pytest .warns (UserWarning ):
376378 (K , S , E ) = lqr (A , B , Q , R , N )
377379
378- def test_lqr_call_format (self ):
380+ @pytest .mark .parametrize ("cdlqr" , [lqr , dlqr ])
381+ def test_lqr_call_format (self , cdlqr ):
379382 # Create a random state space system for testing
380383 sys = rss (2 , 3 , 2 )
384+ sys .dt = None # treat as either continuous or discrete time
381385
382386 # Weighting matrices
383387 Q = np .eye (sys .nstates )
384388 R = np .eye (sys .ninputs )
385389 N = np .zeros ((sys .nstates , sys .ninputs ))
386390
387391 # Standard calling format
388- Kref , Sref , Eref = lqr (sys .A , sys .B , Q , R )
392+ Kref , Sref , Eref = cdlqr (sys .A , sys .B , Q , R )
389393
390394 # Call with system instead of matricees
391- K , S , E = lqr (sys , Q , R )
395+ K , S , E = cdlqr (sys , Q , R )
392396 np .testing .assert_array_almost_equal (Kref , K )
393397 np .testing .assert_array_almost_equal (Sref , S )
394398 np .testing .assert_array_almost_equal (Eref , E )
395399
396400 # Pass a cross-weighting matrix
397- K , S , E = lqr (sys , Q , R , N )
401+ K , S , E = cdlqr (sys , Q , R , N )
398402 np .testing .assert_array_almost_equal (Kref , K )
399403 np .testing .assert_array_almost_equal (Sref , S )
400404 np .testing .assert_array_almost_equal (Eref , E )
401405
402406 # Inconsistent system dimensions
403407 with pytest .raises (ct .ControlDimension , match = "Incompatible dimen" ):
404- K , S , E = lqr (sys .A , sys .C , Q , R )
408+ K , S , E = cdlqr (sys .A , sys .C , Q , R )
405409
406- # incorrect covariance matrix dimensions
410+ # Incorrect covariance matrix dimensions
407411 with pytest .raises (ct .ControlDimension , match = "Q must be a square" ):
408- K , S , E = lqr (sys .A , sys .B , sys .C , R , Q )
412+ K , S , E = cdlqr (sys .A , sys .B , sys .C , R , Q )
413+
414+ # Too few input arguments
415+ with pytest .raises (ct .ControlArgument , match = "not enough input" ):
416+ K , S , E = cdlqr (sys .A , sys .B )
417+
418+ # First argument is the wrong type (use SISO for non-slycot tests)
419+ sys_tf = tf (rss (3 , 1 , 1 ))
420+ sys_tf .dt = None # treat as either continuous or discrete time
421+ with pytest .raises (ct .ControlArgument , match = "LTI system must be" ):
422+ K , S , E = cdlqr (sys_tf , Q , R )
409423
410424 @pytest .mark .xfail (reason = "warning not implemented" )
411425 def testDLQR_warning (self ):
@@ -443,41 +457,47 @@ def test_LQE(self, matarrayin, method):
443457 L , P , poles = lqe (A , G , C , QN , RN , method = method )
444458 self .check_LQE (L , P , poles , G , QN , RN )
445459
446- def test_lqe_call_format (self ):
460+ @pytest .mark .parametrize ("cdlqe" , [lqe , dlqe ])
461+ def test_lqe_call_format (self , cdlqe ):
447462 # Create a random state space system for testing
448463 sys = rss (4 , 3 , 2 )
464+ sys .dt = None # treat as either continuous or discrete time
449465
450466 # Covariance matrices
451467 Q = np .eye (sys .ninputs )
452468 R = np .eye (sys .noutputs )
453469 N = np .zeros ((sys .ninputs , sys .noutputs ))
454470
455471 # Standard calling format
456- Lref , Pref , Eref = lqe (sys .A , sys .B , sys .C , Q , R )
472+ Lref , Pref , Eref = cdlqe (sys .A , sys .B , sys .C , Q , R )
457473
458474 # Call with system instead of matricees
459- L , P , E = lqe (sys , Q , R )
475+ L , P , E = cdlqe (sys , Q , R )
460476 np .testing .assert_array_almost_equal (Lref , L )
461477 np .testing .assert_array_almost_equal (Pref , P )
462478 np .testing .assert_array_almost_equal (Eref , E )
463479
464- # Compare state space and transfer function (SISO only)
465- sys_siso = rss (4 , 1 , 1 )
466- L_ss , P_ss , E_ss = lqe (sys_siso , np .eye (1 ), np .eye (1 ))
467- L_tf , P_tf , E_tf = lqe (tf (sys_siso ), np .eye (1 ), np .eye (1 ))
468- np .testing .assert_array_almost_equal (np .sort (E_ss ), np .sort (E_tf ))
469-
470480 # Make sure we get an error if we specify N
471481 with pytest .raises (ct .ControlNotImplemented ):
472- L , P , E = lqe (sys , Q , R , N )
482+ L , P , E = cdlqe (sys , Q , R , N )
473483
474484 # Inconsistent system dimensions
475485 with pytest .raises (ct .ControlDimension , match = "Incompatible" ):
476- L , P , E = lqe (sys .A , sys .C , sys .B , Q , R )
486+ L , P , E = cdlqe (sys .A , sys .C , sys .B , Q , R )
477487
478- # incorrect covariance matrix dimensions
488+ # Incorrect covariance matrix dimensions
479489 with pytest .raises (ct .ControlDimension , match = "Incompatible" ):
480- L , P , E = lqe (sys .A , sys .B , sys .C , R , Q )
490+ L , P , E = cdlqe (sys .A , sys .B , sys .C , R , Q )
491+
492+ # Too few input arguments
493+ with pytest .raises (ct .ControlArgument , match = "not enough input" ):
494+ L , P , E = cdlqe (sys .A , sys .C )
495+
496+ # First argument is the wrong type (use SISO for non-slycot tests)
497+ sys_tf = tf (rss (3 , 1 , 1 ))
498+ sys_tf .dt = None # treat as either continuous or discrete time
499+ with pytest .raises (ct .ControlArgument , match = "LTI system must be" ):
500+ L , P , E = cdlqe (sys_tf , Q , R )
481501
482502 def check_DLQE (self , L , P , poles , G , QN , RN ):
483503 P_expected = asmatarrayout (G .dot (QN ).dot (G ))
0 commit comments