def test_point_to_point(self):
        # Machine precision for floats.
        eps = np.finfo(float).eps

        for states in range(1, self.maxStates):
            # Start with a random system
            linsys = matlab.rss(states, 1, 1)

            # Make sure the system is not degenerate
            Cmat = ctrl.ctrb(linsys.A, linsys.B)
            if (np.linalg.matrix_rank(Cmat) != states):
                if (self.debug):
                    print("  skipping (not reachable)")
                    continue

            if (self.debug): print(linsys)

            # Create a flat system representation
            flatsys = tg.LinearFlatSystem(linsys)

            # Generate several different initial and final conditions
            for i in range(self.numTests):
                x0 = np.random.rand(linsys.states)
                xf = np.random.rand(linsys.states)
                Tf = np.random.randn()

                # Generate a trajectory from start to stop
                systraj = tg.point_to_point(flatsys, x0, xf, Tf)
                xd, ud = systraj.eval((0,Tf))
                np.testing.assert_array_almost_equal(x0, xd[0,:], decimal=4)
                np.testing.assert_array_almost_equal(xf, xd[1,:], decimal=4)
Пример #2
0
    def test_discrete(self):
        # Test discrete time frequency response

        # SISO state space systems with either fixed or unspecified sampling times
        sys = rss(3, 1, 1)
        siso_ss1d = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.1)
        siso_ss2d = StateSpace(sys.A, sys.B, sys.C, sys.D, True)

        # MIMO state space systems with either fixed or unspecified sampling times
        A = [[-3., 4., 2.], [-1., -3., 0.], [2., 5., 3.]]
        B = [[1., 4.], [-3., -3.], [-2., 1.]]
        C = [[4., 2., -3.], [1., 4., 3.]]
        D = [[-2., 4.], [0., 1.]]
        mimo_ss1d = StateSpace(A, B, C, D, 0.1)
        mimo_ss2d = StateSpace(A, B, C, D, True)

        # SISO transfer functions
        siso_tf1d = TransferFunction([1, 1], [1, 2, 1], 0.1)
        siso_tf2d = TransferFunction([1, 1], [1, 2, 1], True)

        # Go through each system and call the code, checking return types
        for sys in (siso_ss1d, siso_ss2d, mimo_ss1d, mimo_ss2d, siso_tf1d,
                    siso_tf2d):
            # Set frequency range to just below Nyquist freq (for Bode)
            omega_ok = np.linspace(10e-4, 0.99, 100) * np.pi / sys.dt

            # Test frequency response
            ret = sys.freqresp(omega_ok)

            # Check for warning if frequency is out of range
            import warnings
            warnings.simplefilter('always', UserWarning)  # don't supress
            with warnings.catch_warnings(record=True) as w:
                # Set up warnings filter to only show warnings in control module
                warnings.filterwarnings("ignore")
                warnings.filterwarnings("always", module="control")

                # Look for a warning about sampling above Nyquist frequency
                omega_bad = np.linspace(10e-4, 1.1, 10) * np.pi / sys.dt
                ret = sys.freqresp(omega_bad)
                print("len(w) =", len(w))
                self.assertEqual(len(w), 1)
                self.assertIn("above", str(w[-1].message))
                self.assertIn("Nyquist", str(w[-1].message))

            # Test bode plots (currently only implemented for SISO)
            if (sys.inputs == 1 and sys.outputs == 1):
                # Generic call (frequency range calculated automatically)
                ret_ss = bode(sys)

                # Convert to transfer function and test bode again
                systf = tf(sys)
                ret_tf = bode(systf)

                # Make sure we can pass a frequency range
                bode(sys, omega_ok)

            else:
                # Calling bode should generate a not implemented error
                self.assertRaises(NotImplementedError, bode, (sys, ))
Пример #3
0
    def testMinrealBrute(self):
        for n, m, p in permutations(range(1, 6), 3):
            s = matlab.rss(n, p, m)
            sr = s.minreal()
            if s.states > sr.states:
                self.nreductions += 1
            else:
                np.testing.assert_array_almost_equal(np.sort(eigvals(s.A)),
                                                     np.sort(eigvals(sr.A)))
                for i in range(m):
                    for j in range(p):
                        ht1 = matlab.tf(
                            matlab.ss(s.A, s.B[:, i], s.C[j, :], s.D[j, i]))
                        ht2 = matlab.tf(
                            matlab.ss(sr.A, sr.B[:, i], sr.C[j, :], sr.D[j,
                                                                         i]))
                        try:
                            self.assert_numden_almost_equal(
                                ht1.num[0][0], ht2.num[0][0], ht1.den[0][0],
                                ht2.den[0][0])
                        except Exception as e:
                            # for larger systems, the tf minreal's
                            # the original rss, but not the balanced one
                            if n < 6:
                                raise e

        self.assertEqual(self.nreductions, 2)
Пример #4
0
   def test_discrete(self):
      # Test discrete time frequency response

      # SISO state space systems with either fixed or unspecified sampling times
      sys = rss(3, 1, 1)
      siso_ss1d = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.1)
      siso_ss2d = StateSpace(sys.A, sys.B, sys.C, sys.D, True)

      # MIMO state space systems with either fixed or unspecified sampling times
      A = [[-3., 4., 2.], [-1., -3., 0.], [2., 5., 3.]]
      B = [[1., 4.], [-3., -3.], [-2., 1.]]
      C = [[4., 2., -3.], [1., 4., 3.]]
      D = [[-2., 4.], [0., 1.]]
      mimo_ss1d = StateSpace(A, B, C, D, 0.1)
      mimo_ss2d = StateSpace(A, B, C, D, True)

      # SISO transfer functions
      siso_tf1d = TransferFunction([1, 1], [1, 2, 1], 0.1)
      siso_tf2d = TransferFunction([1, 1], [1, 2, 1], True)

      # Go through each system and call the code, checking return types
      for sys in (siso_ss1d, siso_ss2d, mimo_ss1d, mimo_ss2d,
                siso_tf1d, siso_tf2d):
         # Set frequency range to just below Nyquist freq (for Bode)
         omega_ok = np.linspace(10e-4,0.99,100) * np.pi/sys.dt

         # Test frequency response
         ret = sys.freqresp(omega_ok)

         # Check for warning if frequency is out of range
         import warnings
         warnings.simplefilter('always', UserWarning)   # don't supress
         with warnings.catch_warnings(record=True) as w:
            # Set up warnings filter to only show warnings in control module
            warnings.filterwarnings("ignore")
            warnings.filterwarnings("always", module="control")

            # Look for a warning about sampling above Nyquist frequency
            omega_bad = np.linspace(10e-4,1.1,10) * np.pi/sys.dt
            ret = sys.freqresp(omega_bad)
            print("len(w) =", len(w))
            self.assertEqual(len(w), 1)
            self.assertIn("above", str(w[-1].message))
            self.assertIn("Nyquist", str(w[-1].message))

         # Test bode plots (currently only implemented for SISO)
         if (sys.inputs == 1 and sys.outputs == 1):
            # Generic call (frequency range calculated automatically)
            ret_ss = bode(sys)

            # Convert to transfer function and test bode again
            systf = tf(sys);
            ret_tf = bode(systf)

            # Make sure we can pass a frequency range
            bode(sys, omega_ok)

         else:
            # Calling bode should generate a not implemented error
            self.assertRaises(NotImplementedError, bode, (sys,))
Пример #5
0
    def setUp(self):
        """Set up a SISO and MIMO system to test operations on."""

        # Single input, single output continuous and discrete time systems
        sys = matlab.rss(3, 1, 1)
        self.siso_ss1 = StateSpace(sys.A, sys.B, sys.C, sys.D)
        self.siso_ss1c = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.0)
        self.siso_ss1d = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.1)
        self.siso_ss2d = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.2)
        self.siso_ss3d = StateSpace(sys.A, sys.B, sys.C, sys.D, True)

        # Two input, two output continuous time system
        A = [[-3., 4., 2.], [-1., -3., 0.], [2., 5., 3.]]
        B = [[1., 4.], [-3., -3.], [-2., 1.]]
        C = [[4., 2., -3.], [1., 4., 3.]]
        D = [[-2., 4.], [0., 1.]]
        self.mimo_ss1 = StateSpace(A, B, C, D)
        self.mimo_ss1c = StateSpace(A, B, C, D, 0)

        # Two input, two output discrete time system
        self.mimo_ss1d = StateSpace(A, B, C, D, 0.1)

        # Same system, but with a different sampling time
        self.mimo_ss2d = StateSpace(A, B, C, D, 0.2)

        # Single input, single output continuus and discrete transfer function
        self.siso_tf1 = TransferFunction([1, 1], [1, 2, 1])
        self.siso_tf1c = TransferFunction([1, 1], [1, 2, 1], 0)
        self.siso_tf1d = TransferFunction([1, 1], [1, 2, 1], 0.1)
        self.siso_tf2d = TransferFunction([1, 1], [1, 2, 1], 0.2)
        self.siso_tf3d = TransferFunction([1, 1], [1, 2, 1], True)
Пример #6
0
    def test_point_to_point(self):
        # Machine precision for floats.
        eps = np.finfo(float).eps

        for states in range(1, self.maxStates):
            # Start with a random system
            linsys = matlab.rss(states, 1, 1)

            # Make sure the system is not degenerate
            Cmat = ctrl.ctrb(linsys.A, linsys.B)
            if (np.linalg.matrix_rank(Cmat) != states):
                if (self.debug):
                    print("  skipping (not reachable)")
                    continue

            if (self.debug): print(linsys)

            # Create a flat system representation
            flatsys = tg.LinearFlatSystem(linsys)

            # Generate several different initial and final conditions
            for i in range(self.numTests):
                x0 = np.random.rand(linsys.states)
                xf = np.random.rand(linsys.states)
                Tf = np.random.randn()

                # Generate a trajectory from start to stop
                systraj = tg.point_to_point(flatsys, x0, xf, Tf)
                xd, ud = systraj.eval((0, Tf))
                np.testing.assert_array_almost_equal(x0, xd[0, :], decimal=4)
                np.testing.assert_array_almost_equal(xf, xd[1, :], decimal=4)
Пример #7
0
    def testMinrealBrute(self):
        for n, m, p in permutations(range(1,6), 3):
            s = matlab.rss(n, p, m)
            sr = s.minreal()
            if s.states > sr.states:
                self.nreductions += 1
            else:
                np.testing.assert_array_almost_equal(
                    np.sort(eigvals(s.A)), np.sort(eigvals(sr.A)))
                for i in range(m):
                    for j in range(p):
                        ht1 = matlab.tf(
                            matlab.ss(s.A, s.B[:,i], s.C[j,:], s.D[j,i]))
                        ht2 = matlab.tf(
                            matlab.ss(sr.A, sr.B[:,i], sr.C[j,:], sr.D[j,i]))
                        try:
                            self.assert_numden_almost_equal(
                                ht1.num[0][0], ht2.num[0][0],
                                ht1.den[0][0], ht2.den[0][0])
                        except Exception as e:
                            # for larger systems, the tf minreal's
                            # the original rss, but not the balanced one
                            if n < 6:
                                raise e

        self.assertEqual(self.nreductions, 2)
Пример #8
0
    def test_shape(self):
        """Test that rss outputs have the right state, input, and output size."""

        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxIO):
                for outputs in range(1, self.maxIO):
                    sys = matlab.rss(states, outputs, inputs)
                    self.assertEqual(sys.states, states)
                    self.assertEqual(sys.inputs, inputs)
                    self.assertEqual(sys.outputs, outputs)
