From: <kk...@us...> - 2011-02-08 22:16:53
|
Revision: 86 http://python-control.svn.sourceforge.net/python-control/?rev=86&view=rev Author: kkchen Date: 2011-02-08 22:16:47 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified convertTo* to use keywords. Tests for TransferFunction.pole. The optional arguments inputs, outputs for convertTo{StateSpace,TransferFunction} are now keyword arguments. This lets us make sure the user isn't passing the number of inputs and outputs when it shouldn't. A test for TransferFunction.pole passes. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestXferFcn.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:42 UTC (rev 85) +++ branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:16:47 UTC (rev 86) @@ -381,6 +381,17 @@ np.testing.assert_array_almost_equal(phase, truephase) np.testing.assert_array_equal(omega, trueomega) + # Tests for TransferFunction.pole and TransferFunction.zero. + + 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.]) + # Tests for TransferFunction.feedback. def testFeedbackSISO(self): Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:16:42 UTC (rev 85) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:16:47 UTC (rev 86) @@ -401,20 +401,34 @@ return out -def convertToStateSpace(sys, inputs=1, outputs=1): +def convertToStateSpace(sys, **kw): """Convert a system to state space form (if needed). If sys is already a state space, then it is returned. If sys is a transfer function object, then it is converted to a state space and returned. If sys is a scalar, then the number of inputs and outputs can be specified - manually. + manually, as in: + + >>> sys = convertToStateSpace(3.) # Assumes inputs = outputs = 1 + >>> sys = convertToStateSpace(1., inputs=3, outputs=2) + + In the latter example, A = B = C = 0 and D = [[1., 1., 1.] + [1., 1., 1.]]. """ if isinstance(sys, StateSpace): + if len(kw): + raise TypeError("If sys is a StateSpace, convertToStateSpace \ +cannot take keywords.") + # Already a state space system; just return it return sys elif isinstance(sys, xferfcn.TransferFunction): + if len(kw): + raise TypeError("If sys is a TransferFunction, convertToStateSpace \ +cannot take keywords.") + # Change the numerator and denominator arrays so that the transfer # function matrix has a common denominator. num, den = sys._common_den() @@ -427,6 +441,15 @@ return StateSpace(ssout[1], ssout[2], ssout[3], ssout[4]) elif isinstance(sys, (int, long, float, complex)): + if "inputs" in kw: + inputs = kw["inputs"] + else: + inputs = 1 + if "outputs" in kw: + outputs = kw["outputs"] + else: + outputs = 1 + # Generate a simple state space system of the desired dimension # The following Doesn't work due to inconsistencies in ltisys: # return StateSpace([[]], [[]], [[]], eye(outputs, inputs)) Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:42 UTC (rev 85) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:47 UTC (rev 86) @@ -253,7 +253,8 @@ # Convert the second argument to a transfer function. if not isinstance(other, TransferFunction): - other = convertToTransferFunction(other, self.inputs, self.outputs) + other = convertToTransferFunction(other, inputs=self.inputs, + outputs=self.outputs) # Check that the input-output sizes are consistent. if self.inputs != other.inputs: @@ -294,7 +295,8 @@ # Convert the second argument to a transfer function. if isinstance(other, (int, float, long, complex)): - other = convertToTransferFunction(other, self.inputs, self.inputs) + other = convertToTransferFunction(other, inputs=self.inputs, + outputs=self.inputs) else: other = convertToTransferFunction(other) @@ -413,7 +415,7 @@ def zero(self): """Compute the zeros of a transfer function.""" - if (self.inputs > 1 or self.outputs > 1): + if self.inputs > 1 or self.outputs > 1: raise NotImplementedError("TransferFunction.zero is currently \ only implemented for SISO systems.") else: @@ -638,19 +640,33 @@ return num, den -def convertToTransferFunction(sys, inputs=1, outputs=1): +def convertToTransferFunction(sys, **kw): """Convert a system to transfer function form (if needed). If sys is already a transfer function, then it is returned. If sys is a state space object, then it is converted to a transfer function and returned. If sys is a scalar, then the number of inputs and outputs can be - specified manually. + specified manually, as in: + + >>> sys = convertToTransferFunction(3.) # Assumes inputs = outputs = 1 + >>> sys = convertToTransferFunction(1., inputs=3, outputs=2) + + In the latter example, sys's matrix transfer function is [[1., 1., 1.] + [1., 1., 1.]]. """ if isinstance(sys, TransferFunction): + if len(kw): + raise TypeError("If sys is a TransferFunction, \ +convertToTransferFunction cannot take keywords.") + return sys elif isinstance(sys, statesp.StateSpace): + if len(kw): + raise TypeError("If sys is a StateSpace, convertToTransferFunction \ +cannot take keywords.") + # 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) @@ -667,6 +683,15 @@ return TransferFunction(num, den) elif isinstance(sys, (int, long, float, complex)): + if "inputs" in kw: + inputs = kw["inputs"] + else: + inputs = 1 + if "outputs" in kw: + outputs = kw["outputs"] + else: + outputs = 1 + num = [[[sys] for j in range(inputs)] for i in range(outputs)] den = [[[1] for j in range(inputs)] for i in range(outputs)] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |