Example #1
0
    def test_evalfr_siso(self):
        """Evaluate the frequency response of a SISO system at one frequency."""

        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        np.testing.assert_array_almost_equal(evalfr(sys, 1j),
                                             np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(evalfr(sys, 32j),
                                             np.array([[0.00281959302585077 - 0.030628473607392j]]))

        # Test call version as well
        np.testing.assert_almost_equal(sys(1.j), -0.5 - 0.5j)
        np.testing.assert_almost_equal(sys(32.j), 0.00281959302585077 - 0.030628473607392j)

        # Test internal version (with real argument)
        np.testing.assert_array_almost_equal(sys._evalfr(1.),
                                             np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(sys._evalfr(32.),
                                             np.array([[0.00281959302585077 - 0.030628473607392j]]))

        # Deprecated version of the call (should generate warning)
        import warnings
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            sys.evalfr(1.)
            assert len(w) == 1
            assert issubclass(w[-1].category, PendingDeprecationWarning)
Example #2
0
    def testFreqRespMIMO(self):
        """Evaluate the magnitude and phase of a MIMO system at multiple
        frequencies."""

        num = [[[1.0, 2.0], [0.0, 3.0], [2.0, -1.0]], [[1.0], [4.0, 0.0], [1.0, -4.0, 3.0]]]
        den = [[[-3.0, 2.0, 4.0], [1.0, 0.0, 0.0], [2.0, -1.0]], [[3.0, 0.0, 0.0], [2.0, -1.0, -1.0], [1.0]]]
        sys = TransferFunction(num, den)

        trueomega = [0.1, 1.0, 10.0]
        truemag = [
            [[0.496287094505259, 0.307147558416976, 0.0334738176210382], [300.0, 3.0, 0.03], [1.0, 1.0, 1.0]],
            [
                [33.3333333333333, 0.333333333333333, 0.00333333333333333],
                [0.390285696125482, 1.26491106406735, 0.198759144198533],
                [3.01663720059274, 4.47213595499958, 104.92378186093],
            ],
        ]
        truephase = [
            [[3.7128711165168e-4, 0.185347949995695, 1.30770596539255], [-np.pi, -np.pi, -np.pi], [0.0, 0.0, 0.0]],
            [
                [-np.pi, -np.pi, -np.pi],
                [-1.66852323415362, -1.89254688119154, -1.62050658356412],
                [-0.132989648369409, -1.1071487177940, -2.7504672066207],
            ],
        ]

        mag, phase, omega = sys.freqresp(trueomega)

        np.testing.assert_array_almost_equal(mag, truemag)
        np.testing.assert_array_almost_equal(phase, truephase)
        np.testing.assert_array_equal(omega, trueomega)
Example #3
0
 def testFeedback(self):
     h1 = TransferFunction([1], [1, 2, 2])
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(h1, omega)
     np.testing.assert_array_almost_equal(
         f1.feedback(1).freqresp([0.1, 1.0, 10])[0],
         h1.feedback(1).freqresp([0.1, 1.0, 10])[0])
    def test_freqresp_mimo(self):
        """Evaluate the magnitude and phase of a MIMO system at 
        multiple frequencies."""

        num = [[[1., 2.], [0., 3.], [2., -1.]],
               [[1.], [4., 0.], [1., -4., 3.]]]
        den = [[[-3., 2., 4.], [1., 0., 0.], [2., -1.]],
               [[3., 0., .0], [2., -1., -1.], [1.]]]
        sys = TransferFunction(num, den)

        true_omega = [0.1, 1., 10.]
        true_mag = [[[0.49628709, 0.30714755, 0.03347381],
                    [300., 3., 0.03], [1., 1., 1.]],
                    [[33.333333, 0.33333333, 0.00333333],
                     [0.39028569, 1.26491106, 0.19875914],
                    [3.01663720, 4.47213595, 104.92378186]]]
        true_phase = [[[3.7128711e-4, 0.18534794,
                        1.30770596], [-np.pi, -np.pi, -np.pi],
                       [0., 0., 0.]],
                      [[-np.pi, -np.pi, -np.pi],
                       [-1.66852323, -1.89254688, -1.62050658],
                       [-0.13298964, -1.10714871, -2.75046720]]]

        mag, phase, omega = sys.freqresp(true_omega)

        np.testing.assert_array_almost_equal(mag, true_mag)
        np.testing.assert_array_almost_equal(phase, true_phase)
        np.testing.assert_array_equal(omega, true_omega)
Example #5
0
    def testPoleMIMO(self):
        """Test for correct MIMO poles."""

        sys = TransferFunction([[[1.], [1.]], [[1.], [1.]]],
            [[[1., 2.], [1., 3.]], [[1., 4., 4.], [1., 9., 14.]]])
        p = sys.pole()

        np.testing.assert_array_almost_equal(p, [-7., -3., -2., -2.])
Example #6
0
    def testEvalFrSISO(self):
        """Evaluate the frequency response of a SISO system at one frequency."""

        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        np.testing.assert_array_almost_equal(sys.evalfr(1.),
            np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(sys.evalfr(32.),
            np.array([[0.00281959302585077 - 0.030628473607392j]]))
Example #7
0
 def testSISOtf(self):
     # get a SISO transfer function
     h = TransferFunction([1], [1, 2, 2])
     omega = np.logspace(-1, 2, 10)
     frd = FRD(h, omega)
     assert isinstance(frd, FRD)
     
     np.testing.assert_array_almost_equal(
         frd.freqresp([1.0]), h.freqresp([1.0]))
Example #8
0
    def testPoleMIMO(self):
        """Test for correct MIMO poles."""

        sys = TransferFunction(
            [[[1.0], [1.0]], [[1.0], [1.0]]], [[[1.0, 2.0], [1.0, 3.0]], [[1.0, 4.0, 4.0], [1.0, 9.0, 14.0]]]
        )
        p = sys.pole()

        np.testing.assert_array_almost_equal(p, [-7.0, -3.0, -2.0, -2.0])
Example #9
0
    def test_divide_siso(self):
        """Divide two SISO systems."""
        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1])
        sys2 = TransferFunction([[[-1., 3.]]], [[[1., 0., -1.]]])
        sys3 = sys1 / sys2
        sys4 = sys2 / sys1

        np.testing.assert_array_equal(sys3.num, [[[1., 3., 4., -3., -5.]]])
        np.testing.assert_array_equal(sys3.den, [[[-1., -3., 16., 7., -3.]]])
        np.testing.assert_array_equal(sys4.num, sys3.den)
        np.testing.assert_array_equal(sys4.den, sys3.num)
Example #10
0
    def testEvalFrSISO(self):
        """Evaluate the frequency response of a SISO system at one frequency."""

        sys = TransferFunction([1.0, 3.0, 5], [1.0, 6.0, 2.0, -1])

        np.testing.assert_array_almost_equal(sys.evalfr(1.0), np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(sys.evalfr(32.0), np.array([[0.00281959302585077 - 0.030628473607392j]]))

        # Test call version as well
        np.testing.assert_almost_equal(sys(1.0j), -0.5 - 0.5j)
        np.testing.assert_almost_equal(sys(32.0j), 0.00281959302585077 - 0.030628473607392j)
Example #11
0
    def testMulInconsistentDimension(self):
        """Multiply two transfer function matrices of incompatible sizes."""

        sys1 = TransferFunction([[[1., 2.], [4., 5.]], [[2., 5.], [4., 3.]]],
            [[[6., 2.], [4., 1.]], [[6., 7.], [2., 4.]]])
        sys2 = TransferFunction([[[1.]], [[2.]], [[3.]]],
            [[[4.]], [[5.]], [[6.]]])
        self.assertRaises(ValueError, sys1.__mul__, sys2)
        self.assertRaises(ValueError, sys2.__mul__, sys1)
        self.assertRaises(ValueError, sys1.__rmul__, sys2)
        self.assertRaises(ValueError, sys2.__rmul__, sys1)
 def test_mag_phase_omega(self):
     # test for bug reported in gh-58
     sys = TransferFunction(15, [1, 6, 11, 6])
     out = stability_margins(sys)
     omega = np.logspace(-1,1,100)
     mag, phase, omega = sys.freqresp(omega)
     out2 = stability_margins((mag, phase*180/np.pi, omega))
     ind = [0,1,3,4]   # indices of gm, pm, wg, wp -- ignore sm
     marg1 = np.array(out)[ind]
     marg2 = np.array(out2)[ind]
     np.testing.assert_array_almost_equal(marg1, marg2, 4)
Example #13
0
    def test_subtract_siso(self):
        """Subtract two SISO systems."""
        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1])
        sys2 = TransferFunction([[np.array([-1., 3.])]], [[[1., 0., -1.]]])
        sys3 = sys1 - sys2
        sys4 = sys2 - sys1

        np.testing.assert_array_equal(sys3.num, [[[2., 6., -12., -10., -2.]]])
        np.testing.assert_array_equal(sys3.den, [[[1., 6., 1., -7., -2., 1.]]])
        np.testing.assert_array_equal(sys4.num, [[[-2., -6., 12., 10., 2.]]])
        np.testing.assert_array_equal(sys4.den, [[[1., 6., 1., -7., -2., 1.]]])