Пример #9
0
    def testPole(self):
        """Test that the poles of rss outputs have a negative real part."""

        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxIO):
                for outputs in range(1, self.maxIO):
                    sys = matlab.rss(states, outputs, inputs)
                    p = sys.pole()
                    for z in p:
                        self.assertTrue(z.real < 0)
    def test_shape(self):
        """Test that rss outputs have the right state, input, and output size."""

        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxIO):
                for outputs in range(1, self.maxIO):
                    sys = matlab.rss(states, outputs, inputs)
                    self.assertEqual(sys.states, states)
                    self.assertEqual(sys.inputs, inputs)
                    self.assertEqual(sys.outputs, outputs)
    def testTF(self, verbose=False):
        """ Directly tests the functions tb04ad and td04ad through direct comparison of transfer function coefficients.
            Similar to convert_test, but tests at a lower level.
        """
        from slycot import tb04ad, td04ad
        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxI + 1):
                for outputs in range(1, self.maxO + 1):
                    for testNum in range(self.numTests):
                        ssOriginal = matlab.rss(states, outputs, inputs)
                        if (verbose):
                            print('====== Original SS ==========')
                            print(ssOriginal)
                            print('states=', states)
                            print('inputs=', inputs)
                            print('outputs=', outputs)


                        tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb, tfOrigingal_nctrb, tfOriginal_index,\
                            tfOriginal_dcoeff, tfOriginal_ucoeff = tb04ad(states,inputs,outputs,\
                            ssOriginal.A,ssOriginal.B,ssOriginal.C,ssOriginal.D,tol1=0.0)

                        ssTransformed_nr, ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D\
                            = td04ad('R',inputs,outputs,tfOriginal_index,tfOriginal_dcoeff,tfOriginal_ucoeff,tol=0.0)

                        tfTransformed_Actrb, tfTransformed_Bctrb, tfTransformed_Cctrb, tfTransformed_nctrb,\
                            tfTransformed_index, tfTransformed_dcoeff, tfTransformed_ucoeff = tb04ad(ssTransformed_nr,\
                            inputs,outputs,ssTransformed_A, ssTransformed_B, ssTransformed_C,ssTransformed_D,tol1=0.0)
                        #print 'size(Trans_A)=',ssTransformed_A.shape
                        if (verbose):
                            print('===== Transformed SS ==========')
                            print(
                                matlab.ss(ssTransformed_A, ssTransformed_B,
                                          ssTransformed_C, ssTransformed_D))
                            # print 'Trans_nr=',ssTransformed_nr
                            # print 'tfOrig_index=',tfOriginal_index
                            # print 'tfOrig_ucoeff=',tfOriginal_ucoeff
                            # print 'tfOrig_dcoeff=',tfOriginal_dcoeff
                            # print 'tfTrans_index=',tfTransformed_index
                            # print 'tfTrans_ucoeff=',tfTransformed_ucoeff
                            # print 'tfTrans_dcoeff=',tfTransformed_dcoeff
                    #Compare the TF directly, must match
                    #numerators
                        np.testing.assert_array_almost_equal(
                            tfOriginal_ucoeff, tfTransformed_ucoeff, decimal=3)
                        #denominators
                        np.testing.assert_array_almost_equal(
                            tfOriginal_dcoeff, tfTransformed_dcoeff, decimal=3)
Пример #12
0
def dsystem_dt(request):
    """Test systems for test_discrete"""
    # SISO state space systems with either fixed or unspecified sampling times
    sys = rss(3, 1, 1)

    # MIMO state space systems with either fixed or unspecified sampling times
    A = [[-3., 4., 2.], [-1., -3., 0.], [2., 5., 3.]]
    B = [[1., 4.], [-3., -3.], [-2., 1.]]
    C = [[4., 2., -3.], [1., 4., 3.]]
    D = [[-2., 4.], [0., 1.]]

    dt = request.param
    systems = {'sssiso': StateSpace(sys.A, sys.B, sys.C, sys.D, dt),
               'ssmimo': StateSpace(A, B, C, D, dt),
               'tf': TransferFunction([1, 1], [1, 2, 1], dt)}
    return systems
Пример #13
0
    def testFreqResp(self):
        """Compare the bode reponses of the SS systems and TF systems to the original SS
           They generally are different realizations but have same freq resp. 
           Currently this test may only be applied to SISO systems.
        """              
        for states in range(1,self.maxStates):
            for testNum in range(self.numTests):                       
                for inputs in range(1,1):
                    for outputs in range(1,1):       
                        ssOriginal = matlab.rss(states, inputs, outputs)
                        
                        tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb, tfOrigingal_nctrb, tfOriginal_index,\
                            tfOriginal_dcoeff, tfOriginal_ucoeff = tb04ad(states,inputs,outputs,\
                            ssOriginal.A,ssOriginal.B,ssOriginal.C,ssOriginal.D,tol1=0.0)
                        
                        ssTransformed_nr, ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D\
                            = td04ad('R',inputs,outputs,tfOriginal_index,tfOriginal_dcoeff,tfOriginal_ucoeff,tol=0.0)
                        
                        tfTransformed_Actrb, tfTransformed_Bctrb, tfTransformed_Cctrb, tfTransformed_nctrb,\
                            tfTransformed_index, tfTransformed_dcoeff, tfTransformed_ucoeff = tb04ad(\
                            ssTransformed_nr,inputs,outputs,ssTransformed_A, ssTransformed_B, ssTransformed_C,\
                            ssTransformed_D,tol1=0.0)

                        numTransformed = np.array(tfTransformed_ucoeff)
                        denTransformed = np.array(tfTransformed_dcoeff)
                        numOriginal = np.array(tfOriginal_ucoeff)
                        denOriginal = np.array(tfOriginal_dcoeff)
                                              
                        ssTransformed = matlab.ss(ssTransformed_A,ssTransformed_B,ssTransformed_C,ssTransformed_D)
                        for inputNum in range(inputs):
                            for outputNum in range(outputs):
                                [ssOriginalMag,ssOriginalPhase,freq] = matlab.bode(ssOriginal,Plot=False) 
                                [tfOriginalMag,tfOriginalPhase,freq] = matlab.bode(matlab.tf(numOriginal[outputNum][inputNum],denOriginal[outputNum]),Plot=False)
                                [ssTransformedMag,ssTransformedPhase,freq] = matlab.bode(ssTransformed,freq,Plot=False)
                                [tfTransformedMag,tfTransformedPhase,freq] = matlab.bode(matlab.tf(numTransformed[outputNum][inputNum],denTransformed[outputNum]),freq,Plot=False)
                                #print 'numOrig=',numOriginal[outputNum][inputNum]
                                #print 'denOrig=',denOriginal[outputNum]
                                #print 'numTrans=',numTransformed[outputNum][inputNum]
                                #print 'denTrans=',denTransformed[outputNum]
                                np.testing.assert_array_almost_equal(ssOriginalMag,tfOriginalMag,decimal=3)
                                np.testing.assert_array_almost_equal(ssOriginalPhase,tfOriginalPhase,decimal=3)       
                                np.testing.assert_array_almost_equal(ssOriginalMag,ssTransformedMag,decimal=3)
                                np.testing.assert_array_almost_equal(ssOriginalPhase,ssTransformedPhase,decimal=3)
                                np.testing.assert_array_almost_equal(tfOriginalMag,tfTransformedMag,decimal=3)
                                np.testing.assert_array_almost_equal(tfOriginalPhase,tfTransformedPhase,decimal=2)
Пример #14
0
    def testTF(self, verbose=False):
        """ Directly tests the functions tb04ad and td04ad through direct
            comparison of transfer function coefficients.
            Similar to convert_test, but tests at a lower level.
        """
        from slycot import tb04ad, td04ad
        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxI + 1):
                for outputs in range(1, self.maxO + 1):
                    for testNum in range(self.numTests):
                        ssOriginal = matlab.rss(states, outputs, inputs)
                        if (verbose):
                            print('====== Original SS ==========')
                            print(ssOriginal)
                            print('states=', states)
                            print('inputs=', inputs)
                            print('outputs=', outputs)

                        tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb,\
                            tfOrigingal_nctrb, tfOriginal_index,\
                            tfOriginal_dcoeff, tfOriginal_ucoeff =\
                            tb04ad(states, inputs, outputs,
                                   ssOriginal.A, ssOriginal.B,
                                   ssOriginal.C, ssOriginal.D, tol1=0.0)

                        ssTransformed_nr, ssTransformed_A, ssTransformed_B,\
                            ssTransformed_C, ssTransformed_D\
                            = td04ad('R', inputs, outputs, tfOriginal_index,
                                     tfOriginal_dcoeff, tfOriginal_ucoeff,
                                     tol=0.0)

                        tfTransformed_Actrb, tfTransformed_Bctrb,\
                            tfTransformed_Cctrb, tfTransformed_nctrb,\
                            tfTransformed_index, tfTransformed_dcoeff,\
                            tfTransformed_ucoeff = tb04ad(
                                ssTransformed_nr, inputs, outputs,
                                ssTransformed_A, ssTransformed_B,
                                ssTransformed_C, ssTransformed_D, tol1=0.0)
                        # print('size(Trans_A)=',ssTransformed_A.shape)
                        if (verbose):
                            print('===== Transformed SS ==========')
                            print(
                                matlab.ss(ssTransformed_A, ssTransformed_B,
                                          ssTransformed_C, ssTransformed_D))
Пример #15
0
 def testTF(self, verbose=False):
     """ Directly tests the functions tb04ad and td04ad through direct comparison of transfer function coefficients.
         Similar to convert_test, but tests at a lower level.
     """
     from slycot import tb04ad, td04ad
     for states in range(1, self.maxStates):
         for inputs in range(1, self.maxI+1):
             for outputs in range(1, self.maxO+1):
                 for testNum in range(self.numTests):
                     ssOriginal = matlab.rss(states, inputs, outputs)
                     if (verbose):
                         print('====== Original SS ==========')
                         print(ssOriginal)
                         print('states=', states)
                         print('inputs=', inputs)
                         print('outputs=', outputs)
                     
                     
                     tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb, tfOrigingal_nctrb, tfOriginal_index,\
                         tfOriginal_dcoeff, tfOriginal_ucoeff = tb04ad(states,inputs,outputs,\
                         ssOriginal.A,ssOriginal.B,ssOriginal.C,ssOriginal.D,tol1=0.0)
                     
                     ssTransformed_nr, ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D\
                         = td04ad('R',inputs,outputs,tfOriginal_index,tfOriginal_dcoeff,tfOriginal_ucoeff,tol=0.0)
                     
                     tfTransformed_Actrb, tfTransformed_Bctrb, tfTransformed_Cctrb, tfTransformed_nctrb,\
                         tfTransformed_index, tfTransformed_dcoeff, tfTransformed_ucoeff = tb04ad(ssTransformed_nr,\
                         inputs,outputs,ssTransformed_A, ssTransformed_B, ssTransformed_C,ssTransformed_D,tol1=0.0)
                     #print 'size(Trans_A)=',ssTransformed_A.shape
                     if (verbose):
                         print('===== Transformed SS ==========')
                         print(matlab.ss(ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D))
                         # print 'Trans_nr=',ssTransformed_nr                      
                         # print 'tfOrig_index=',tfOriginal_index
                         # print 'tfOrig_ucoeff=',tfOriginal_ucoeff
                         # print 'tfOrig_dcoeff=',tfOriginal_dcoeff
                         # print 'tfTrans_index=',tfTransformed_index
                         # print 'tfTrans_ucoeff=',tfTransformed_ucoeff
                         # print 'tfTrans_dcoeff=',tfTransformed_dcoeff
                    #Compare the TF directly, must match
                     #numerators
                     np.testing.assert_array_almost_equal(tfOriginal_ucoeff,tfTransformed_ucoeff,decimal=3)
                     #denominators
                     np.testing.assert_array_almost_equal(tfOriginal_dcoeff,tfTransformed_dcoeff,decimal=3)
    def testTF(self, verbose=False):
        """ Directly tests the functions tb04ad and td04ad through direct
            comparison of transfer function coefficients.
            Similar to convert_test, but tests at a lower level.
        """
        from slycot import tb04ad, td04ad
        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxI+1):
                for outputs in range(1, self.maxO+1):
                    for testNum in range(self.numTests):
                        ssOriginal = matlab.rss(states, outputs, inputs)
                        if (verbose):
                            print('====== Original SS ==========')
                            print(ssOriginal)
                            print('states=', states)
                            print('inputs=', inputs)
                            print('outputs=', outputs)

                        tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb,\
                            tfOrigingal_nctrb, tfOriginal_index,\
                            tfOriginal_dcoeff, tfOriginal_ucoeff =\
                            tb04ad(states, inputs, outputs,
                                   ssOriginal.A, ssOriginal.B,
                                   ssOriginal.C, ssOriginal.D, tol1=0.0)

                        ssTransformed_nr, ssTransformed_A, ssTransformed_B,\
                            ssTransformed_C, ssTransformed_D\
                            = td04ad('R', inputs, outputs, tfOriginal_index,
                                     tfOriginal_dcoeff, tfOriginal_ucoeff,
                                     tol=0.0)

                        tfTransformed_Actrb, tfTransformed_Bctrb,\
                            tfTransformed_Cctrb, tfTransformed_nctrb,\
                            tfTransformed_index, tfTransformed_dcoeff,\
                            tfTransformed_ucoeff = tb04ad(
                                ssTransformed_nr, inputs, outputs,
                                ssTransformed_A, ssTransformed_B,
                                ssTransformed_C, ssTransformed_D, tol1=0.0)
                        # print('size(Trans_A)=',ssTransformed_A.shape)
                        if (verbose):
                            print('===== Transformed SS ==========')
                            print(matlab.ss(ssTransformed_A, ssTransformed_B,
                                            ssTransformed_C, ssTransformed_D))
