def __init__(self, *args, **kwords): """Initialize the LTI system using either: (numerator, denominator) (zeros, poles, gain) (A, B, C, D) -- state-space. """ N = len(args) if N == 2: # Numerator denominator transfer function input self.__dict__["num"], self.__dict__["den"] = normalize(*args) self.__dict__["zeros"], self.__dict__["poles"], self.__dict__["gain"] = tf2zpk(*args) self.__dict__["A"], self.__dict__["B"], self.__dict__["C"], self.__dict__["D"] = tf2ss(*args) self.inputs = 1 if len(self.num.shape) > 1: self.outputs = self.num.shape[0] else: self.outputs = 1 elif N == 3: # Zero-pole-gain form self.__dict__["zeros"], self.__dict__["poles"], self.__dict__["gain"] = args self.__dict__["num"], self.__dict__["den"] = zpk2tf(*args) self.__dict__["A"], self.__dict__["B"], self.__dict__["C"], self.__dict__["D"] = zpk2ss(*args) self.inputs = 1 if len(self.zeros.shape) > 1: self.outputs = self.zeros.shape[0] else: self.outputs = 1 elif N == 4: # State-space form self.__dict__["A"], self.__dict__["B"], self.__dict__["C"], self.__dict__["D"] = abcd_normalize(*args) self.__dict__["zeros"], self.__dict__["poles"], self.__dict__["gain"] = ss2zpk(*args) self.__dict__["num"], self.__dict__["den"] = ss2tf(*args) self.inputs = self.B.shape[-1] self.outputs = self.C.shape[0] else: raise ValueError("Needs 2, 3, or 4 arguments.")
def tf2ss(num, den): """Transfer function to state-space representation. Parameters ---------- num, den : array_like Sequences representing the numerator and denominator polynomials. The denominator needs to be at least as long as the numerator. Returns ------- A, B, C, D : ndarray State space representation of the system. """ # Controller canonical state-space representation. # if M+1 = len(num) and K+1 = len(den) then we must have M <= K # states are found by asserting that X(s) = U(s) / D(s) # then Y(s) = N(s) * X(s) # # A, B, C, and D follow quite naturally. # num, den = normalize(num, den) # Strips zeros, checks arrays nn = len(num.shape) if nn == 1: num = asarray([num], num.dtype) M = num.shape[1] K = len(den) if M > K: msg = "Improper transfer function. `num` is longer than `den`." raise ValueError(msg) if M == 0 or K == 0: # Null system return array([], float), array([], float), array([], float), \ array([], float) # pad numerator to have same number of columns has denominator num = r_['-1', zeros((num.shape[0], K - M), num.dtype), num] if num.shape[-1] > 0: D = num[:, 0] else: D = array([], float) if K == 1: return array([], float), array([], float), array([], float), D frow = -array([den[1:]]) A = r_[frow, eye(K - 2, K - 1)] B = eye(K - 1, 1) C = num[:, 1:] - num[:, 0] * den[1:] return A, B, C, D
def __init__(self, *args, **kwords): """ Initialize the LTI system using either: - (numerator, denominator) - (zeros, poles, gain) - (A, B, C, D) : state-space. """ N = len(args) if N == 2: # Numerator denominator transfer function input self.__dict__['num'], self.__dict__['den'] = normalize(*args) self.__dict__['zeros'], self.__dict__['poles'], \ self.__dict__['gain'] = tf2zpk(*args) self.__dict__['A'], self.__dict__['B'], \ self.__dict__['C'], \ self.__dict__['D'] = tf2ss(*args) self.inputs = 1 if len(self.num.shape) > 1: self.outputs = self.num.shape[0] else: self.outputs = 1 elif N == 3: # Zero-pole-gain form self.__dict__['zeros'], self.__dict__['poles'], \ self.__dict__['gain'] = args self.__dict__['num'], self.__dict__['den'] = zpk2tf(*args) self.__dict__['A'], self.__dict__['B'], \ self.__dict__['C'], \ self.__dict__['D'] = zpk2ss(*args) # make sure we have numpy arrays self.zeros = numpy.asarray(self.zeros) self.poles = numpy.asarray(self.poles) self.inputs = 1 if len(self.zeros.shape) > 1: self.outputs = self.zeros.shape[0] else: self.outputs = 1 elif N == 4: # State-space form self.__dict__['A'], self.__dict__['B'], \ self.__dict__['C'], \ self.__dict__['D'] = abcd_normalize(*args) self.__dict__['zeros'], self.__dict__['poles'], \ self.__dict__['gain'] = ss2zpk(*args) self.__dict__['num'], self.__dict__['den'] = ss2tf(*args) self.inputs = self.B.shape[-1] self.outputs = self.C.shape[0] else: raise ValueError("Needs 2, 3, or 4 arguments.")
def tf2ss(num, den): """Transfer function to state-space representation. Inputs: num, den -- sequences representing the numerator and denominator polynomials. Outputs: A, B, C, D -- state space representation of the system. """ # Controller canonical state-space representation. # if M+1 = len(num) and K+1 = len(den) then we must have M <= K # states are found by asserting that X(s) = U(s) / D(s) # then Y(s) = N(s) * X(s) # # A, B, C, and D follow quite naturally. # num, den = normalize(num, den) # Strips zeros, checks arrays nn = len(num.shape) if nn == 1: num = asarray([num], num.dtype) M = num.shape[1] K = len(den) if (M > K): raise ValueError, "Improper transfer function." if (M == 0 or K == 0): # Null system return array([],float), array([], float), array([], float), \ array([], float) # pad numerator to have same number of columns has denominator num = r_['-1',zeros((num.shape[0],K-M), num.dtype), num] if num.shape[-1] > 0: D = num[:,0] else: D = array([],float) if K == 1: return array([], float), array([], float), array([], float), D frow = -array([den[1:]]) A = r_[frow, eye(K-2, K-1)] B = eye(K-1, 1) C = num[:,1:] - num[:,0] * den[1:] return A, B, C, D