diff --git a/control/bdalg.py b/control/bdalg.py index 9d5aac654..b92496477 100644 --- a/control/bdalg.py +++ b/control/bdalg.py @@ -54,6 +54,7 @@ """ import scipy as sp +import numpy as np from . import xferfcn as tf from . import statesp as ss from . import frdata as frd @@ -221,18 +222,18 @@ def feedback(sys1, sys2=1, sign=-1): """ # Check for correct input types. - if not isinstance(sys1, (int, float, complex, tf.TransferFunction, - ss.StateSpace, frd.FRD)): + if not isinstance(sys1, (int, float, complex, np.number, + tf.TransferFunction, ss.StateSpace, frd.FRD)): raise TypeError("sys1 must be a TransferFunction, StateSpace " + "or FRD object, or a scalar.") - if not isinstance(sys2, (int, float, complex, tf.TransferFunction, - ss.StateSpace, frd.FRD)): + if not isinstance(sys2, (int, float, complex, np.number, + tf.TransferFunction, ss.StateSpace, frd.FRD)): raise TypeError("sys2 must be a TransferFunction, StateSpace " + "or FRD object, or a scalar.") # If sys1 is a scalar, convert it to the appropriate LTI type so that we can # its feedback member function. - if isinstance(sys1, (int, float, complex)): + if isinstance(sys1, (int, float, complex, np.number)): if isinstance(sys2, tf.TransferFunction): sys1 = tf._convertToTransferFunction(sys1) elif isinstance(sys2, ss.StateSpace): diff --git a/control/frdata.py b/control/frdata.py index ff1663b15..313da12b2 100644 --- a/control/frdata.py +++ b/control/frdata.py @@ -49,6 +49,7 @@ """ # External function declarations +import numpy as np from numpy import angle, array, empty, ones, \ real, imag, matrix, absolute, eye, linalg, where, dot from scipy.interpolate import splprep, splev @@ -219,7 +220,7 @@ def __mul__(self, other): """Multiply two LTI objects (serial connection).""" # Convert the second argument to a transfer function. - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): return FRD(self.fresp * other, self.omega, smooth=(self.ifunc is not None)) else: @@ -245,7 +246,7 @@ def __rmul__(self, other): """Right Multiply two LTI objects (serial connection).""" # Convert the second argument to an frd function. - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): return FRD(self.fresp * other, self.omega, smooth=(self.ifunc is not None)) else: @@ -272,7 +273,7 @@ def __rmul__(self, other): def __truediv__(self, other): """Divide two LTI objects.""" - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): return FRD(self.fresp * (1/other), self.omega, smooth=(self.ifunc is not None)) else: @@ -295,7 +296,7 @@ def __div__(self, other): # TODO: Division of MIMO transfer function objects is not written yet. def __rtruediv__(self, other): """Right divide two LTI objects.""" - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): return FRD(other / self.fresp, self.omega, smooth=(self.ifunc is not None)) else: @@ -449,7 +450,7 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1): return FRD(fresp, omega, smooth=True) - elif isinstance(sys, (int, float, complex)): + elif isinstance(sys, (int, float, complex, np.number)): fresp = ones((outputs, inputs, len(omega)), dtype=float)*sys return FRD(fresp, omega, smooth=True) diff --git a/control/lti.py b/control/lti.py index ab7672d51..aeef5cbb1 100644 --- a/control/lti.py +++ b/control/lti.py @@ -12,6 +12,7 @@ timebaseEqual() """ +import numpy as np from numpy import absolute, real __all__ = ['issiso', 'timebase', 'timebaseEqual', 'isdtime', 'isctime', @@ -96,7 +97,7 @@ def dcgain(self): # Test to see if a system is SISO def issiso(sys, strict=False): - if isinstance(sys, (int, float, complex)) and not strict: + if isinstance(sys, (int, float, complex, np.number)) and not strict: return True elif not isinstance(sys, LTI): raise ValueError("Object is not an LTI system") @@ -114,7 +115,7 @@ def timebase(sys, strict=True): set to False, dt = True will be returned as 1. """ # System needs to be either a constant or an LTI system - if isinstance(sys, (int, float, complex)): + if isinstance(sys, (int, float, complex, np.number)): return None elif not isinstance(sys, LTI): raise ValueError("Timebase not defined") @@ -162,7 +163,7 @@ def isdtime(sys, strict=False): """ # Check to see if this is a constant - if isinstance(sys, (int, float, complex)): + if isinstance(sys, (int, float, complex, np.number)): # OK as long as strict checking is off return True if not strict else False @@ -187,7 +188,7 @@ def isctime(sys, strict=False): """ # Check to see if this is a constant - if isinstance(sys, (int, float, complex)): + if isinstance(sys, (int, float, complex, np.number)): # OK as long as strict checking is off return True if not strict else False diff --git a/control/statesp.py b/control/statesp.py index 13e662f03..816485f77 100644 --- a/control/statesp.py +++ b/control/statesp.py @@ -58,6 +58,7 @@ from numpy.random import rand, randn from numpy.linalg import solve, eigvals, matrix_rank from numpy.linalg.linalg import LinAlgError +import scipy as sp from scipy.signal import lti, cont2discrete # from exceptions import Exception import warnings @@ -218,7 +219,7 @@ def __add__(self, other): """Add two LTI systems (parallel connection).""" # Check for a couple of special cases - if (isinstance(other, (int, float, complex))): + if (isinstance(other, (int, float, complex, np.number))): # Just adding a scalar; put it in the D matrix A, B, C = self.A, self.B, self.C; D = self.D + other; @@ -275,7 +276,7 @@ def __mul__(self, other): """Multiply two LTI objects (serial connection).""" # Check for a couple of special cases - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): # Just multiplying by a scalar; change the output A, B = self.A, self.B C = self.C * other @@ -316,7 +317,7 @@ def __rmul__(self, other): """Right multiply two LTI objects (serial connection).""" # Check for a couple of special cases - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): # Just multiplying by a scalar; change the input A, C = self.A, self.C; B = self.B * other; @@ -699,11 +700,10 @@ def _convertToStateSpace(sys, **kw): # TODO: do we want to squeeze first and check dimenations? # I think this will fail if num and den aren't 1-D after # the squeeze - lti_sys = lti(squeeze(sys.num), squeeze(sys.den)) - return StateSpace(lti_sys.A, lti_sys.B, lti_sys.C, lti_sys.D, - sys.dt) + A, B, C, D = sp.signal.tf2ss(squeeze(sys.num), squeeze(sys.den)) + return StateSpace(A, B, C, D, sys.dt) - elif isinstance(sys, (int, float, complex)): + elif isinstance(sys, (int, float, complex, np.number)): if "inputs" in kw: inputs = kw["inputs"] else: diff --git a/control/xferfcn.py b/control/xferfcn.py index be21f8509..0d7d2f417 100644 --- a/control/xferfcn.py +++ b/control/xferfcn.py @@ -52,10 +52,11 @@ """ # External function declarations +import numpy as np from numpy import angle, any, array, empty, finfo, insert, ndarray, ones, \ polyadd, polymul, polyval, roots, sort, sqrt, zeros, squeeze, exp, pi, \ where, delete, real, poly, poly1d -import numpy as np +import scipy as sp from scipy.signal import lti, tf2zpk, zpk2tf, cont2discrete from copy import deepcopy from warnings import warn @@ -126,7 +127,7 @@ def __init__(self, *args): data = [num, den] for i in range(len(data)): # Check for a scalar (including 0d ndarray) - if (isinstance(data[i], (int, float, complex)) or + if (isinstance(data[i], (int, float, complex, np.number)) or (isinstance(data[i], ndarray) and data[i].ndim == 0)): # Convert scalar to list of list of array. if (isinstance(data[i], int)): @@ -135,7 +136,7 @@ def __init__(self, *args): else: data[i] = [[array([data[i]])]] elif (isinstance(data[i], (list, tuple, ndarray)) and - isinstance(data[i][0], (int, float, complex))): + isinstance(data[i][0], (int, float, complex, np.number))): # Convert array to list of list of array. if (isinstance(data[i][0], int)): # Convert integers to floats at this point @@ -146,7 +147,8 @@ def __init__(self, *args): elif (isinstance(data[i], list) and isinstance(data[i][0], list) and isinstance(data[i][0][0], (list, tuple, ndarray)) and - isinstance(data[i][0][0][0], (int, float, complex))): + isinstance(data[i][0][0][0], (int, float, complex, + np.number))): # We might already have the right format. Convert the # coefficient vectors to arrays, if necessary. for j in range(len(data[i])): @@ -363,7 +365,7 @@ def __rsub__(self, other): def __mul__(self, other): """Multiply two LTI objects (serial connection).""" # Convert the second argument to a transfer function. - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): other = _convertToTransferFunction(other, inputs=self.inputs, outputs=self.inputs) else: @@ -410,7 +412,7 @@ def __rmul__(self, other): """Right multiply two LTI objects (serial connection).""" # Convert the second argument to a transfer function. - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): other = _convertToTransferFunction(other, inputs=self.inputs, outputs=self.inputs) else: @@ -458,7 +460,7 @@ def __rmul__(self, other): def __truediv__(self, other): """Divide two LTI objects.""" - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): other = _convertToTransferFunction( other, inputs=self.inputs, outputs=self.inputs) @@ -492,7 +494,7 @@ def __div__(self, other): # TODO: Division of MIMO transfer function objects is not written yet. def __rtruediv__(self, other): """Right divide two LTI objects.""" - if isinstance(other, (int, float, complex)): + if isinstance(other, (int, float, complex, np.number)): other = _convertToTransferFunction( other, inputs=self.inputs, outputs=self.inputs) @@ -1128,22 +1130,21 @@ def _convertToTransferFunction(sys, **kw): # Each transfer function matrix row # has a common denominator. den[i][j] = list(tfout[5][i, :]) - # print(num) - # print(den) + except ImportError: # If slycot is not available, use signal.lti (SISO only) if (sys.inputs != 1 or sys.outputs != 1): raise TypeError("No support for MIMO without slycot") - lti_sys = lti(sys.A, sys.B, sys.C, sys.D) - num = squeeze(lti_sys.num) - den = squeeze(lti_sys.den) - # print(num) - # print(den) + # Do the conversion using sp.signal.ss2tf + # Note that this returns a 2D array for the numerator + num, den = sp.signal.ss2tf(sys.A, sys.B, sys.C, sys.D) + num = squeeze(num) # Convert to 1D array + den = squeeze(den) # Probably not needed return TransferFunction(num, den, sys.dt) - elif isinstance(sys, (int, float, complex)): + elif isinstance(sys, (int, float, complex, np.number)): if "inputs" in kw: inputs = kw["inputs"] else: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy