|
1 | | -"""statesp_test.py - test state space class |
| 1 | +"""Tests for the StateSpace class. |
2 | 2 |
|
3 | 3 | RMM, 30 Mar 2011 based on TestStateSp from v0.4a) |
4 | 4 | RMM, 14 Jun 2019 statesp_array_test.py coverted from statesp_test.py to test |
@@ -563,54 +563,44 @@ def test_rmul_mimo_siso(self, left, right, expected): |
563 | 563 | ) |
564 | 564 |
|
565 | 565 | @slycotonly |
566 | | - def test_pow(self, sys222, sys322): |
| 566 | + @pytest.mark.parametrize("power", [0, 1, 3, -3]) |
| 567 | + @pytest.mark.parametrize("sysname", ["sys222", "sys322"]) |
| 568 | + def test_pow(self, request, sysname, power): |
567 | 569 | """Test state space powers.""" |
568 | | - for sys in [sys222, sys322]: |
569 | | - # Power of 0 |
570 | | - result = sys**0 |
571 | | - expected = StateSpace([], [], [], np.eye(2), dt=0) |
572 | | - np.testing.assert_allclose(expected.A, result.A) |
573 | | - np.testing.assert_allclose(expected.B, result.B) |
574 | | - np.testing.assert_allclose(expected.C, result.C) |
575 | | - np.testing.assert_allclose(expected.D, result.D) |
576 | | - # Power of 1 |
577 | | - result = sys**1 |
578 | | - expected = sys |
579 | | - np.testing.assert_allclose(expected.A, result.A) |
580 | | - np.testing.assert_allclose(expected.B, result.B) |
581 | | - np.testing.assert_allclose(expected.C, result.C) |
582 | | - np.testing.assert_allclose(expected.D, result.D) |
583 | | - # Power of -1 (inverse of biproper system) |
584 | | - # Testing transfer function representations to avoid the |
585 | | - # non-uniqueness of the state-space representation. Once MIMO |
586 | | - # canonical forms are supported, can check canonical state-space |
587 | | - # matrices instead. |
588 | | - result = (sys * sys**-1).minreal() |
589 | | - expected = StateSpace([], [], [], np.eye(2), dt=0) |
590 | | - assert_tf_close_coeff( |
591 | | - ss2tf(expected).minreal(), |
592 | | - ss2tf(result).minreal(), |
593 | | - ) |
| 570 | + sys = request.getfixturevalue(sysname) |
| 571 | + result = sys**power |
| 572 | + if power == 0: |
| 573 | + expected = StateSpace([], [], [], np.eye(2), dt=0) |
| 574 | + else: |
| 575 | + sign = 1 if power > 0 else -1 |
| 576 | + expected = sys**sign |
| 577 | + for i in range(1,abs(power)): |
| 578 | + expected *= sys**sign |
| 579 | + np.testing.assert_allclose(expected.A, result.A) |
| 580 | + np.testing.assert_allclose(expected.B, result.B) |
| 581 | + np.testing.assert_allclose(expected.C, result.C) |
| 582 | + np.testing.assert_allclose(expected.D, result.D) |
| 583 | + |
| 584 | + @slycotonly |
| 585 | + @pytest.mark.parametrize("order", ["inv*sys", "sys*inv"]) |
| 586 | + @pytest.mark.parametrize("sysname", ["sys222", "sys322"]) |
| 587 | + def test_pow_inv(self, request, sysname, order): |
| 588 | + """Power of -1 (inverse of biproper system). |
| 589 | +
|
| 590 | + Testing transfer function representations to avoid the |
| 591 | + non-uniqueness of the state-space representation. Once MIMO |
| 592 | + canonical forms are supported, can check canonical state-space |
| 593 | + matrices instead. |
| 594 | + """ |
| 595 | + sys = request.getfixturevalue(sysname) |
| 596 | + if order == "inv*sys": |
594 | 597 | result = (sys**-1 * sys).minreal() |
595 | | - expected = StateSpace([], [], [], np.eye(2), dt=0) |
596 | | - assert_tf_close_coeff( |
597 | | - ss2tf(expected).minreal(), |
598 | | - ss2tf(result).minreal(), |
599 | | - ) |
600 | | - # Power of 3 |
601 | | - result = sys**3 |
602 | | - expected = sys * sys * sys |
603 | | - np.testing.assert_allclose(expected.A, result.A) |
604 | | - np.testing.assert_allclose(expected.B, result.B) |
605 | | - np.testing.assert_allclose(expected.C, result.C) |
606 | | - np.testing.assert_allclose(expected.D, result.D) |
607 | | - # Power of -3 |
608 | | - result = sys**-3 |
609 | | - expected = sys**-1 * sys**-1 * sys**-
8000
1 |
610 | | - np.testing.assert_allclose(expected.A, result.A) |
611 | | - np.testing.assert_allclose(expected.B, result.B) |
612 | | - np.testing.assert_allclose(expected.C, result.C) |
613 | | - np.testing.assert_allclose(expected.D, result.D) |
| 598 | + else: |
| 599 | + result = (sys * sys**-1).minreal() |
| 600 | + expected = StateSpace([], [], [], np.eye(2), dt=0) |
| 601 | + assert_tf_close_coeff( |
| 602 | + ss2tf(expected).minreal(), |
| 603 | + ss2tf(result).minreal()) |
614 | 604 |
|
615 | 605 | @slycotonly |
616 | 606 | def test_truediv(self, sys222, sys322): |
|
0 commit comments