Example #14
0
def test_mag_phase_omega():
    """Test for bug reported in gh-58"""
    sys = TransferFunction(15, [1, 6, 11, 6])
    out = stability_margins(sys)
    omega = np.logspace(-2, 2, 1000)
    mag, phase, omega = sys.freqresp(omega)
    out2 = stability_margins((mag, phase * 180 / np.pi, omega))
    ind = [0, 1, 3, 4]  # indices of gm, pm, wg, wp -- ignore sm
    marg1 = np.array(out)[ind]
    marg2 = np.array(out2)[ind]
    assert_allclose(marg1, marg2, atol=1.5e-3)
Example #15
0
    def test_multiply_siso(self):
        """Multiply two SISO systems."""
        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1])
        sys2 = TransferFunction([[[-1., 3.]]], [[[1., 0., -1.]]])
        sys3 = sys1 * sys2
        sys4 = sys2 * sys1

        np.testing.assert_array_equal(sys3.num, [[[-1., 0., 4., 15.]]])
        np.testing.assert_array_equal(sys3.den, [[[1., 6., 1., -7., -2., 1.]]])
        np.testing.assert_array_equal(sys3.num, sys4.num)
        np.testing.assert_array_equal(sys3.den, sys4.den)
Example #16
0
    def test_multiply_scalar(self):
        """Multiply two direct feedthrough systems."""
        sys1 = TransferFunction(2., [1.])
        sys2 = TransferFunction(1., 4.)
        sys3 = sys1 * sys2
        sys4 = sys1 * sys2

        np.testing.assert_array_equal(sys3.num, [[[2.]]])
        np.testing.assert_array_equal(sys3.den, [[[4.]]])
        np.testing.assert_array_equal(sys3.num, sys4.num)
        np.testing.assert_array_equal(sys3.den, sys4.den)
