From: <kk...@us...> - 2011-02-08 22:16:32
|
Revision: 82 http://python-control.svn.sourceforge.net/python-control/?rev=82&view=rev Author: kkchen Date: 2011-02-08 22:16:26 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Implemented and tested convertToTransferFunction (which ss2tf uses). Various fixes: - changed control.exception to exception in the imports of statefbk.py - changed sys + (const) to behave more like MATLAB Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestXferFcn.py branches/control-0.4a/src/statefbk.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/TestXferFcn.py =================================================================== --- branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:16:21 UTC (rev 81) +++ branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:16:26 UTC (rev 82) @@ -1,7 +1,8 @@ #!/usr/bin/env python import numpy as np -from xferfcn import TransferFunction +from statesp import StateSpace +from xferfcn import TransferFunction, convertToTransferFunction import unittest class TestXferFcn(unittest.TestCase): @@ -383,7 +384,8 @@ # Tests for TransferFunction.feedback. 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]) @@ -395,5 +397,27 @@ 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 testConvertToTransferFunction(self): + """Test for correct state space to transfer function conversion.""" + + A = [[1., -2.], [-3., 4.]] + B = [[6., 5.], [4., 3.]] + C = [[1., -2.], [3., -4.], [5., -6.]] + D = [[1., 0.], [0., 1.], [1., 0.]] + sys = StateSpace(A, B, C, D) + + tfsys = convertToTransferFunction(sys) + + num = [[np.array([1., -7., 10.]), np.array([-1., 10.])], + [np.array([2., -8.]), np.array([1., -2., -8.])], + [np.array([1., 1., -30.]), np.array([7., -22.])]] + den = [[np.array([1., -5., -2.]) for j in range(sys.inputs)] + for i in range(sys.outputs)] + + for i in range(sys.outputs): + for j in range(sys.inputs): + np.testing.assert_array_almost_equal(tfsys.num[i][j], num[i][j]) + np.testing.assert_array_almost_equal(tfsys.den[i][j], den[i][j]) + if __name__ == "__main__": unittest.main() Modified: branches/control-0.4a/src/statefbk.py =================================================================== --- branches/control-0.4a/src/statefbk.py 2011-02-08 22:16:21 UTC (rev 81) +++ branches/control-0.4a/src/statefbk.py 2011-02-08 22:16:26 UTC (rev 82) @@ -42,7 +42,7 @@ # External packages and modules import numpy as np import ctrlutil -from control.exception import * +from exception import * # Pole placement def place(A, B, p): Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:16:21 UTC (rev 81) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:16:26 UTC (rev 82) @@ -69,7 +69,7 @@ """ from numpy import angle, any, array, concatenate, cos, dot, empty, exp, eye, \ - pi, poly, poly1d, matrix, roots, sin, zeros + ones, pi, poly, poly1d, matrix, roots, sin, zeros from numpy.random import rand, randn from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError @@ -382,7 +382,7 @@ # The following Doesn't work due to inconsistencies in ltisys: # return StateSpace([[]], [[]], [[]], eye(outputs, inputs)) return StateSpace(0., zeros((1, inputs)), zeros((outputs, 1)), - sys * eye(outputs, inputs)) + sys * ones(outputs, inputs)) else: raise TypeError("Can't convert given type to StateSpace system.") Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:21 UTC (rev 81) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:26 UTC (rev 82) @@ -75,6 +75,7 @@ polyval, zeros from scipy.signal import lti from copy import deepcopy +from slycot import tb04ad from lti import Lti import statesp @@ -397,8 +398,8 @@ polyval(self.den[i][j], w * 1.j)), omega) fresp = array(fresp) - mag[i, j] = abs(fresp) - phase[i, j] = angle(fresp) + mag[i, j, :] = abs(fresp) + phase[i, j, :] = angle(fresp) return mag, phase, omega @@ -537,15 +538,24 @@ if isinstance(sys, TransferFunction): return sys elif isinstance(sys, statesp.StateSpace): - # TODO: Wrap SLICOT to do state space to transfer function conversion. - raise NotImplementedError("State space to transfer function conversion \ -is not implemented yet.") + # Use Slycot to make the transformation. + tfout = tb04ad(sys.states, sys.inputs, sys.outputs, sys.A, sys.B, sys.C, + sys.D, sys.outputs, sys.outputs, sys.inputs) + + # Preallocate outputs. + num = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)] + den = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)] + + for i in range(sys.outputs): + for j in range(sys.inputs): + num[i][j] = list(tfout[6][i, j, :]) + # Each transfer function matrix row has a common denominator. + den[i][j] = list(tfout[5][i, :]) + + return TransferFunction(num, den) elif isinstance(sys, (int, long, float, complex)): - # Make an identity system. - num = [[[0] for j in range(inputs)] for i in range(outputs)] + num = [[[sys] for j in range(inputs)] for i in range(outputs)] den = [[[1] for j in range(inputs)] for i in range(outputs)] - for i in range(min(inputs, outputs)): - num[i][i] = [sys] return TransferFunction(num, den) else: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |