Skip to content

Commit c4f1c34

Browse files
authored
Merge pull request #170 from murrayrm/fix_scipy-1.0
Fixes for SciPy 1.0 compatibility
2 parents 9457031 + 11c99ef commit c4f1c34

File tree

5 files changed

+41
-37
lines changed

5 files changed

+41
-37
lines changed

control/bdalg.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"""
5555

5656
import scipy as sp
57+
import numpy as np
5758
from . import xferfcn as tf
5859
from . import statesp as ss
5960
from . import frdata as frd
@@ -221,18 +222,18 @@ def feedback(sys1, sys2=1, sign=-1):
221222
"""
222223

223224
# Check for correct input types.
224-
if not isinstance(sys1, (int, float, complex, tf.TransferFunction,
225-
ss.StateSpace, frd.FRD)):
225+
if not isinstance(sys1, (int, float, complex, np.number,
226+
tf.TransferFunction, ss.StateSpace, frd.FRD)):
226227
raise TypeError("sys1 must be a TransferFunction, StateSpace " +
227228
"or FRD object, or a scalar.")
228-
if not isinstance(sys2, (int, float, complex, tf.TransferFunction,
229-
ss.StateSpace, frd.FRD)):
229+
if not isinstance(sys2, (int, float, complex, np.number,
230+
tf.TransferFunction, ss.StateSpace, frd.FRD)):
230231
raise TypeError("sys2 must be a TransferFunction, StateSpace " +
231232
"or FRD object, or a scalar.")
232233

233234
# If sys1 is a scalar, convert it to the appropriate LTI type so that we can
234235
# its feedback member function.
235-
if isinstance(sys1, (int, float, complex)):
236+
if isinstance(sys1, (int, float, complex, np.number)):
236237
if isinstance(sys2, tf.TransferFunction):
237238
sys1 = tf._convertToTransferFunction(sys1)
238239
elif isinstance(sys2, ss.StateSpace):

control/frdata.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"""
5050

5151
# External function declarations
52+
import numpy as np
5253
from numpy import angle, array, empty, ones, \
5354
real, imag, matrix, absolute, eye, linalg, where, dot
5455
from scipy.interpolate import splprep, splev
@@ -219,7 +220,7 @@ def __mul__(self, other):
219220
"""Multiply two LTI objects (serial connection)."""
220221

221222
# Convert the second argument to a transfer function.
222-
if isinstance(other, (int, float, complex)):
223+
if isinstance(other, (int, float, complex, np.number)):
223224
return FRD(self.fresp * other, self.omega,
224225
smooth=(self.ifunc is not None))
225226
else:
@@ -245,7 +246,7 @@ def __rmul__(self, other):
245246
"""Right Multiply two LTI objects (serial connection)."""
246247

247248
# Convert the second argument to an frd function.
248-
if isinstance(other, (int, float, complex)):
249+
if isinstance(other, (int, float, complex, np.number)):
249250
return FRD(self.fresp * other, self.omega,
250251
smooth=(self.ifunc is not None))
251252
else:
@@ -272,7 +273,7 @@ def __rmul__(self, other):
272273
def __truediv__(self, other):
273274
"""Divide two LTI objects."""
274275

275-
if isinstance(other, (int, float, complex)):
276+
if isinstance(other, (int, float, complex, np.number)):
276277
return FRD(self.fresp * (1/other), self.omega,
277278
smooth=(self.ifunc is not None))
278279
else:
@@ -295,7 +296,7 @@ def __div__(self, other):
295296
# TODO: Division of MIMO transfer function objects is not written yet.
296297
def __rtruediv__(self, other):
297298
"""Right divide two LTI objects."""
298-
if isinstance(other, (int, float, complex)):
299+
if isinstance(other, (int, float, complex, np.number)):
299300
return FRD(other / self.fresp, self.omega,
300301
smooth=(self.ifunc is not None))
301302
else:
@@ -449,7 +450,7 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1):
449450

450451
return FRD(fresp, omega, smooth=True)
451452

452-
elif isinstance(sys, (int, float, complex)):
453+
elif isinstance(sys, (int, float, complex, np.number)):
453454
fresp = ones((outputs, inputs, len(omega)), dtype=float)*sys
454455
return FRD(fresp, omega, smooth=True)
455456

control/lti.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
timebaseEqual()
1313
"""
1414

15+
import numpy as np
1516
from numpy import absolute, real
1617