Пример #17
0
    def testMinrealBrute(self):
        for n, m, p in permutations(range(1, 6), 3):
            s = matlab.rss(n, p, m)
            sr = s.minreal()
            if s.states > sr.states:
                self.nreductions += 1
            else:
                # Check to make sure that poles and zeros match

                # For poles, just look at eigenvalues of A
                np.testing.assert_array_almost_equal(np.sort(eigvals(s.A)),
                                                     np.sort(eigvals(sr.A)))

                # For zeros, need to extract SISO systems
                for i in range(m):
                    for j in range(p):
                        # Extract SISO dynamixs from input i to output j
                        s1 = matlab.ss(s.A, s.B[:, i], s.C[j, :], s.D[j, i])
                        s2 = matlab.ss(sr.A, sr.B[:, i], sr.C[j, :], sr.D[j,
                                                                          i])

                        # Check that the zeros match
                        # Note: sorting doesn't work => have to do the hard way
                        z1 = matlab.zero(s1)
                        z2 = matlab.zero(s2)

                        # Start by making sure we have the same # of zeros
                        self.assertEqual(len(z1), len(z2))

                        # Make sure all zeros in s1 are in s2
                        for zero in z1:
                            # Find the closest zero
                            self.assertAlmostEqual(min(abs(z2 - zero)), 0.)

                        # Make sure all zeros in s2 are in s1
                        for zero in z2:
                            # Find the closest zero
                            self.assertAlmostEqual(min(abs(z1 - zero)), 0.)

        # Make sure that the number of systems reduced is as expected
        # (Need to update this number if you change the seed at top of file)
        self.assertEqual(self.nreductions, 2)
Пример #18
0
    def testMinrealBrute(self):
        for n, m, p in permutations(range(1,6), 3):
            s = matlab.rss(n, p, m)
            sr = s.minreal()
            if s.states > sr.states:
                self.nreductions += 1
            else:
                # Check to make sure that poles and zeros match

                # For poles, just look at eigenvalues of A
                np.testing.assert_array_almost_equal(
                    np.sort(eigvals(s.A)), np.sort(eigvals(sr.A)))

                # For zeros, need to extract SISO systems
                for i in range(m):
                    for j in range(p):
                        # Extract SISO dynamixs from input i to output j
                        s1 = matlab.ss(s.A, s.B[:,i], s.C[j,:], s.D[j,i])
                        s2 = matlab.ss(sr.A, sr.B[:,i], sr.C[j,:], sr.D[j,i])

                        # Check that the zeros match
                        # Note: sorting doesn't work => have to do the hard way
                        z1 = matlab.zero(s1)
                        z2 = matlab.zero(s2)

                        # Start by making sure we have the same # of zeros
                        self.assertEqual(len(z1), len(z2))

                        # Make sure all zeros in s1 are in s2
                        for zero in z1:
                            # Find the closest zero
                            self.assertAlmostEqual(min(abs(z2 - zero)), 0.)

                        # Make sure all zeros in s2 are in s1
                        for zero in z2:
                            # Find the closest zero
                            self.assertAlmostEqual(min(abs(z1 - zero)), 0.)

        # Make sure that the number of systems reduced is as expected
        # (Need to update this number if you change the seed at top of file)
        self.assertEqual(self.nreductions, 2)
Пример #19
0
    def testFreqResp(self):
        """Compare the bode reponses of the SS systems and TF systems to the original SS
           They generally are different realizations but have same freq resp.
           Currently this test may only be applied to SISO systems.
        """
        from slycot import tb04ad, td04ad
        for states in range(1, self.maxStates):
            for testNum in range(self.numTests):
                for inputs in range(1, 1):
                    for outputs in range(1, 1):
                        ssOriginal = matlab.rss(states, outputs, inputs)

                        tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb,\
                            tfOrigingal_nctrb, tfOriginal_index,\
                            tfOriginal_dcoeff, tfOriginal_ucoeff = tb04ad(
                                states, inputs, outputs, ssOriginal.A,
                                ssOriginal.B, ssOriginal.C, ssOriginal.D,
                                tol1=0.0)

                        ssTransformed_nr, ssTransformed_A, ssTransformed_B,\
                            ssTransformed_C, ssTransformed_D\
                            = td04ad('R', inputs, outputs, tfOriginal_index,
                                     tfOriginal_dcoeff, tfOriginal_ucoeff,
                                     tol=0.0)

                        tfTransformed_Actrb, tfTransformed_Bctrb,\
                            tfTransformed_Cctrb, tfTransformed_nctrb,\
                            tfTransformed_index, tfTransformed_dcoeff,\
                            tfTransformed_ucoeff = tb04ad(
                                ssTransformed_nr, inputs, outputs,
                                ssTransformed_A, ssTransformed_B,
                                ssTransformed_C, ssTransformed_D,
                                tol1=0.0)

                        numTransformed = np.array(tfTransformed_ucoeff)
                        denTransformed = np.array(tfTransformed_dcoeff)
                        numOriginal = np.array(tfOriginal_ucoeff)
                        denOriginal = np.array(tfOriginal_dcoeff)

                        ssTransformed = matlab.ss(ssTransformed_A,
                                                  ssTransformed_B,
                                                  ssTransformed_C,
                                                  ssTransformed_D)
                        for inputNum in range(inputs):
                            for outputNum in range(outputs):
                                [ssOriginalMag, ssOriginalPhase, freq] =\
                                    matlab.bode(ssOriginal, plot=False)
                                [tfOriginalMag, tfOriginalPhase, freq] =\
                                    matlab.bode(matlab.tf(
                                        numOriginal[outputNum][inputNum],
                                        denOriginal[outputNum]), plot=False)
                                [ssTransformedMag, ssTransformedPhase, freq] =\
                                    matlab.bode(ssTransformed,
                                                freq, plot=False)
                                [tfTransformedMag, tfTransformedPhase, freq] =\
                                    matlab.bode(matlab.tf(
                                        numTransformed[outputNum][inputNum],
                                        denTransformed[outputNum]),
                                        freq, plot=False)
                                # print('numOrig=',
                                #  numOriginal[outputNum][inputNum])
                                # print('denOrig=',
                                #  denOriginal[outputNum])
                                # print('numTrans=',
                                #  numTransformed[outputNum][inputNum])
                                # print('denTrans=',
                                #  denTransformed[outputNum])
                                np.testing.assert_array_almost_equal(
                                    ssOriginalMag, tfOriginalMag, decimal=3)
                                np.testing.assert_array_almost_equal(
                                    ssOriginalPhase,
                                    tfOriginalPhase,
                                    decimal=3)
                                np.testing.assert_array_almost_equal(
                                    ssOriginalMag, ssTransformedMag, decimal=3)
                                np.testing.assert_array_almost_equal(
                                    ssOriginalPhase,
                                    ssTransformedPhase,
                                    decimal=3)
                                np.testing.assert_array_almost_equal(
                                    tfOriginalMag, tfTransformedMag, decimal=3)
                                np.testing.assert_array_almost_equal(
                                    tfOriginalPhase,
                                    tfTransformedPhase,
                                    decimal=2)
Пример #20
0
from control import tf
from control.matlab import rss
from numpy import logspace
from timeit import timeit

nstates = 10
sys = rss(nstates)
sys_tf = tf(sys)
w = logspace(-1, 1, 50)
ntimes = 1000
time_ss = timeit("sys.freqresp(w)",
                 setup="from __main__ import sys, w",
                 number=ntimes)
time_tf = timeit("sys_tf.freqresp(w)",
                 setup="from __main__ import sys_tf, w",
                 number=ntimes)
print("State-space model on %d states: %f" % (nstates, time_ss))
print("Transfer-function model on %d states: %f" % (nstates, time_tf))
Пример #21
0
    def testConvert(self):
        """Test state space to transfer function conversion."""
        verbose = self.debug
        from control.statesp import _mimo2siso
        
        #print __doc__

        # Machine precision for floats.
        eps = np.finfo(float).eps

        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxIO):
                for outputs in range(1, self.maxIO):
                    # start with a random SS system and transform to TF then
                    # back to SS, check that the matrices are the same.
                    ssOriginal = matlab.rss(states, outputs, inputs)
                    if (verbose):
                        self.printSys(ssOriginal, 1)

                    # Make sure the system is not degenerate
                    Cmat = control.ctrb(ssOriginal.A, ssOriginal.B)
                    if (np.linalg.matrix_rank(Cmat) != states):
                        if (verbose):
                            print("  skipping (not reachable)")
                        continue
                    Omat = control.obsv(ssOriginal.A, ssOriginal.C)
                    if (np.linalg.matrix_rank(Omat) != states):
                        if (verbose):
                            print("  skipping (not observable)")
                        continue

                    tfOriginal = matlab.tf(ssOriginal)
                    if (verbose):
                        self.printSys(tfOriginal, 2)
                    
                    ssTransformed = matlab.ss(tfOriginal)
                    if (verbose):
                        self.printSys(ssTransformed, 3)

                    tfTransformed = matlab.tf(ssTransformed)
                    if (verbose):
                        self.printSys(tfTransformed, 4)

                    # Check to see if the state space systems have same dim
                    if (ssOriginal.states != ssTransformed.states):
                        print("WARNING: state space dimension mismatch: " + \
                            "%d versus %d" % \
                            (ssOriginal.states, ssTransformed.states))

                    # Now make sure the frequency responses match
                    # Since bode() only handles SISO, go through each I/O pair
                    # For phase, take sine and cosine to avoid +/- 360 offset
                    for inputNum in range(inputs):
                        for outputNum in range(outputs):
                            if (verbose):
                                print("Checking input %d, output %d" \
                                    % (inputNum, outputNum))
                            ssorig_mag, ssorig_phase, ssorig_omega = \
                                control.bode(_mimo2siso(ssOriginal, \
                                                        inputNum, outputNum), \
                                                 deg=False, Plot=False)
                            ssorig_real = ssorig_mag * np.cos(ssorig_phase)
                            ssorig_imag = ssorig_mag * np.sin(ssorig_phase)

                            #
                            # Make sure TF has same frequency response
                            #
                            num = tfOriginal.num[outputNum][inputNum]
                            den = tfOriginal.den[outputNum][inputNum]
                            tforig = control.tf(num, den)
                                                
                            tforig_mag, tforig_phase, tforig_omega = \
                                control.bode(tforig, ssorig_omega, \
                                                 deg=False, Plot=False)

                            tforig_real = tforig_mag * np.cos(tforig_phase)
                            tforig_imag = tforig_mag * np.sin(tforig_phase)
                            np.testing.assert_array_almost_equal( \
                                ssorig_real, tforig_real)
                            np.testing.assert_array_almost_equal( \
                                ssorig_imag, tforig_imag)

                            #
                            # Make sure xform'd SS has same frequency response
                            #
                            ssxfrm_mag, ssxfrm_phase, ssxfrm_omega = \
                                control.bode(_mimo2siso(ssTransformed, \
                                                        inputNum, outputNum), \
                                                 ssorig_omega, \
                                                 deg=False, Plot=False)
                            ssxfrm_real = ssxfrm_mag * np.cos(ssxfrm_phase)
                            ssxfrm_imag = ssxfrm_mag * np.sin(ssxfrm_phase)
                            np.testing.assert_array_almost_equal( \
                                ssorig_real, ssxfrm_real)
                            np.testing.assert_array_almost_equal( \
                                ssorig_imag, ssxfrm_imag)

                            #
                            # Make sure xform'd TF has same frequency response
                            #
                            num = tfTransformed.num[outputNum][inputNum]
                            den = tfTransformed.den[outputNum][inputNum]
                            tfxfrm = control.tf(num, den)
                            tfxfrm_mag, tfxfrm_phase, tfxfrm_omega = \
                                control.bode(tfxfrm, ssorig_omega, \
                                                 deg=False, Plot=False)
                            
                            tfxfrm_real = tfxfrm_mag * np.cos(tfxfrm_phase)
                            tfxfrm_imag = tfxfrm_mag * np.sin(tfxfrm_phase)
                            np.testing.assert_array_almost_equal( \
                                ssorig_real, tfxfrm_real)
                            np.testing.assert_array_almost_equal( \
                                ssorig_imag, tfxfrm_imag)
