Skip to content

Commit 01314a6

Browse files
committed
added ssdata and tfdata functions
1 parent c4adc4c commit 01314a6

File tree

6 files changed

+87
-6
lines changed

6 files changed

+87
-6
lines changed

ChangeLog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
2012-10-03 Richard Murray <murray@altura.local>
2+
3+
* tests/matlab_test.py (TestMatlab.testSsdata): unit test
4+
5+
* src/matlab.py (ssdata, tfdata): new functions to return state
6+
space and transfer function object data. For transfer functions,
7+
currenly requires SISO system
8+
9+
* src/freqplot.py (bode_plot): Adding np.atleast_1d to the
10+
np.squeeze calculations makes it possible to use a single value
11+
frequency list (contributed by Benjamin White)
12+
113
2012-09-09 Richard Murray <murray@altura.local>
214

315
* tests/statefbk_test.py (TestStatefbk.testAcker): unit test

src/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,4 @@
8080
from matlab import nichols, rlocus, margin
8181
# bode and nyquist come directly from freqplot.py
8282
from matlab import step, impulse, initial, lsim
83+
from matlab import ssdata, tfdata

src/freqplot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ def bode_plot(syslist, omega=None, dB=False, Hz=False, deg=True,
114114

115115
# Get the magnitude and phase of the system
116116
mag_tmp, phase_tmp, omega = sys.freqresp(omega)
117-
mag = np.squeeze(mag_tmp)
118-
phase = np.squeeze(phase_tmp)
117+
mag = np.atleast_1d(np.squeeze(mag_tmp))
118+
phase = np.atleast_1d(np.squeeze(phase_tmp))
119119
phase = unwrap(phase)
120120
if Hz: omega = omega/(2*sp.pi)
121121
if dB: mag = 20*sp.log10(mag)

src/matlab.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,3 +1338,45 @@ def lsim(sys, U=0., T=None, X0=0., **keywords):
13381338
T, yout, xout = timeresp.forced_response(sys, T, U, X0,
13391339
transpose = True, **keywords)
13401340
return yout, T, xout
1341+
1342+
# Return state space data as a tuple
1343+
def ssdata(sys):
1344+
'''
1345+
Return state space data objects for a system
1346+
1347+
Parameters
1348+
----------
1349+
sys: Lti (StateSpace, or TransferFunction)
1350+
LTI system whose data will be returned
1351+
1352+
Returns
1353+
-------
1354+
(A, B, C, D): list of matrices
1355+
State space data for the system
1356+
'''
1357+
ss = _convertToStateSpace(sys)
1358+
return (ss.A, ss.B, ss.C, ss.D)
1359+
1360+
# Return transfer function data as a tuple
1361+
def tfdata(sys, **kw):
1362+
'''
1363+
Return transfer function data objects for a system
1364+
1365+
Parameters
1366+
----------
1367+
sys: Lti (StateSpace, or TransferFunction)
1368+
LTI system whose data will be returned
1369+
1370+
Keywords
1371+
--------
1372+
inputs = int; outputs = int
1373+
For MIMO transfer function, return num, den for given inputs, outputs
1374+
1375+
Returns
1376+
-------
1377+
(num, den): numerator and denominator arrays
1378+
Transfer function coefficients (SISO only)
1379+
'''
1380+
tf = _convertToTransferFunction(sys, **kw)
1381+
1382+
return (tf.num, tf.den)

src/xferfcn.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -786,16 +786,16 @@ def _convertToTransferFunction(sys, **kw):
786786

787787
if isinstance(sys, TransferFunction):
788788
if len(kw):
789-
raise TypeError("If sys is a TransferFunction, \
790-
_convertToTransferFunction cannot take keywords.")
789+
raise TypeError("If sys is a TransferFunction, " +
790+
"_convertToTransferFunction cannot take keywords.")
791791

792792
return sys
793793
elif isinstance(sys, statesp.StateSpace):
794794
try:
795795
from slycot import tb04ad
796796
if len(kw):
797-
raise TypeError("If sys is a StateSpace, \
798-
_convertToTransferFunction cannot take keywords.")
797+
raise TypeError("If sys is a StateSpace, " +
798+
"_convertToTransferFunction cannot take keywords.")
799799

800800
# Use Slycot to make the transformation
801801
# Make sure to convert system matrices to numpy arrays

tests/matlab_test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,32 @@ def testUnwrap(self):
353353
wrapped = phase % (2 * np.pi)
354354
unwrapped = unwrap(wrapped)
355355

356+
def testSISOssdata(self):
357+
ssdata_1 = ssdata(self.siso_ss2);
358+
ssdata_2 = ssdata(self.siso_tf2);
359+
for i in range(len(ssdata_1)):
360+
np.testing.assert_array_almost_equal(ssdata_1[i], ssdata_2[i])
361+
362+
def testMIMOssdata(self):
363+
m = (self.mimo_ss1.A, self.mimo_ss1.B, self.mimo_ss1.C, self.mimo_ss1.D)
364+
ssdata_1 = ssdata(self.mimo_ss1);
365+
for i in range(len(ssdata_1)):
366+
np.testing.assert_array_almost_equal(ssdata_1[i], m[i])
367+
368+
def testSISOtfdata(self):
369+
tfdata_1 = tfdata(self.siso_tf2);
370+
tfdata_2 = tfdata(self.siso_tf2);
371+
for i in range(len(tfdata_1)):
372+
np.testing.assert_array_almost_equal(tfdata_1[i], tfdata_2[i])
373+
374+
#! TODO: not yet implemented
375+
# def testMIMOtfdata(self):
376+
# sisotf = ss2tf(self.siso_ss1)
377+
# tfdata_1 = tfdata(sisotf)
378+
# tfdata_2 = tfdata(self.mimo_ss1, input=0, output=0)
379+
# for i in range(len(tfdata)):
380+
# np.testing.assert_array_almost_equal(tfdata_1[i], tfdata_2[i])
381+
356382
def suite():
357383
return unittest.TestLoader().loadTestsFromTestCase(TestMatlab)
358384

0 commit comments

Comments
 (0)