1718
__all__ = ['issiso', 'timebase', 'timebaseEqual', 'isdtime', 'isctime',
@@ -96,7 +97,7 @@ def dcgain(self):
9697

9798
# Test to see if a system is SISO
9899
def issiso(sys, strict=False):
99-
if isinstance(sys, (int, float, complex)) and not strict:
100+
if isinstance(sys, (int, float, complex, np.number)) and not strict:
100101
return True
101102
elif not isinstance(sys, LTI):
102103
raise ValueError("Object is not an LTI system")
@@ -114,7 +115,7 @@ def timebase(sys, strict=True):
114115
set to False, dt = True will be returned as 1.
115116
"""
116117
# System needs to be either a constant or an LTI system
117-
if isinstance(sys, (int, float, complex)):
118+
if isinstance(sys, (int, float, complex, np.number)):
118119
return None
119120
elif not isinstance(sys, LTI):
120121
raise ValueError("Timebase not defined")
@@ -162,7 +163,7 @@ def isdtime(sys, strict=False):
162163
"""
163164

164165
# Check to see if this is a constant
165-
if isinstance(sys, (int, float, complex)):
166+
if isinstance(sys, (int, float, complex, np.number)):
166167
# OK as long as strict checking is off
167168
return True if not strict else False
168169

@@ -187,7 +188,7 @@ def isctime(sys, strict=False):
187188
"""
188189

189190
# Check to see if this is a constant
190-
if isinstance(sys, (int, float, complex)):
191+
if isinstance(sys, (int, float, complex, np.number)):
191192
# OK as long as strict checking is off
192193
return True if not strict else False
193194

control/statesp.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from numpy.random import rand, randn
5959
from numpy.linalg import solve, eigvals, matrix_rank
6060
from numpy.linalg.linalg import LinAlgError
61+
import scipy as sp
6162
from scipy.signal import lti, cont2discrete
6263
# from exceptions import Exception
6364
import warnings
@@ -218,7 +219,7 @@ def __add__(self, other):
218219
"""Add two LTI systems (parallel connection)."""
219220

220221
# Check for a couple of special cases
221-
if (isinstance(other, (int, float, complex))):
222+
if (isinstance(other, (int, float, complex, np.number))):
222223
# Just adding a scalar; put it in the D matrix
223224
A, B, C = self.A, self.B, self.C;
224225
D = self.D + other;
@@ -275,7 +276,7 @@ def __mul__(self, other):
275276
"""Multiply two LTI objects (serial connection)."""
276277

277278
# Check for a couple of special cases
278-
if isinstance(other, (int, float, complex)):
279+
if isinstance(other, (int, float, complex, np.number)):
279280
# Just multiplying by a scalar; change the output
280281
A, B = self.A, self.B
281282
C = self.C * other
@@ -316,7 +317,7 @@ def __rmul__(self, other):
316317
"""Right multiply two LTI objects (serial connection)."""
317318

318319
# Check for a couple of special cases
319-
if isinstance(other, (int, float, complex)):
320+
if isinstance(other, (int, float, complex, np.number)):
320321
# Just multiplying by a scalar; change the input
321322
A, C = self.A, self.C;
322323
B = self.B * other;
@@ -699,11 +700,10 @@ def _convertToStateSpace(sys, **kw):
699700
# TODO: do we want to squeeze first and check dimenations?
700701
# I think this will fail if num and den aren't 1-D after
701702
# the squeeze
702-
lti_sys = lti(squeeze(sys.num), squeeze(sys.den))
703-
return StateSpace(lti_sys.A, lti_sys.B, lti_sys.C, lti_sys.D,
704-
sys.dt)
703+
A, B, C, D = sp.signal.tf2ss(squeeze(sys.num), squeeze(sys.den))
704+
return StateSpace(A, B, C, D, sys.dt)
705705

706-
elif isinstance(sys, (int, float, complex)):
706+
elif isinstance(sys, (int, float, complex, np.number)):
707707
if "inputs" in kw:
708708
inputs = kw["inputs"]
709709
else:

control/xferfcn.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@
5252
"""
5353

5454
# External function declarations
55+
import numpy as np
5556
from numpy import angle, any, array, empty, finfo, insert, ndarray, ones, \
5657
polyadd, polymul, polyval, roots, sort, sqrt, zeros, squeeze, exp, pi, \
5758
where, delete, real, poly, poly1d
58-
import numpy as np
59+
import scipy as sp
5960
from scipy.signal import lti, tf2zpk, zpk2tf, cont2discrete
6061
from copy import deepcopy
6162
from warnings import warn
@@ -126,7 +127,7 @@ def __init__(self, *args):
126127
data = [num, den]
127128
for i in range(len(data)):
128129
# Check for a scalar (including 0d ndarray)
129-
if (isinstance(data[i], (int, float, complex)) or
130+
if (isinstance(data[i], (int, float, complex, np.number)) or
130131
(isinstance(data[i], ndarray) and data[i].ndim == 0)):
131132
# Convert scalar to list of list of array.
132133
if (isinstance(data[i], int)):
@@ -135,7 +136,7 @@ def __init__(self, *args):
135136
else:
136137
data[i] = [[array([data[i]])]]
137138
elif (isinstance(data[i], (list, tuple, ndarray)) and
138-
isinstance(data[i][0], (int, float, complex))):
139+
isinstance(data[i][0], (int, float, complex, np.number))):
139140
# Convert array to list of list of array.
140141
if (isinstance(data[i][0], int)):
141142
# Convert integers to floats at this point
@@ -146,7 +147,8 @@ def __init__(self, *args):
146147
elif (isinstance(data[i], list) and
147148
isinstance(data[i][0], list) and
148149
isinstance(data[i][0][0], (list, tuple, ndarray)) and
149-
isinstance(data[i][0][0][0], (int, float, complex))):
150+
isinstance(data[i][0][0][0], (int, float, complex,
151+
np.number))):
150152
# We might already have the right format. Convert the
151153
# coefficient vectors to arrays, if necessary.
152154
for j in range(len(data[i])):
@@ -363,7 +365,7 @@ def __rsub__(self, other):
363365
def __mul__(self, other):
364366
"""Multiply two LTI objects (serial connection)."""
365367
# Convert the second argument to a transfer function.
366-
if isinstance(other, (int, float, complex)):
368+
if isinstance(other, (int, float, complex, np.number)):
367369
other = _convertToTransferFunction(other, inputs=self.inputs,
368370
outputs=self.inputs)
369371
else:
@@ -410,7 +412,7 @@ def __rmul__(self, other):
410412
"""Right multiply two LTI objects (serial connection)."""
411413