Пример #22
0
    def testConvert(self):
        """Test state space to transfer function conversion."""
        verbose = self.debug

        # print __doc__

        # Machine precision for floats.
        # eps = np.finfo(float).eps

        for states in range(1, self.maxStates):
            for inputs in range(1, self.maxIO):
                for outputs in range(1, self.maxIO):
                    # start with a random SS system and transform to TF then
                    # back to SS, check that the matrices are the same.
                    ssOriginal = matlab.rss(states, outputs, inputs)
                    if (verbose):
                        self.printSys(ssOriginal, 1)

                    # Make sure the system is not degenerate
                    Cmat = ctrb(ssOriginal.A, ssOriginal.B)
                    if (np.linalg.matrix_rank(Cmat) != states):
                        if (verbose):
                            print("  skipping (not reachable)")
                        continue
                    Omat = obsv(ssOriginal.A, ssOriginal.C)
                    if (np.linalg.matrix_rank(Omat) != states):
                        if (verbose):
                            print("  skipping (not observable)")
                        continue

                    tfOriginal = matlab.tf(ssOriginal)
                    if (verbose):
                        self.printSys(tfOriginal, 2)

                    ssTransformed = matlab.ss(tfOriginal)
                    if (verbose):
                        self.printSys(ssTransformed, 3)

                    tfTransformed = matlab.tf(ssTransformed)
                    if (verbose):
                        self.printSys(tfTransformed, 4)

                    # Check to see if the state space systems have same dim
                    if (ssOriginal.states != ssTransformed.states):
                        print("WARNING: state space dimension mismatch: " + \
                            "%d versus %d" % \
                            (ssOriginal.states, ssTransformed.states))

                    # Now make sure the frequency responses match
                    # Since bode() only handles SISO, go through each I/O pair
                    # For phase, take sine and cosine to avoid +/- 360 offset
                    for inputNum in range(inputs):
                        for outputNum in range(outputs):
                            if (verbose):
                                print("Checking input %d, output %d" \
                                    % (inputNum, outputNum))
                            ssorig_mag, ssorig_phase, ssorig_omega = \
                                bode(_mimo2siso(ssOriginal, \
                                                        inputNum, outputNum), \
                                                 deg=False, plot=False)
                            ssorig_real = ssorig_mag * np.cos(ssorig_phase)
                            ssorig_imag = ssorig_mag * np.sin(ssorig_phase)

                            #
                            # Make sure TF has same frequency response
                            #
                            num = tfOriginal.num[outputNum][inputNum]
                            den = tfOriginal.den[outputNum][inputNum]
                            tforig = tf(num, den)

                            tforig_mag, tforig_phase, tforig_omega = \
                                bode(tforig, ssorig_omega, \
                                                 deg=False, plot=False)

                            tforig_real = tforig_mag * np.cos(tforig_phase)
                            tforig_imag = tforig_mag * np.sin(tforig_phase)
                            np.testing.assert_array_almost_equal( \
                                ssorig_real, tforig_real)
                            np.testing.assert_array_almost_equal( \
                                ssorig_imag, tforig_imag)

                            #
                            # Make sure xform'd SS has same frequency response
                            #
                            ssxfrm_mag, ssxfrm_phase, ssxfrm_omega = \
                                bode(_mimo2siso(ssTransformed, \
                                                        inputNum, outputNum), \
                                                 ssorig_omega, \
                                                 deg=False, plot=False)
                            ssxfrm_real = ssxfrm_mag * np.cos(ssxfrm_phase)
                            ssxfrm_imag = ssxfrm_mag * np.sin(ssxfrm_phase)
                            np.testing.assert_array_almost_equal( \
                            ssorig_real, ssxfrm_real)
                            np.testing.assert_array_almost_equal( \
                            ssorig_imag, ssxfrm_imag)
                            #
                            # Make sure xform'd TF has same frequency response
                            #
                            num = tfTransformed.num[outputNum][inputNum]
                            den = tfTransformed.den[outputNum][inputNum]
                            tfxfrm = tf(num, den)
                            tfxfrm_mag, tfxfrm_phase, tfxfrm_omega = \
                                bode(tfxfrm, ssorig_omega, \
                                                 deg=False, plot=False)

                            tfxfrm_real = tfxfrm_mag * np.cos(tfxfrm_phase)
                            tfxfrm_imag = tfxfrm_mag * np.sin(tfxfrm_phase)
                            np.testing.assert_array_almost_equal( \
                                ssorig_real, tfxfrm_real)
                            np.testing.assert_array_almost_equal( \
                                ssorig_imag, tfxfrm_imag)
Пример #23
0
C = np.matrix('0.5, 0.6875, 0.7031, 0.5')
D = np.matrix('0.')

# The full system
fsys = StateSpace(A,B,C,D)
# The reduced system, truncating the order by 1
ord = 3
rsys = msimp.balred(fsys,ord, method = 'truncate')

# Comparison of the step responses of the full and reduced systems
plt.figure(1)
y, t = mt.step(fsys)
yr, tr = mt.step(rsys)
plt.plot(t.T, y.T)
plt.plot(tr.T, yr.T)

# Repeat balanced reduction, now with 100-dimensional random state space
sysrand = mt.rss(100, 1, 1)
rsysrand = msimp.balred(sysrand,10,method ='truncate')

# Comparison of the impulse responses of the full and reduced random systems
plt.figure(2)
yrand, trand = mt.impulse(sysrand)
yrandr, trandr = mt.impulse(rsysrand)
plt.plot(trand.T, yrand.T, trandr.T, yrandr.T) 


if 'PYCONTROL_TEST_EXAMPLES' not in os.environ:
    plt.show()

B = np.array([[2.], [0.], [0.], [0.]])
C = np.array([[0.5, 0.6875, 0.7031, 0.5]])
D = np.array([[0.]])

# The full system
fsys = StateSpace(A, B, C, D)

# The reduced system, truncating the order by 1
n = 3
rsys = msimp.balred(fsys, n, method='truncate')

# Comparison of the step responses of the full and reduced systems
plt.figure(1)
y, t = mt.step(fsys)
yr, tr = mt.step(rsys)
plt.plot(t.T, y.T)
plt.plot(tr.T, yr.T)

# Repeat balanced reduction, now with 100-dimensional random state space
sysrand = mt.rss(100, 1, 1)
rsysrand = msimp.balred(sysrand, 10, method='truncate')

# Comparison of the impulse responses of the full and reduced random systems
plt.figure(2)
yrand, trand = mt.impulse(sysrand)
yrandr, trandr = mt.impulse(rsysrand)
plt.plot(trand.T, yrand.T, trandr.T, yrandr.T)

if 'PYCONTROL_TEST_EXAMPLES' not in os.environ:
    plt.show()
Пример #25
0
    def test_discrete(self):
        # Test discrete time frequency response

        # SISO state space systems with either fixed or unspecified sampling times
        sys = rss(3, 1, 1)
        siso_ss1d = StateSpace(sys.A, sys.B, sys.C, sys.D, 0.1)
        siso_ss2d = StateSpace(sys.A, sys.B, sys.C, sys.D, True)

        # MIMO state space systems with either fixed or unspecified sampling times
        A = [[-3., 4., 2.], [-1., -3., 0.], [2., 5., 3.]]
        B = [[1., 4.], [-3., -3.], [-2., 1.]]
        C = [[4., 2., -3.], [1., 4., 3.]]
        D = [[-2., 4.], [0., 1.]]
        mimo_ss1d = StateSpace(A, B, C, D, 0.1)
        mimo_ss2d = StateSpace(A, B, C, D, True)

        # SISO transfer functions
        siso_tf1d = TransferFunction([1, 1], [1, 2, 1], 0.1)
        siso_tf2d = TransferFunction([1, 1], [1, 2, 1], True)

        # Go through each system and call the code, checking return types
        for sys in (siso_ss1d, siso_ss2d, mimo_ss1d, mimo_ss2d, siso_tf1d,
                    siso_tf2d):
            # Set frequency range to just below Nyquist freq (for Bode)
            omega_ok = np.linspace(10e-4, 0.99, 100) * np.pi / sys.dt

            # Test frequency response
            ret = sys.freqresp(omega_ok)

            # Check for warning if frequency is out of range
            import warnings
            warnings.simplefilter('always', UserWarning)  # don't supress
            with warnings.catch_warnings(record=True) as w:
                # Set up warnings filter to only show warnings in control module
                warnings.filterwarnings("ignore")
                warnings.filterwarnings("always", module="control")

                # Look for a warning about sampling above Nyquist frequency
                omega_bad = np.linspace(10e-4, 1.1, 10) * np.pi / sys.dt
                ret = sys.freqresp(omega_bad)
                print("len(w) =", len(w))
                self.assertEqual(len(w), 1)
                self.assertIn("above", str(w[-1].message))
                self.assertIn("Nyquist", str(w[-1].message))

            # Test bode plots (currently only implemented for SISO)
            if (sys.inputs == 1 and sys.outputs == 1):
                # Generic call (frequency range calculated automatically)
                ret_ss = bode(sys)

                # Convert to transfer function and test bode again
                systf = tf(sys)
                ret_tf = bode(systf)

                # Make sure we can pass a frequency range
                bode(sys, omega_ok)

            else:
                # Calling bode should generate a not implemented error
                self.assertRaises(NotImplementedError, bode, (sys, ))

        def test_options(self):
            """Test ability to set parameter values"""

        # Generate a Bode plot of a transfer function
        sys = ctrl.tf([1000], [1, 25, 100, 0])
        fig1 = plt.figure()
        ctrl.bode_plot(sys, dB=False, deg=True, Hz=False)

        # Save the parameter values
        left1, right1 = fig1.axes[0].xaxis.get_data_interval()
        numpoints1 = len(fig1.axes[0].lines[0].get_data()[0])

        # Same transfer function, but add a decade on each end
        ctrl.config.set_defaults('freqplot', feature_periphery_decades=2)
        fig2 = plt.figure()
        ctrl.bode_plot(sys, dB=False, deg=True, Hz=False)
        left2, right2 = fig2.axes[0].xaxis.get_data_interval()

        # Make sure we got an extra decade on each end
        self.assertAlmostEqual(left2, 0.1 * left1)
        self.assertAlmostEqual(right2, 10 * right1)

        # Same transfer function, but add more points to the plot
        ctrl.config.set_defaults('freqplot',
                                 feature_periphery_decades=2,
                                 number_of_samples=13)
        fig3 = plt.figure()
        ctrl.bode_plot(sys, dB=False, deg=True, Hz=False)
        numpoints3 = len(fig3.axes[0].lines[0].get_data()[0])

        # Make sure we got the right number of points
        self.assertNotEqual(numpoints1, numpoints3)
        self.assertEqual(numpoints3, 13)

        # Reset default parameters to avoid contamination
        ctrl.config.reset_defaults()
Пример #26
0
 def testRss(self):
     """Call rss()"""
     rss(1)
     rss(2)
     rss(2, 1, 3)
from control import tf
from control.matlab import rss
from numpy import logspace
from timeit import timeit

nstates = 10
sys = rss(nstates)
sys_tf = tf(sys)
w = logspace(-1,1,50)
ntimes = 1000
time_ss = timeit("sys.freqresp(w)", setup="from __main__ import sys, w", number=ntimes)
time_tf = timeit("sys_tf.freqresp(w)", setup="from __main__ import sys_tf, w", number=ntimes)
print("State-space model on %d states: %f" % (nstates, time_ss))
print("Transfer-function model on %d states: %f" % (nstates, time_tf))