Example #17
0
    def testFeedback(self):
        h1 = TransferFunction([1], [1, 2, 2])
        omega = np.logspace(-1, 2, 10)
        f1 = FRD(h1, omega)
        np.testing.assert_array_almost_equal(
            f1.feedback(1).frequency_response([0.1, 1.0, 10])[0],
            h1.feedback(1).frequency_response([0.1, 1.0, 10])[0])

        # Make sure default argument also works
        np.testing.assert_array_almost_equal(
            f1.feedback().frequency_response([0.1, 1.0, 10])[0],
            h1.feedback().frequency_response([0.1, 1.0, 10])[0])
Example #18
0
    def test_feedback_siso(self):
        """Test for correct SISO transfer function feedback."""
        sys1 = TransferFunction([-1., 4.], [1., 3., 5.])
        sys2 = TransferFunction([2., 3., 0.], [1., -3., 4., 0])

        sys3 = sys1.feedback(sys2)
        sys4 = sys1.feedback(sys2, 1)

        np.testing.assert_array_equal(sys3.num, [[[-1., 7., -16., 16., 0.]]])
        np.testing.assert_array_equal(sys3.den, [[[1., 0., -2., 2., 32., 0.]]])
        np.testing.assert_array_equal(sys4.num, [[[-1., 7., -16., 16., 0.]]])
        np.testing.assert_array_equal(sys4.den, [[[1., 0., 2., -8., 8., 0.]]])
Example #19
0
    def testSISOtf(self):
        # get a SISO transfer function
        h = TransferFunction([1], [1, 2, 2])
        omega = np.logspace(-1, 2, 10)
        frd = FRD(h, omega)
        assert isinstance(frd, FRD)

        mag1, phase1, omega1 = frd.frequency_response([1.0])
        mag2, phase2, omega2 = h.frequency_response([1.0])
        np.testing.assert_array_almost_equal(mag1, mag2)
        np.testing.assert_array_almost_equal(phase1, phase2)
        np.testing.assert_array_almost_equal(omega1, omega2)
Example #20
0
 def test_mag_phase_omega(self):
     # test for bug reported in gh-58
     sys = TransferFunction(15, [1, 6, 11, 6])
     out = stability_margins(sys)
     omega = np.logspace(-2, 2, 1000)
     mag, phase, omega = sys.freqresp(omega)
     #print( mag, phase, omega)
     out2 = stability_margins((mag, phase * 180 / np.pi, omega))
     ind = [0, 1, 3, 4]  # indices of gm, pm, wg, wp -- ignore sm
     marg1 = np.array(out)[ind]
     marg2 = np.array(out2)[ind]
     assert_array_almost_equal(marg1, marg2, 4)
