Skip to content

Commit 0d6ee57

Browse files
committed
Added in patches from Ryan Krauss <rkrauss@siue.edu>:
* now possible to call a transfer function with a complex argument and get back the value of the transfer function (returns a matrix in MIMO case) * default argument for second transfer function in feedback() call is now 1. Note that this will only work for SISO systems (wasn't sure extending to MIMO was that useful).
1 parent 3fbc191 commit 0d6ee57

File tree

8 files changed

+73
-6
lines changed

8 files changed

+73
-6
lines changed

ChangeLog

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
2013-06-09 Richard Murray <murray@altura-2.local>
2+
3+
* tests/bdalg_test.py (TestFeedback.testScalarSS)
4+
(TestFeedback.testScalarTF): added simple test of default argument
5+
to feedback() for state space and transfer function systems
6+
7+
* tests/frd_test.py (TestFRD.testFeedback): added test of default
8+
argument to feedback() for FRD type
9+
10+
* src/bdalg.py (feedback):
11+
* src/frdata.py (FRD.feedback):
12+
* src/statesp.py (StateSpace.feedback):
13+
patched in default value of 1 for other system in feedback().
14+
Contributed by Ryan Krauss <rkrauss@siue.edu>
15+
16+
* tests/xferfcn_test.py (TestXferFcn.testEvalFrMIMO)
17+
(TestXferFcn.testEvalFrSISO): added tests of __call__ version of
18+
evalfr.
19+
20+
* src/xferfcn.py (TransferFunction.__call__): patched in new
21+
__call__ functionality from Ryan Krauss <rkrauss@siue.edu>, but
22+
modified to use evalfr (works with MIMO). SISO transfer functions
23+
return a single complex number, MIMO transfer functions return a
24+
matrix of complex numbers.
25+
126
2013-05-23 Rene van Paassen <rene.vanpaassen@gmail.com>
227

328
* src/margin.py: re-vamped stability_margins function. Now

src/bdalg.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ def negate(sys):
172172

173173
return -sys;
174174

175-
def feedback(sys1, sys2, sign=-1):
175+
#! TODO: expand to allow sys2 default to work in MIMO case?
176+
def feedback(sys1, sys2=1, sign=-1):
176177
"""
177178
Feedback interconnection between two I/O systems.
178179

src/frdata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def freqresp(self, omega):
393393

394394
return mag, phase, omega
395395

396-
def feedback(self, other, sign=-1):
396+
def feedback(self, other=1, sign=-1):
397397
"""Feedback interconnection between two FRD objects."""
398398

399399
other = _convertToFRD(other, omega=self.omega)

src/statesp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ def zero(self):
447447
return roots(num)
448448

449449
# Feedback around a state space system
450-
def feedback(self, other, sign=-1):
450+
def feedback(self, other=1, sign=-1):
451451
"""Feedback interconnection between two LTI systems."""
452452

453453
other = _convertToStateSpace(other)

src/xferfcn.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
# External function declarations
8282
from numpy import angle, any, array, empty, finfo, insert, ndarray, ones, \
8383
polyadd, polymul, polyval, roots, sort, sqrt, zeros, squeeze, exp, pi, \
84-
where, delete, real, poly
84+
where, delete, real, poly, poly1d
8585
from scipy.signal import lti
8686
from copy import deepcopy
8787
from warnings import warn
@@ -231,7 +231,21 @@ def __init__(self, *args):
231231
self.den = den
232232

233233
self._truncatecoeff()
234-
234+
235+
def __call__(self, s):
236+
"""Evaluate the system's transfer function for a complex vairable
237+
238+
For a SISO transfer function, returns the value of the
239+
transfer function. For a MIMO transfer fuction, returns a
240+
matrix of values evaluated at complex variable s."""
241+
242+
if (self.inputs > 1 or self.outputs > 1):
243+
# MIMO transfer function, return a matrix
244+
return self.horner(s)
245+
else:
246+
# SISO transfer function, return a scalar
247+
return self.horner(s)[0][0]
248+
235249
def _truncatecoeff(self):
236250
"""Remove extraneous zero coefficients from num and den.
237251
@@ -604,7 +618,7 @@ def zero(self):
604618
#for now, just give zeros of a SISO tf
605619
return roots(self.num[0][0])
606620

607-
def feedback(self, other, sign=-1):
621+
def feedback(self, other=1, sign=-1):
608622
"""Feedback interconnection between two LTI objects."""
609623

610624
other = _convertToTransferFunction(other)

tests/bdalg_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def testScalarSS(self):
5050
np.testing.assert_array_almost_equal(ans2.C, [[2.5, 0.]])
5151
np.testing.assert_array_almost_equal(ans2.D, [[2.5]])
5252

53+
# Make sure default arugments work as well
54+
ans3 = feedback(self.sys2, 1)
55+
ans4 = feedback(self.sys2)
56+
np.testing.assert_array_almost_equal(ans3.A, ans4.A)
57+
np.testing.assert_array_almost_equal(ans3.B, ans4.B)
58+
np.testing.assert_array_almost_equal(ans3.C, ans4.C)
59+
np.testing.assert_array_almost_equal(ans3.D, ans4.D)
60+
5361
def testScalarTF(self):
5462
"""Scalar system with transfer function feedback block."""
5563

@@ -61,6 +69,12 @@ def testScalarTF(self):
6169
np.testing.assert_array_almost_equal(ans2.num, [[[2.5, 5., 7.5]]])
6270
np.testing.assert_array_almost_equal(ans2.den, [[[1., -0.5, -2.]]])
6371

72+
# Make sure default arugments work as well
73+
ans3 = feedback(self.sys1, 1)
74+
ans4 = feedback(self.sys1)
75+
np.testing.assert_array_almost_equal(ans3.num, ans4.num)
76+
np.testing.assert_array_almost_equal(ans3.den, ans4.den)
77+
6478
def testSSScalar(self):
6579
"""State space system with scalar feedback block."""
6680

tests/frd_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ def testFeedback(self):
8484
np.testing.assert_array_almost_equal(
8585
f1.feedback(1).freqresp([0.1, 1.0, 10])[0],
8686
h1.feedback(1).freqresp([0.1, 1.0, 10])[0])
87+
88+
# Make sure default argument also works
89+
np.testing.assert_array_almost_equal(
90+
f1.feedback().freqresp([0.1, 1.0, 10])[0],
91+
h1.feedback().freqresp([0.1, 1.0, 10])[0])
8792

8893
def testFeedback2(self):
8994
h2 = StateSpace([[-1.0, 0], [0, -2.0]], [[0.4], [0.1]],

tests/xferfcn_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ def testEvalFrSISO(self):
324324
np.testing.assert_array_almost_equal(sys.evalfr(32.),
325325
np.array([[0.00281959302585077 - 0.030628473607392j]]))
326326

327+
# Test call version as well
328+
np.testing.assert_almost_equal(sys(1.j), -0.5 - 0.5j)
329+
np.testing.assert_almost_equal(sys(32.j),
330+
0.00281959302585077 - 0.030628473607392j)
331+
327332
def testEvalFrMIMO(self):
328333
"""Evaluate the frequency response of a MIMO system at one frequency."""
329334

@@ -338,6 +343,9 @@ def testEvalFrMIMO(self):
338343

339344
np.testing.assert_array_almost_equal(sys.evalfr(2.), resp)
340345

346+
# Test call version as well
347+
np.testing.assert_array_almost_equal(sys(2.j), resp)
348+
341349
# Tests for TransferFunction.freqresp.
342350

343351
def testFreqRespSISO(self):

0 commit comments

Comments
 (0)