412414
# Convert the second argument to a transfer function.
413-
if isinstance(other, (int, float, complex)):
415+
if isinstance(other, (int, float, complex, np.number)):
414416
other = _convertToTransferFunction(other, inputs=self.inputs,
415417
outputs=self.inputs)
416418
else:
@@ -458,7 +460,7 @@ def __rmul__(self, other):
458460
def __truediv__(self, other):
459461
"""Divide two LTI objects."""
460462

461-
if isinstance(other, (int, float, complex)):
463+
if isinstance(other, (int, float, complex, np.number)):
462464
other = _convertToTransferFunction(
463465
other, inputs=self.inputs,
464466
outputs=self.inputs)
@@ -492,7 +494,7 @@ def __div__(self, other):
492494
# TODO: Division of MIMO transfer function objects is not written yet.
493495
def __rtruediv__(self, other):
494496
"""Right divide two LTI objects."""
495-
if isinstance(other, (int, float, complex)):
497+
if isinstance(other, (int, float, complex, np.number)):
496498
other = _convertToTransferFunction(
497499
other, inputs=self.inputs,
498500
outputs=self.inputs)
@@ -1128,22 +1130,21 @@ def _convertToTransferFunction(sys, **kw):
11281130
# Each transfer function matrix row
11291131
# has a common denominator.
11301132
den[i][j] = list(tfout[5][i, :])
1131-
# print(num)
1132-
# print(den)
1133+
11331134
except ImportError:
11341135
# If slycot is not available, use signal.lti (SISO only)
11351136
if (sys.inputs != 1 or sys.outputs != 1):
11361137
raise TypeError("No support for MIMO without slycot")
11371138

1138-
lti_sys = lti(sys.A, sys.B, sys.C, sys.D)
1139-
num = squeeze(lti_sys.num)
1140-
den = squeeze(lti_sys.den)
1141-
# print(num)
1142-
# print(den)
1139+
# Do the conversion using sp.signal.ss2tf
1140+
# Note that this returns a 2D array for the numerator
1141+
num, den = sp.signal.ss2tf(sys.A, sys.B, sys.C, sys.D)
1142+
num = squeeze(num) # Convert to 1D array
1143+
den = squeeze(den) # Probably not needed
11431144

11441145
return TransferFunction(num, den, sys.dt)
11451146

1146-
elif isinstance(sys, (int, float, complex)):
1147+
elif isinstance(sys, (int, float, complex, np.number)):
11471148
if "inputs" in kw:
11481149
inputs = kw["inputs"]
11491150
else:

0 commit comments

Comments
 (0)