Example #21
0
    def testFeedbackSISO(self):
        """Test for correct SISO transfer function feedback."""

        sys1 = TransferFunction([-1.0, 4.0], [1.0, 3.0, 5.0])
        sys2 = TransferFunction([2.0, 3.0, 0.0], [1.0, -3.0, 4.0, 0])

        sys3 = sys1.feedback(sys2)
        sys4 = sys1.feedback(sys2, 1)

        np.testing.assert_array_equal(sys3.num, [[[-1.0, 7.0, -16.0, 16.0, 0.0]]])
        np.testing.assert_array_equal(sys3.den, [[[1.0, 0.0, -2.0, 2.0, 32.0, 0.0]]])
        np.testing.assert_array_equal(sys4.num, [[[-1.0, 7.0, -16.0, 16.0, 0.0]]])
        np.testing.assert_array_equal(sys4.den, [[[1.0, 0.0, 2.0, -8.0, 8.0, 0.0]]])
Example #22
0
    def testFeedbackSISO(self):
        """Test for correct SISO transfer function feedback."""

        sys1 = TransferFunction([-1., 4.], [1., 3., 5.])
        sys2 = TransferFunction([2., 3., 0.], [1., -3., 4., 0])

        sys3 = sys1.feedback(sys2)
        sys4 = sys1.feedback(sys2, 1)

        np.testing.assert_array_equal(sys3.num, [[[-1., 7., -16., 16., 0.]]])
        np.testing.assert_array_equal(sys3.den, [[[1., 0., -2., 2., 32., 0.]]])
        np.testing.assert_array_equal(sys4.num, [[[-1., 7., -16., 16., 0.]]])
        np.testing.assert_array_equal(sys4.den, [[[1., 0., 2., -8., 8., 0.]]])
    def test_constructor_nodt(self):
        """Test the constructor when an object without dt is passed"""
        sysin = TransferFunction([[[0., 1.], [2., 3.]]],
                                 [[[5., 2.], [3., 0.]]])
        del sysin.dt
        sys = TransferFunction(sysin)
        assert sys.dt == defaults['control.default_dt']

        # test for static gain
        sysin = TransferFunction([[[2.], [3.]]], [[[1.], [.1]]])
        del sysin.dt
        sys = TransferFunction(sysin)
        assert sys.dt is None
