From 3215681a496615cf72d6e6cf3ef6593abda35756 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 19 Jan 2026 01:12:39 -0500 Subject: [PATCH 1/2] fix return shape for place_acker (#1190) --- control/statefbk.py | 2 +- control/tests/statefbk_test.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/control/statefbk.py b/control/statefbk.py index b6e9c9655..414673fcf 100644 --- a/control/statefbk.py +++ b/control/statefbk.py @@ -251,7 +251,7 @@ def place_acker(A, B, poles): pmat = pmat + p[n-i-1] * np.linalg.matrix_power(A, i) K = np.linalg.solve(ct, pmat) - K = K[-1, :] # Extract the last row + K = K[-1:, :] # Extract the last row return K diff --git a/control/tests/statefbk_test.py b/control/tests/statefbk_test.py index 97cf7be68..33fadc741 100644 --- a/control/tests/statefbk_test.py +++ b/control/tests/statefbk_test.py @@ -1272,3 +1272,20 @@ def test_create_statefbk_params(unicycle): assert [k for k in clsys.params.keys()] == ['K', 'a', 'b'] assert clsys.params['a'] == 2 assert clsys.params['b'] == 1 + + +@pytest.mark.parametrize('ny, nu', [(1, 1), (2, 2), (2, 1)]) +@pytest.mark.parametrize('method', [place, place_varga, place_acker]) +def test_place_variants(ny, nu, method): + sys = ct.rss(states=2, inputs=nu, outputs=ny) + desired_poles = -np.arange(1, sys.nstates + 1, 1) + + if method == place_acker and sys.ninputs != 1: + with pytest.raises(np.linalg.LinAlgError, match="must be square"): + K = method(sys.A, sys.B, desired_poles) + else: + K = method(sys.A, sys.B, desired_poles) + + placed_poles = np.linalg.eigvals(sys.A - sys.B @ K) + np.testing.assert_array_almost_equal( + np.sort(desired_poles), np.sort(placed_poles)) From 8c71d6ef964cb59765c10574dadb67a63c12b906 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 19 Jan 2026 01:29:33 -0500 Subject: [PATCH 2/2] add mark for slycot in unit test --- control/tests/statefbk_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/control/tests/statefbk_test.py b/control/tests/statefbk_test.py index 33fadc741..d0230fb18 100644 --- a/control/tests/statefbk_test.py +++ b/control/tests/statefbk_test.py @@ -1275,7 +1275,10 @@ def test_create_statefbk_params(unicycle): @pytest.mark.parametrize('ny, nu', [(1, 1), (2, 2), (2, 1)]) -@pytest.mark.parametrize('method', [place, place_varga, place_acker]) +@pytest.mark.parametrize( + 'method', [ + place, place_acker, + pytest.param(place_varga, marks=pytest.mark.slycot)]) def test_place_variants(ny, nu, method): sys = ct.rss(states=2, inputs=nu, outputs=ny) desired_poles = -np.arange(1, sys.nstates + 1, 1)