Skip to content

Commit f3cda64

Browse files
committed
change pole(), zero() to poles(), zeros(), with legacy interface available
1 parent 14fa890 commit f3cda64

20 files changed

+159
-121
lines changed

control/freqplot.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -722,11 +722,11 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
722722
if isinstance(sys, (StateSpace, TransferFunction)) \
723723
and indent_direction != 'none':
724724
if sys.isctime():
725-
splane_poles = sys.pole()
725+
splane_poles = sys.poles()
726726
else:
727727
# map z-plane poles to s-plane, ignoring any at the origin
728728
# because we don't need to indent for them
729-
zplane_poles = sys.pole()
729+
zplane_poles = sys.poles()
730730
zplane_poles = zplane_poles[~np.isclose(abs(zplane_poles), 0.)]
731731
splane_poles = np.log(zplane_poles)/sys.dt
732732

@@ -1328,8 +1328,8 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
13281328
try:
13291329
# Add new features to the list
13301330
if sys.isctime():
1331-
features_ = np.concatenate((np.abs(sys.pole()),
1332-
np.abs(sys.zero())))
1331+
features_ = np.concatenate(
1332+
(np.abs(sys.poles()), np.abs(sys.zeros())))
13331333
# Get rid of poles and zeros at the origin
13341334
toreplace = np.isclose(features_, 0.0)
13351335
if np.any(toreplace):
@@ -1339,8 +1339,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
13391339
# TODO: What distance to the Nyquist frequency is appropriate?
13401340
freq_interesting.append(fn * 0.9)
13411341

1342-
features_ = np.concatenate((sys.pole(),
1343-
sys.zero()))
1342+
features_ = np.concatenate((sys.poles(), sys.zeros()))
13441343
# Get rid of poles and zeros on the real axis (imag==0)
13451344
# * origin and real < 0
13461345
# * at 1.: would result in omega=0. (logaritmic plot!)

control/lti.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
from . import config
1919

2020
__all__ = ['issiso', 'timebase', 'common_timebase', 'timebaseEqual',
21-
'isdtime', 'isctime', 'pole', 'zero', 'damp', 'evalfr',
22-
'frequency_response', 'freqresp', 'dcgain']
21+
'isdtime', 'isctime', 'poles', 'zeros', 'damp', 'evalfr',
22+
'frequency_response', 'freqresp', 'dcgain', 'pole', 'zero']
2323

2424
class LTI:
2525
"""LTI is a parent class to linear time-invariant (LTI) system objects.
@@ -156,7 +156,7 @@ def damp(self):
156156
poles : array
157157
Array of system poles
158158
'''
159-
poles = self.pole()
159+
poles = self.poles()
160160

161161
if isdtime(self, strict=True):
162162
splane_poles = np.log(poles.astype(complex))/self.dt
@@ -242,6 +242,21 @@ def _dcgain(self, warn_infinite):
242242
else:
243243
return zeroresp
244244

245+
#
246+
# Deprecated functions
247+
#
248+
249+
def pole(self):
250+
warn("pole() will be deprecated; use poles()",
251+
PendingDeprecationWarning)
252+
return self.poles()
253+
254+
def zero(self):
255+
warn("zero() will be deprecated; use zeros()",
256+
PendingDeprecationWarning)
257+
return self.zeros()
258+
259+
245260
# Test to see if a system is SISO
246261
def issiso(sys, strict=False):
247262
"""
@@ -426,7 +441,8 @@ def isctime(sys, strict=False):
426441
# Got passed something we don't recognize
427442
return False
428443

429-
def pole(sys):
444+
445+
def poles(sys):
430446
"""
431447
Compute system poles.
432448
@@ -440,23 +456,23 @@ def pole(sys):
440456
poles: ndarray
441457
Array that contains the system's poles.
442458
443-
Raises
444-
------
445-
NotImplementedError
446-
when called on a TransferFunction object
447-
448459
See Also
449460
--------
450-
zero
451-
TransferFunction.pole
452-
StateSpace.pole
461+
zeros
462+
TransferFunction.poles
463+
StateSpace.poles
453464
454465
"""
455466

456-
return sys.pole()
467+
return sys.poles()
457468

458469