Example #24
0
    def testEvalFrMIMO(self):
        """Evaluate the frequency response of a MIMO system at one frequency."""

        num = [[[1., 2.], [0., 3.], [2., -1.]],
               [[1.], [4., 0.], [1., -4., 3.]]]
        den = [[[-3., 2., 4.], [1., 0., 0.], [2., -1.]],
               [[3., 0., .0], [2., -1., -1.], [1.]]]
        sys = TransferFunction(num, den)
        resp = [[0.147058823529412 + 0.0882352941176471j, -0.75, 1.],
                [-0.083333333333333, -0.188235294117647 - 0.847058823529412j,
                 -1. - 8.j]]
        
        np.testing.assert_array_almost_equal(sys.evalfr(2.), resp)
    def testEvalFrSISO(self):
        """Evaluate the frequency response of a SISO system at one frequency."""

        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        np.testing.assert_array_almost_equal(sys.evalfr(1.),
            np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(sys.evalfr(32.),
            np.array([[0.00281959302585077 - 0.030628473607392j]]))

        # Test call version as well
        np.testing.assert_almost_equal(sys(1.j), -0.5 - 0.5j)
        np.testing.assert_almost_equal(sys(32.j),
            0.00281959302585077 - 0.030628473607392j)
Example #26
0
    def test_freqresp_siso(self):
        """Evaluate the SISO magnitude and phase at multiple frequencies"""
        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        truemag = [[[4.63507337473906, 0.707106781186548, 0.0866592803995351]]]
        truephase = [[[-2.89596891081488, -2.35619449019234,
                       -1.32655885133871]]]
        trueomega = [0.1, 1., 10.]

        mag, phase, omega = sys.freqresp(trueomega)

        np.testing.assert_array_almost_equal(mag, truemag)
        np.testing.assert_array_almost_equal(phase, truephase)
        np.testing.assert_array_almost_equal(omega, trueomega)
Example #27
0
 def plant(self, request):
     plants = {
         'syscont':
         TransferFunction(1, [1, 3, 0]),
         'sysdisc1':
         c2d(TransferFunction(1, [1, 3, 0]), .1),
         'syscont221':
         StateSpace([[-.3, 0], [1, 0]], [[
             -1,
         ], [
             .1,
         ]], [0, -.3], 0)
     }
     return plants[request.param]
    def test__isstatic(self):
        numstatic = 1.1
        denstatic = 1.2
        numdynamic = [1, 1]
        dendynamic = [2, 1]
        numstaticmimo = [[[
            1.1,
        ], [
            1.2,
        ]], [[
            1.2,
        ], [
            0.8,
        ]]]
        denstaticmimo = [[[
            1.9,
        ], [
            1.2,
        ]], [[
            1.2,
        ], [
            0.8,
        ]]]
        numdynamicmimo = [[[1.1, 0.9], [1.2]], [[1.2], [0.8]]]
        dendynamicmimo = [[[1.1, 0.7], [0.2]], [[1.2], [0.8]]]
        assert TransferFunction(numstatic, denstatic)._isstatic()
        assert TransferFunction(numstaticmimo, denstaticmimo)._isstatic()

        assert not TransferFunction(numstatic, dendynamic)._isstatic()
        assert not TransferFunction(numdynamic, dendynamic)._isstatic()
        assert not TransferFunction(numdynamic, denstatic)._isstatic()
        assert not TransferFunction(numstatic, dendynamic)._isstatic()

        assert not TransferFunction(numstaticmimo, dendynamicmimo)._isstatic()
        assert not TransferFunction(numdynamicmimo, denstaticmimo)._isstatic()
Example #29
0
    def test_repr(self, Hargs, ref):
        """Test __repr__ printout."""
        H = TransferFunction(*Hargs)

        assert repr(H) == ref

        # and reading back
        array = np.array  # noqa
        H2 = eval(H.__repr__())
        for p in range(len(H.num)):
            for m in range(len(H.num[0])):
                np.testing.assert_array_almost_equal(H.num[p][m], H2.num[p][m])
                np.testing.assert_array_almost_equal(H.den[p][m], H2.den[p][m])
            assert H.dt == H2.dt
    def test_common_den(self):
        """ Test the helper function to compute common denomitators."""

        # _common_den() computes the common denominator per input/column.
        # The testing columns are:
        # 0: no common poles
        # 1: regular common poles
        # 2: poles with multiplicity,
        # 3: complex poles
        # 4: complex poles below threshold

        eps = np.finfo(float).eps
        tol_imag = np.sqrt(eps * 5 * 2 * 2) * 0.9

        numin = [[[1.], [1.], [1.], [1.], [1.]], [[1.], [1.], [1.], [1.],
                                                  [1.]]]
        denin = [
            [
                [1., 3., 2.],  # 0: poles: [-1, -2]
                [1., 6., 11., 6.],  # 1: poles: [-1, -2, -3]
                [1., 6., 11., 6.],  # 2: poles: [-1, -2, -3]
                [1., 6., 11., 6.],  # 3: poles: [-1, -2, -3]
                [1., 6., 11., 6.]
            ],  # 4: poles: [-1, -2, -3],
            [
                [1., 12., 47., 60.],  # 0: poles: [-3, -4, -5]
                [1., 9., 26., 24.],  # 1: poles: [-2, -3, -4]
                [1., 7., 16., 12.],  # 2: poles: [-2, -2, -3]
                [1., 7., 17., 15.],  # 3: poles: [-2+1J, -2-1J, -3],
                np.poly([-2 + tol_imag * 1J, -2 - tol_imag * 1J, -3])
            ]
        ]
        numref = np.array([[[0., 0., 1., 12., 47., 60.],
                            [0., 0., 0., 1., 4., 0.], [0., 0., 0., 1., 2., 0.],
                            [0., 0., 0., 1., 4., 5.], [0., 0., 0., 1., 2.,
                                                       0.]],
                           [[0., 0., 0., 1., 3., 2.], [0., 0., 0., 1., 1., 0.],
                            [0., 0., 0., 1., 1., 0.], [0., 0., 0., 1., 3., 2.],
                            [0., 0., 0., 1., 1., 0.]]])
        denref = np.array([[1., 15., 85., 225., 274., 120.],
                           [1., 10., 35., 50., 24., 0.],
                           [1., 8., 23., 28., 12., 0.],
                           [1., 10., 40., 80., 79., 30.],
                           [1., 8., 23., 28., 12., 0.]])
        sys = TransferFunction(numin, denin)
        num, den, denorder = sys._common_den()
        np.testing.assert_array_almost_equal(num[:2, :, :], numref)
        np.testing.assert_array_almost_equal(num[2:, :, :], np.zeros(
            (3, 5, 6)))
        np.testing.assert_array_almost_equal(den, denref)
Example #31
0
    def test_step_robustness(self):
        "Unit test: https://github.com/python-control/python-control/issues/240"
        # Create 2 input, 2 output system
        num = [[[0], [1]], [[1], [0]]]

        den1 = [[[1], [1, 1]], [[1, 4], [1]]]
        sys1 = TransferFunction(num, den1)

        den2 = [[[1], [1e-10, 1, 1]], [[1, 4], [1]]]  # slight perturbation
        sys2 = TransferFunction(num, den2)

        # Compute step response from input 1 to output 1, 2
        t1, y1 = step_response(sys1, input=0)
        t2, y2 = step_response(sys2, input=0)
        np.testing.assert_array_almost_equal(y1, y2)
Example #32
0
    def testEvalFrMIMO(self):
        """Evaluate the frequency response of a MIMO system at one frequency."""

        num = [[[1.0, 2.0], [0.0, 3.0], [2.0, -1.0]], [[1.0], [4.0, 0.0], [1.0, -4.0, 3.0]]]
        den = [[[-3.0, 2.0, 4.0], [1.0, 0.0, 0.0], [2.0, -1.0]], [[3.0, 0.0, 0.0], [2.0, -1.0, -1.0], [1.0]]]
        sys = TransferFunction(num, den)
        resp = [
            [0.147058823529412 + 0.0882352941176471j, -0.75, 1.0],
            [-0.083333333333333, -0.188235294117647 - 0.847058823529412j, -1.0 - 8.0j],
        ]

        np.testing.assert_array_almost_equal(sys.evalfr(2.0), resp)

        # Test call version as well
        np.testing.assert_array_almost_equal(sys(2.0j), resp)
Example #33
0
    def testFreqRespSISO(self):
        """Evaluate the magnitude and phase of a SISO system at multiple
        frequencies."""

        sys = TransferFunction([1.0, 3.0, 5], [1.0, 6.0, 2.0, -1])

        truemag = [[[4.63507337473906, 0.707106781186548, 0.0866592803995351]]]
        truephase = [[[-2.89596891081488, -2.35619449019234, -1.32655885133871]]]
        trueomega = [0.1, 1.0, 10.0]

        mag, phase, omega = sys.freqresp(trueomega)

        np.testing.assert_array_almost_equal(mag, truemag)
        np.testing.assert_array_almost_equal(phase, truephase)
        np.testing.assert_array_almost_equal(omega, trueomega)
Example #34
0
    def test_evalfr_mimo(self):
        """Evaluate the frequency response of a MIMO system at a freq"""
        num = [[[1., 2.], [0., 3.], [2., -1.]],
               [[1.], [4., 0.], [1., -4., 3.]]]
        den = [[[-3., 2., 4.], [1., 0., 0.], [2., -1.]],
               [[3., 0., .0], [2., -1., -1.], [1.]]]
        sys = TransferFunction(num, den)
        resp = [[0.147058823529412 + 0.0882352941176471j, -0.75, 1.],
                [-0.083333333333333, -0.188235294117647 - 0.847058823529412j,
                 -1. - 8.j]]

        np.testing.assert_array_almost_equal(sys._evalfr(2.), resp)

        # Test call version as well
        np.testing.assert_array_almost_equal(sys(2.j), resp)
Example #35
0
    def testTruncateCoeff2(self):
        """Remove extraneous zeros in polynomial representations."""

        sys1 = TransferFunction([0., 0., 0.], 1.)

        np.testing.assert_array_equal(sys1.num, [[[0.]]])
        np.testing.assert_array_equal(sys1.den, [[[1.]]])
Example #36
0
    def test_phase_crossover_frequencies(self):
        omega, gain = phase_crossover_frequencies(self.sys2)
        np.testing.assert_array_almost_equal(omega, [1.73205, 0.])
        np.testing.assert_array_almost_equal(gain, [-0.5, 0.25])

        tf = TransferFunction([1], [1, 1])
        omega, gain = phase_crossover_frequencies(tf)
        np.testing.assert_array_almost_equal(omega, [0.])
        np.testing.assert_array_almost_equal(gain, [1.])

        # testing MIMO, only (0,0) element is considered
        tf = TransferFunction([[[1], [2]], [[3], [4]]],
                              [[[1, 2, 3, 4], [1, 1]], [[1, 1], [1, 1]]])
        omega, gain = phase_crossover_frequencies(tf)
        np.testing.assert_array_almost_equal(omega, [1.73205081, 0.])
        np.testing.assert_array_almost_equal(gain, [-0.5, 0.25])
 def test_constructor_double_dt(self):
     """Test that providing dt as arg and kwarg prefers arg with warning"""
     with pytest.warns(UserWarning,
                       match="received multiple dt.*"
                       "using positional arg"):
         sys = TransferFunction(1, [1, 2, 3], 0.1, dt=0.2)
     assert sys.dt == 0.1
Example #38
0
    def test_call_siso(self, dt, omega, resp):
        """Evaluate the frequency response of a SISO system at one frequency."""
        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        if dt:
            sys = sample_system(sys, dt)
            s = np.exp(omega * 1j * dt)
        else:
            s = omega * 1j

        # Correct versions of the call
        np.testing.assert_allclose(evalfr(sys, s), resp, atol=1e-3)
        np.testing.assert_allclose(sys(s), resp, atol=1e-3)
        # Deprecated version of the call (should generate exception)
        with pytest.raises(AttributeError):
            np.testing.assert_allclose(sys.evalfr(omega), resp, atol=1e-3)
Example #39
0
    def test_slice(self):
        sys = TransferFunction(
            [ [   [1],    [2],    [3]], [   [3],    [4],    [5]] ],
            [ [[1, 2], [1, 3], [1, 4]], [[1, 4], [1, 5], [1, 6]] ])
        sys1 = sys[1:, 1:]
        assert (sys1.ninputs, sys1.noutputs) == (2, 1)

        sys2 = sys[:2, :2]
        assert (sys2.ninputs, sys2.noutputs) == (2, 2)

        sys = TransferFunction(
            [ [   [1],    [2],    [3]], [   [3],    [4],    [5]] ],
            [ [[1, 2], [1, 3], [1, 4]], [[1, 4], [1, 5], [1, 6]] ], 0.5)
        sys1 = sys[1:, 1:]
        assert (sys1.ninputs, sys1.noutputs) == (2, 1)
        assert sys1.dt == 0.5
Example #40
0
    def test_reverse_sign_siso(self):
        """Negate a SISO system."""
        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1.])
        sys2 = - sys1

        np.testing.assert_array_equal(sys2.num, [[[-1., -3., -5.]]])
        np.testing.assert_array_equal(sys2.den, [[[1., 6., 2., -1.]]])
Example #41
0
    def test_reverse_sign_scalar(self):
        """Negate a direct feedthrough system."""
        sys1 = TransferFunction(2., np.array([-3.]))
        sys2 = - sys1

        np.testing.assert_array_equal(sys2.num, [[[-2.]]])
        np.testing.assert_array_equal(sys2.den, [[[-3.]]])
Example #42
0
    def test_root_locus_zoom(self):
        """Check the zooming functionality of the Root locus plot"""
        system = TransferFunction([1000], [1, 25, 100, 0])
        plt.figure()
        root_locus(system)
        fig = plt.gcf()
        ax_rlocus = fig.axes[0]

        event = type(
            'test', (object, ), {
                'xdata': 14.7607954359,
                'ydata': -35.6171379864,
                'inaxes': ax_rlocus.axes
            })()
        ax_rlocus.set_xlim((-10.813628105112421, 14.760795435937652))
        ax_rlocus.set_ylim((-35.61713798641108, 33.879716621220311))
        plt.get_current_fig_manager().toolbar.mode = 'zoom rect'
        _RLClickDispatcher(event, system, fig, ax_rlocus, '-')

        zoom_x = ax_rlocus.lines[-2].get_data()[0][0:5]
        zoom_y = ax_rlocus.lines[-2].get_data()[1][0:5]
        zoom_y = [abs(y) for y in zoom_y]

        zoom_x_valid = [
            -5., -4.61281263, -4.16689986, -4.04122642, -3.90736502
        ]
        zoom_y_valid = [0., 0., 0., 0., 0.]

        assert_array_almost_equal(zoom_x, zoom_x_valid)
        assert_array_almost_equal(zoom_y, zoom_y_valid)
Example #43
0
    def test_truncate_coefficients_null_numerator(self):
        """Remove extraneous zeros in polynomial representations."""

        sys1 = TransferFunction([0., 0., 0.], 1.)

        np.testing.assert_array_equal(sys1.num, [[[0.]]])
        np.testing.assert_array_equal(sys1.den, [[[1.]]])
Example #44
0
 def test_frd(self):
     f = np.array([
         0.005, 0.010, 0.020, 0.030, 0.040, 0.050, 0.060, 0.070, 0.080,
         0.090, 0.100, 0.200, 0.300, 0.400, 0.500, 0.750, 1.000, 1.250,
         1.500, 1.750, 2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500,
         3.750, 4.000, 4.250, 4.500, 4.750, 5.000, 6.000, 7.000, 8.000,
         9.000, 10.000
     ])
     gain = np.array([
         0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2,
         0.3, 0.5, 0.5, -0.4, -2.3, -4.8, -7.3, -9.6, -11.7, -13.6, -15.3,
         -16.9, -18.3, -19.6, -20.8, -22.0, -23.1, -24.1, -25.0, -25.9,
         -29.1, -31.9, -34.2, -36.2, -38.1
     ])
     phase = np.array([
         0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -19, -29, -40, -51,
         -81, -114, -144, -168, -187, -202, -214, -224, -233, -240, -247,
         -253, -259, -264, -269, -273, -277, -280, -292, -301, -307, -313,
         -317
     ])
     # calculate response as complex number
     resp = 10**(gain / 20) * np.exp(1j * phase / (180. / np.pi))
     # frequency response data
     fresp = FRD(resp, f * 2 * np.pi, smooth=True)
     s = TransferFunction([1, 0], [1])
     G = 1. / (s**2)
     K = 1.
     C = K * (1 + 1.9 * s)
     TFopen = fresp * C * G
     gm, pm, sm, wg, wp, ws = stability_margins(TFopen)
     assert_array_almost_equal([pm], [44.55], 2)