459-
def zero(sys):
470+
def pole(sys):
471+
warn("pole() will be deprecated; use poles()", PendingDeprecationWarning)
472+
return poles(sys)
473+
474+
475+
def zeros(sys):
460476
"""
461477
Compute system zeros.
462478
@@ -470,20 +486,21 @@ def zero(sys):
470486
zeros: ndarray
471487
Array that contains the system's zeros.
472488
473-
Raises
474-
------
475-
NotImplementedError
476-
when called on a MIMO system
477-
478489
See Also
479490
--------
480-
pole
481-
StateSpace.zero
482-
TransferFunction.zero
491+
poles
492+
StateSpace.zeros
493+
TransferFunction.zeros
483494
484495
"""
485496

486-
return sys.zero()
497+
return sys.zeros()
498+
499+
500+
def zero(sys):
501+
warn("zero() will be deprecated; use zeros()", PendingDeprecationWarning)
502+
return zeros(sys)
503+
487504

488505
def damp(sys, doprint=True):
489506
"""

control/matlab/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
from ..dtime import c2d
8585
from ..sisotool import sisotool
8686

87+
# Functions that are renamed in MATLAB
88+
pole, zero = poles, zeros
89+
8790
# Import functions specific to Matlab compatibility package
8891
from .timeresp import *
8992
from .wrappers import *

control/modelsimp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ def minreal(sys, tol=None, verbose=True):
354354
sysr = sys.minreal(tol)
355355
if verbose:
356356
print("{nstates} states have been removed from the model".format(
357-
nstates=len(sys.pole()) - len(sysr.pole())))
357+
nstates=len(sys.poles()) - len(sysr.poles())))
358358
return sysr
359359

360360

control/pzmap.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ def pzmap(sys, plot=None, grid=None, title='Pole Zero Map', **kwargs):
104104
if not isinstance(sys, LTI):
105105
raise TypeError('Argument ``sys``: must be a linear system.')
106106

107-
poles = sys.pole()
108-
zeros = sys.zero()
107+
poles = sys.poles()
108+
zeros = sys.zeros()
109109

110110
if (plot):
111111
import matplotlib.pyplot as plt

control/statesp.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ def horner(self, x, warn_infinite=True):
933933

934934
# Evaluating at a pole. Return value depends if there
935935
# is a zero at the same point or not.
936-
if x_idx in self.zero():
936+
if x_idx in self.zeros():
937937
out[:, :, idx] = complex(np.nan, np.nan)
938938
else:
939939
out[:, :, idx] = complex(np.inf, np.nan)
@@ -955,12 +955,12 @@ def freqresp(self, omega):
955955
return self.frequency_response(omega)
956956

957957
# Compute poles and zeros
958-
def pole(self):
958+
def poles(self):
959959
"""Compute the poles of a state space system."""
960960

961961
return eigvals(self.A) if self.nstates else np.array([])
962962

963-
def zero(self):
963+
def zeros(self):
964964
"""Compute the zeros of a state space system."""
965965

966966
if not self.nstates:
@@ -982,9 +982,9 @@ def zero(self):
982982

983983
except ImportError: # Slycot unavailable. Fall back to scipy.
984984
if self.C.shape[0] != self.D.shape[1]:
985-
raise NotImplementedError("StateSpace.zero only supports "
986-
"systems with the same number of "
987-
"inputs as outputs.")
985+
raise NotImplementedError(
986+
"StateSpace.zero only supports systems with the same "
987+
"number of inputs as outputs.")
988988

989989
# This implements the QZ algorithm for finding transmission zeros
990990
# from

control/tests/bdalg_test.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from control.xferfcn import TransferFunction
1212
from control.statesp import StateSpace
1313
from control.bdalg import feedback, append, connect
14-
from control.lti import zero, pole
14+
from control.lti import zeros, poles
1515

1616

1717
class TestFeedback:
@@ -188,52 +188,52 @@ def testLists(self, tsys):
188188

189189
# Series
190190
sys1_2 = ctrl.series(sys1, sys2)
191-
np.testing.assert_array_almost_equal(sort(pole(sys1_2)), [-4., -2.])
192-
np.testing.assert_array_almost_equal(sort(zero(sys1_2)), [-3., -1.])
191+
np.testing.assert_array_almost_equal(sort(poles(sys1_2)), [-4., -2.])
192+
np.testing.assert_array_almost_equal(sort(zeros(sys1_2)), [-3., -1.])
193193

194194
sys1_3 = ctrl.series(sys1, sys2, sys3)
195-
np.testing.assert_array_almost_equal(sort(pole(sys1_3)),
195+
np.testing.assert_array_almost_equal(sort(poles(sys1_3)),
196196
[-6., -4., -2.])
197-
np.testing.assert_array_almost_equal(sort(zero(sys1_3)),
197+
np.testing.assert_array_almost_equal(sort(zeros(sys1_3)),
198198
[-5., -3., -1.])
199199

200200
sys1_4 = ctrl.series(sys1, sys2, sys3, sys4)
201-
np.testing.assert_array_almost_equal(sort(pole(sys1_4)),
201+
np.testing.assert_array_almost_equal(sort(poles(sys1_4)),
202202
[-8., -6., -4., -2.])
203-
np.testing.assert_array_almost_equal(sort(zero(sys1_4)),
203+
np.testing.assert_array_almost_equal(sort(zeros(sys1_4)),
204204
[-7., -5., -3., -1.])
205205

206206
sys1_5 = ctrl.series(sys1, sys2, sys3, sys4, sys5)
207-
np.testing.assert_array_almost_equal(sort(pole(sys1_5)),
207+
np.testing.assert_array_almost_equal(sort(poles(sys1_5)),
208208
[-8., -6., -4., -2., -0.])
209-
np.testing.assert_array_almost_equal(sort(zero(sys1_5)),
209+
np.testing.assert_array_almost_equal(sort(zeros(sys1_5)),
210210
[-9., -7., -5., -3., -1.])
211211

212212
# Parallel
213213
sys1_2 = ctrl.parallel(sys1, sys2)
214-
np.testing.assert_array_almost_equal(sort(pole(sys1_2)), [-4., -2.])
215-
np.testing.assert_array_almost_equal(sort(zero(sys1_2)),
216-
sort(zero(sys1 + sys2)))
214+
np.testing.assert_array_almost_equal(sort(poles(sys1_2)), [-4., -2.])
215+
np.testing.assert_array_almost_equal(sort(zeros(sys1_2)),
216+
sort(zeros(sys1 + sys2)))
217217

218218
sys1_3 = ctrl.parallel(sys1, sys2, sys3)
219-
np.testing.assert_array_almost_equal(sort(pole(sys1_3)),
219+
np.testing.assert_array_almost_equal(sort(poles(sys1_3)),
220220
[-6., -4., -2.])
221-
np.testing.assert_array_almost_equal(sort(zero(sys1_3)),
222-
sort(zero(sys1 + sys2 + sys3)))
221+
np.testing.assert_array_almost_equal(sort(zeros(sys1_3)),
222+
sort(zeros(sys1 + sys2 + sys3)))
223223

224224
sys1_4 = ctrl.parallel(sys1, sys2, sys3, sys4)
225-
np.testing.assert_array_almost_equal(sort(pole(sys1_4)),
225+
np.testing.assert_array_almost_equal(sort(poles(sys1_4)),
226226
[-8., -6., -4., -2.])
227227
np.testing.assert_array_almost_equal(
228-
sort(zero(sys1_4)),
229-
sort(zero(sys1 + sys2 + sys3 + sys4)))
228+
sort(zeros(sys1_4)),
229+
sort(zeros(sys1 + sys2 + sys3 + sys4)))
230230

231231
sys1_5 = ctrl.parallel(sys1, sys2, sys3, sys4, sys5)
232-
np.testing.assert_array_almost_equal(sort(pole(sys1_5)),
232+
np.testing.assert_array_almost_equal(sort(poles(sys1_5)),
233233
[-8., -6., -4., -2., -0.])
234234
np.testing.assert_array_almost_equal(
235-
sort(zero(sys1_5)),
236-
sort(zero(sys1 + sys2 + sys3 + sys4 + sys5)))
235+
sort(zeros(sys1_5)),
236+
sort(zeros(sys1 + sys2 + sys3 + sys4 + sys5)))
237237

238238
def testMimoSeries(self, tsys):
239239
"""regression: bdalg.series reverses order of arguments"""

control/tests/convert_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def testTf2SsDuplicatePoles(self):
225225
[[1], [1, 0]]]
226226
g = tf(num, den)
227227
s = ss(g)
228-
np.testing.assert_allclose(g.pole(), s.pole())
228+
np.testing.assert_allclose(g.poles(), s.poles())
229229

230230
@slycotonly
231231
def test_tf2ss_robustness(self):
@@ -241,10 +241,10 @@ def test_tf2ss_robustness(self):
241241
sys2ss = tf2ss(sys2tf)
242242

243243
# Make sure that the poles match for StateSpace and TransferFunction
244-
np.testing.assert_array_almost_equal(np.sort(sys1tf.pole()),
245-
np.sort(sys1ss.pole()))
246-
np.testing.assert_array_almost_equal(np.sort(sys2tf.pole()),
247-
np.sort(sys2ss.pole()))
244+
np.testing.assert_array_almost_equal(np.sort(sys1tf.poles()),
245+
np.sort(sys1ss.poles()))
246+
np.testing.assert_array_almost_equal(np.sort(sys2tf.poles()),
247+
np.sort(sys2ss.poles()))
248248

249249
def test_tf2ss_nonproper(self):
250250
"""Unit tests for non-proper transfer functions"""

control/tests/freqresp_test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -418,11 +418,11 @@ def test_dcgain_consistency():
418418
"""Test to make sure that DC gain is consistently evaluated"""
419419
# Set up transfer function with pole at the origin
420420
sys_tf = ctrl.tf([1], [1, 0])
421-
assert 0 in sys_tf.pole()
421+
assert 0 in sys_tf.poles()
422422

423423
# Set up state space system with pole at the origin
424424
sys_ss = ctrl.tf2ss(sys_tf)
425-
assert 0 in sys_ss.pole()
425+
assert 0 in sys_ss.poles()
426426

427427
# Finite (real) numerator over 0 denominator => inf + nanj
428428
np.testing.assert_equal(
@@ -440,8 +440,8 @@ def test_dcgain_consistency():
440440

441441
# Set up transfer function with pole, zero at the origin
442442
sys_tf = ctrl.tf([1, 0], [1, 0])
443-
assert 0 in sys_tf.pole()
444-
assert 0 in sys_tf.zero()
443+
assert 0 in sys_tf.poles()
444+
assert 0 in sys_tf.zeros()
445445

446446
# Pole and zero at the origin should give nan + nanj for the response
447447
np.testing.assert_equal(
@@ -456,15 +456,15 @@ def test_dcgain_consistency():
456456
ctrl.tf2ss(ctrl.tf([1], [1, 0]))
457457

458458
# Different systems give different representations => test accordingly
459-
if 0 in sys_ss.pole() and 0 in sys_ss.zero():
459+
if 0 in sys_ss.poles() and 0 in sys_ss.zeros():
460460
# Pole and zero at the origin => should get (nan + nanj)
461461
np.testing.assert_equal(
462462
sys_ss(0, warn_infinite=False), complex(np.nan, np.nan))
463463
np.testing.assert_equal(
464464
sys_ss(0j, warn_infinite=False), complex(np.nan, np.nan))
465465
np.testing.assert_equal(
466466
sys_ss.dcgain(), np.nan)
467-
elif 0 in sys_ss.pole():
467+
elif 0 in sys_ss.poles():
468468
# Pole at the origin, but zero elsewhere => should get (inf + nanj)
469469
np.testing.assert_equal(
470470
sys_ss(0, warn_infinite=False), complex(np.inf, np.nan))
@@ -479,11 +479,11 @@ def test_dcgain_consistency():
479479
# Pole with non-zero, complex numerator => inf + infj
480480
s = ctrl.tf('s')
481481
sys_tf = (s + 1) / (s**2 + 1)
482-
assert 1j in sys_tf.pole()
482+
assert 1j in sys_tf.poles()
483483

484484
# Set up state space system with pole on imaginary axis
485485
sys_ss = ctrl.tf2ss(sys_tf)
486-
assert 1j in sys_tf.pole()
486+
assert 1j in sys_tf.poles()
487487

488488
# Make sure we get correct response if evaluated at the pole
489489
np.testing.assert_equal(

control/tests/iosys_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ def test_lineariosys_statespace(self, tsys):
12131213

12141214
# Make sure that state space functions work for LinearIOSystems
12151215
np.testing.assert_allclose(
1216-
iosys_siso.pole(), tsys.siso_linsys.pole())
1216+
iosys_siso.poles(), tsys.siso_linsys.poles())
12171217
omega = np.logspace(.1, 10, 100)
12181218
mag_io, phase_io, omega_io = iosys_siso.frequency_response(omega)
12191219
mag_ss, phase_ss, omega_ss = tsys.siso_linsys.frequency_response(omega)

0 commit comments

Comments
 (0)