Example #45
0
    def test_slice(self):
        sys = TransferFunction(
            [[[1], [2], [3]], [[3], [4], [5]]],
            [[[1, 2], [1, 3], [1, 4]], [[1, 4], [1, 5], [1, 6]]])
        sys1 = sys[1:, 1:]
        self.assertEqual((sys1.inputs, sys1.outputs), (2, 1))

        sys2 = sys[:2, :2]
        self.assertEqual((sys2.inputs, sys2.outputs), (2, 2))

        sys = TransferFunction(
            [[[1], [2], [3]], [[3], [4], [5]]],
            [[[1, 2], [1, 3], [1, 4]], [[1, 4], [1, 5], [1, 6]]], 0.5)
        sys1 = sys[1:, 1:]
        self.assertEqual((sys1.inputs, sys1.outputs), (2, 1))
        self.assertEqual(sys1.dt, 0.5)
    def test_evalfr_siso(self):
        """Evaluate the frequency response of a SISO system at one frequency."""

        sys = TransferFunction([1., 3., 5], [1., 6., 2., -1])

        np.testing.assert_array_almost_equal(evalfr(sys, 1j),
                                             np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(
            evalfr(sys, 32j),
            np.array([[0.00281959302585077 - 0.030628473607392j]]))

        # Test call version as well
        np.testing.assert_almost_equal(sys(1.j), -0.5 - 0.5j)
        np.testing.assert_almost_equal(
            sys(32.j), 0.00281959302585077 - 0.030628473607392j)

        # Test internal version (with real argument)
        np.testing.assert_array_almost_equal(
            sys._evalfr(1.), np.array([[-0.5 - 0.5j]]))
        np.testing.assert_array_almost_equal(
            sys._evalfr(32.),
            np.array([[0.00281959302585077 - 0.030628473607392j]]))
Example #47
0
    def test_dcgain(self):
        sys = TransferFunction(6, 3)
        np.testing.assert_equal(sys.dcgain(), 2)

        sys2 = TransferFunction(6, [1, 3])
        np.testing.assert_equal(sys2.dcgain(), 2)

        sys3 = TransferFunction(6, [1, 0])
        np.testing.assert_equal(sys3.dcgain(), np.inf)

        num = [[[15], [21], [33]], [[10], [14], [22]]]
        den = [[[1, 3], [2, 3], [3, 3]], [[1, 5], [2, 7], [3, 11]]]
        sys4 = TransferFunction(num, den)
        expected = [[5, 7, 11], [2, 2, 2]]
        np.testing.assert_array_equal(sys4.dcgain(), expected)
Example #48
0
    def test_dcgain_discr(self):
        """Test DC gain for discrete-time transfer functions"""
        # static gain
        sys = TransferFunction(6, 3, True)
        np.testing.assert_equal(sys.dcgain(), 2)

        # averaging filter
        sys = TransferFunction(0.5, [1, -0.5], True)
        np.testing.assert_almost_equal(sys.dcgain(), 1)

        # differencer
        sys = TransferFunction(1, [1, -1], True)
        np.testing.assert_equal(sys.dcgain(), np.inf)

        # summer
        # causes a RuntimeWarning due to the divide by zero
        sys = TransferFunction([1,-1], [1], True)
        np.testing.assert_equal(sys.dcgain(), 0)
    def test_div(self):
        # Make sure that sampling times work correctly
        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1])
        sys2 = TransferFunction([[[-1., 3.]]], [[[1., 0., -1.]]], True)
        sys3 = sys1 / sys2
        self.assertEqual(sys3.dt, True)

        sys2 = TransferFunction([[[-1., 3.]]], [[[1., 0., -1.]]], 0.5)
        sys3 = sys1 / sys2
        self.assertEqual(sys3.dt, 0.5)

        sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1], 0.1)
        self.assertRaises(ValueError, TransferFunction.__truediv__, sys1, sys2)

        sys1 = sample_system(rss(4, 1, 1), 0.5)
        sys3 = TransferFunction.__rtruediv__(sys2, sys1)
        self.assertEqual(sys3.dt, 0.5)
Example #50
0
 def test_double_cancelling_poles_siso(self):
     
     H = TransferFunction([1, 1], [1, 2, 1])
     p = H.pole()
     np.testing.assert_array_almost_equal(p, [-1, -1])