signal.ltisys

ltisys – a collection of classes and functions for modeling linear time invariant systems.

Module Contents

Classes

LinearTimeInvariant(self)
lti(self,*system) Continuous-time linear time invariant system base class.
dlti(self,*system,**kwargs) Discrete-time linear time invariant system base class.
TransferFunction(self,*system,**kwargs) rLinear Time Invariant system class in transfer function form.
TransferFunctionContinuous() r
TransferFunctionDiscrete() r
ZerosPolesGain(self,*system,**kwargs) r
ZerosPolesGainContinuous() r
ZerosPolesGainDiscrete() r
StateSpace(self,*system,**kwargs) r
StateSpaceContinuous() r
StateSpaceDiscrete() r
Bunch(self,**kwds)

Functions

_atleast_2d_or_none(arg)
lsim2(system,U=None,T=None,X0=None,**kwargs) Simulate output of a continuous-time linear system, by using
_cast_to_array_dtype(in1,in2) Cast array to dtype of other array, while avoiding ComplexWarning.
lsim(system,U,T,X0=None,interp=True) Simulate output of a continuous-time linear system.
_default_response_times(A,n) Compute a reasonable set of time samples for the response time.
impulse(system,X0=None,T=None,N=None) Impulse response of continuous-time system.
impulse2(system,X0=None,T=None,N=None,**kwargs) Impulse response of a single-input, continuous-time linear system.
step(system,X0=None,T=None,N=None) Step response of continuous-time system.
step2(system,X0=None,T=None,N=None,**kwargs) Step response of continuous-time system.
bode(system,w=None,n=100) Calculate Bode magnitude and phase data of a continuous-time system.
freqresp(system,w=None,n=10000) Calculate the frequency response of a continuous-time system.
_valid_inputs(A,B,poles,method,rtol,maxiter) Check the poles come in complex conjugage pairs
_order_complex_poles(poles) Check we have complex conjugates pairs and reorder P according to YT, ie
_KNV0(B,ker_pole,transfer_matrix,j,poles) Algorithm “KNV0” Kautsky et Al. Robust pole
_YT_real(ker_pole,Q,transfer_matrix,i,j) Applies algorithm from YT section 6.1 page 19 related to real pairs
_YT_complex(ker_pole,Q,transfer_matrix,i,j) Applies algorithm from YT section 6.2 page 20 related to complex pairs
_YT_loop(ker_pole,transfer_matrix,poles,B,maxiter,rtol) Algorithm “YT” Tits, Yang. Globally Convergent
_KNV0_loop(ker_pole,transfer_matrix,poles,B,maxiter,rtol) Loop over all poles one by one and apply KNV method 0 algorithm
place_poles(A,B,poles,method=”YT”,rtol=0.001,maxiter=30) Compute K such that eigenvalues (A - dot(B, K))=poles.
dlsim(system,u,t=None,x0=None) Simulate output of a discrete-time linear system.
dimpulse(system,x0=None,t=None,n=None) Impulse response of discrete-time system.
dstep(system,x0=None,t=None,n=None) Step response of discrete-time system.
dfreqresp(system,w=None,n=10000,whole=False) Calculate the frequency response of a discrete-time system.
dbode(system,w=None,n=100) Calculate Bode magnitude and phase data of a discrete-time system.
class LinearTimeInvariant
__new__(*system, **kwargs)

Create a new object, don’t allow direct instances.

__init__()

Initialize the lti baseclass.

The heavy lifting is done by the subclasses.

dt()

Return the sampling time of the system, None for lti systems.

_dt_dict()
zeros()

Zeros of the system.

poles()

Poles of the system.

_as_ss()

Convert to StateSpace system, without copying.

sys: StateSpace
The StateSpace system. If the class is already an instance of StateSpace then this instance is returned.
_as_zpk()

Convert to ZerosPolesGain system, without copying.

sys: ZerosPolesGain
The ZerosPolesGain system. If the class is already an instance of ZerosPolesGain then this instance is returned.
_as_tf()

Convert to TransferFunction system, without copying.

sys: ZerosPolesGain
The TransferFunction system. If the class is already an instance of TransferFunction then this instance is returned.
class lti(*system)

Continuous-time linear time invariant system base class.

*system : arguments

The lti class can be instantiated with either 2, 3 or 4 arguments. The following gives the number of arguments and the corresponding continuous-time subclass that is created:

  • 2: TransferFunction: (numerator, denominator)
  • 3: ZerosPolesGain: (zeros, poles, gain)
  • 4: StateSpace: (A, B, C, D)

Each argument can be an array or a sequence.

ZerosPolesGain, StateSpace, TransferFunction, dlti

lti instances do not exist directly. Instead, lti creates an instance of one of its subclasses: StateSpace, TransferFunction or ZerosPolesGain.

If (numerator, denominator) is passed in for *system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g., s^2 + 3s + 5 would be represented as [1, 3, 5]).

Changing the value of properties that are not directly part of the current system representation (such as the zeros of a StateSpace system) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_zpk() before accessing/changing the zeros, poles or gain.

>>> from scipy import signal
>>> signal.lti(1, 2, 3, 4)
StateSpaceContinuous(
array([[1]]),
array([[2]]),
array([[3]]),
array([[4]]),
dt: None
)
>>> signal.lti([1, 2], [3, 4], 5)
ZerosPolesGainContinuous(
array([1, 2]),
array([3, 4]),
5,
dt: None
)
>>> signal.lti([3, 4], [1, 2])
TransferFunctionContinuous(
array([ 3.,  4.]),
array([ 1.,  2.]),
dt: None
)
__new__(*system)

Create an instance of the appropriate subclass.

__init__(*system)

Initialize the lti baseclass.

The heavy lifting is done by the subclasses.

impulse(X0=None, T=None, N=None)

Return the impulse response of a continuous-time system. See impulse for details.

step(X0=None, T=None, N=None)

Return the step response of a continuous-time system. See step for details.

output(U, T, X0=None)

Return the response of a continuous-time system to input U. See lsim for details.

bode(w=None, n=100)

Calculate Bode magnitude and phase data of a continuous-time system.

Returns a 3-tuple containing arrays of frequencies [rad/s], magnitude [dB] and phase [deg]. See bode for details.

>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> sys = signal.TransferFunction([1], [1, 1])
>>> w, mag, phase = sys.bode()
>>> plt.figure()
>>> plt.semilogx(w, mag)    # Bode magnitude plot
>>> plt.figure()
>>> plt.semilogx(w, phase)  # Bode phase plot
>>> plt.show()
freqresp(w=None, n=10000)

Calculate the frequency response of a continuous-time system.

Returns a 2-tuple containing arrays of frequencies [rad/s] and complex magnitude. See freqresp for details.

to_discrete(dt, method="zoh", alpha=None)

Return a discretized version of the current system.

Parameters: See cont2discrete for details.

sys: instance of dlti

class dlti(*system, **kwargs)

Discrete-time linear time invariant system base class.

*system: arguments

The dlti class can be instantiated with either 2, 3 or 4 arguments. The following gives the number of arguments and the corresponding discrete-time subclass that is created:

  • 2: TransferFunction: (numerator, denominator)
  • 3: ZerosPolesGain: (zeros, poles, gain)
  • 4: StateSpace: (A, B, C, D)

Each argument can be an array or a sequence.

dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to True (unspecified sampling time). Must be specified as a keyword argument, for example, dt=0.1.

ZerosPolesGain, StateSpace, TransferFunction, lti

dlti instances do not exist directly. Instead, dlti creates an instance of one of its subclasses: StateSpace, TransferFunction or ZerosPolesGain.

Changing the value of properties that are not directly part of the current system representation (such as the zeros of a StateSpace system) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_zpk() before accessing/changing the zeros, poles or gain.

If (numerator, denominator) is passed in for *system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g., z^2 + 3z + 5 would be represented as [1, 3, 5]).

New in version 0.18.0.

>>> from scipy import signal
>>> signal.dlti(1, 2, 3, 4)
StateSpaceDiscrete(
array([[1]]),
array([[2]]),
array([[3]]),
array([[4]]),
dt: True
)
>>> signal.dlti(1, 2, 3, 4, dt=0.1)
StateSpaceDiscrete(
array([[1]]),
array([[2]]),
array([[3]]),
array([[4]]),
dt: 0.1
)
>>> signal.dlti([1, 2], [3, 4], 5, dt=0.1)
ZerosPolesGainDiscrete(
array([1, 2]),
array([3, 4]),
5,
dt: 0.1
)
>>> signal.dlti([3, 4], [1, 2], dt=0.1)
TransferFunctionDiscrete(
array([ 3.,  4.]),
array([ 1.,  2.]),
dt: 0.1
)
__new__(*system, **kwargs)

Create an instance of the appropriate subclass.

__init__(*system, **kwargs)

Initialize the lti baseclass.

The heavy lifting is done by the subclasses.

dt()

Return the sampling time of the system.

dt(dt)
impulse(x0=None, t=None, n=None)

Return the impulse response of the discrete-time dlti system. See dimpulse for details.

step(x0=None, t=None, n=None)

Return the step response of the discrete-time dlti system. See dstep for details.

output(u, t, x0=None)

Return the response of the discrete-time system to input u. See dlsim for details.

bode(w=None, n=100)

Calculate Bode magnitude and phase data of a discrete-time system.

Returns a 3-tuple containing arrays of frequencies [rad/s], magnitude [dB] and phase [deg]. See dbode for details.

>>> from scipy import signal
>>> import matplotlib.pyplot as plt

Transfer function: H(z) = 1 / (z^2 + 2z + 3) with sampling time 0.5s

>>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.5)

Equivalent: signal.dbode(sys)

>>> w, mag, phase = sys.bode()
>>> plt.figure()
>>> plt.semilogx(w, mag)    # Bode magnitude plot
>>> plt.figure()
>>> plt.semilogx(w, phase)  # Bode phase plot
>>> plt.show()
freqresp(w=None, n=10000, whole=False)

Calculate the frequency response of a discrete-time system.

Returns a 2-tuple containing arrays of frequencies [rad/s] and complex magnitude. See dfreqresp for details.

class TransferFunction(*system, **kwargs)

rLinear Time Invariant system class in transfer function form.

Represents the system as the continuous-time transfer function or the discrete-time transfer function , where are elements of the numerator num, are elements of the denominator den, and N == len(b) - 1, M == len(a) - 1. TransferFunction systems inherit additional functionality from the lti, respectively the dlti classes, depending on which system representation is used.

*system: arguments

The TransferFunction class can be instantiated with 1 or 2 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti or dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 2: array_like: (numerator, denominator)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to None (continuous-time). Must be specified as a keyword argument, for example, dt=0.1.

ZerosPolesGain, StateSpace, lti, dlti tf2ss, tf2zpk, tf2sos

Changing the value of properties that are not part of the TransferFunction system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_ss() before accessing/changing the A, B, C, D system matrices.

If (numerator, denominator) is passed in for *system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 or z^2 + 3z + 5 would be represented as [1, 3, 5])

Construct the transfer function:

>>> from scipy import signal
>>> num = [1, 3, 3]
>>> den = [1, 2, 1]
>>> signal.TransferFunction(num, den)
TransferFunctionContinuous(
array([ 1.,  3.,  3.]),
array([ 1.,  2.,  1.]),
dt: None
)

Contruct the transfer function with a sampling time of 0.1 seconds:

>>> signal.TransferFunction(num, den, dt=0.1)
TransferFunctionDiscrete(
array([ 1.,  3.,  3.]),
array([ 1.,  2.,  1.]),
dt: 0.1
)
__new__(*system, **kwargs)

Handle object conversion if input is an instance of lti.

__init__(*system, **kwargs)

Initialize the state space LTI system.

__repr__()

Return representation of the system’s transfer function

num()

Numerator of the TransferFunction system.

num(num)
den()

Denominator of the TransferFunction system.

den(den)
_copy(system)

Copy the parameters of another TransferFunction object

system : TransferFunction
The StateSpace system that is to be copied
to_tf()

Return a copy of the current TransferFunction system.

sys : instance of TransferFunction
The current system (copy)
to_zpk()

Convert system representation to ZerosPolesGain.

sys : instance of ZerosPolesGain
Zeros, poles, gain representation of the current system
to_ss()

Convert system representation to StateSpace.

sys : instance of StateSpace
State space model of the current system
_z_to_zinv(den)

Change a transfer function from the variable z to z**-1.

num, den: 1d array_like
Sequences representing the coefficients of the numerator and denominator polynomials, in order of descending degree of ‘z’. That is, 5z**2 + 3z + 2 is presented as [5, 3, 2].
num, den: 1d array_like
Sequences representing the coefficients of the numerator and denominator polynomials, in order of ascending degree of ‘z**-1’. That is, 5 + 3 z**-1 + 2 z**-2 is presented as [5, 3, 2].
_zinv_to_z(den)

Change a transfer function from the variable z to z**-1.

num, den: 1d array_like
Sequences representing the coefficients of the numerator and denominator polynomials, in order of ascending degree of ‘z**-1’. That is, 5 + 3 z**-1 + 2 z**-2 is presented as [5, 3, 2].
num, den: 1d array_like
Sequences representing the coefficients of the numerator and denominator polynomials, in order of descending degree of ‘z’. That is, 5z**2 + 3z + 2 is presented as [5, 3, 2].
class TransferFunctionContinuous

r Continuous-time Linear Time Invariant system in transfer function form.

Represents the system as the transfer function , where are elements of the numerator num, are elements of the denominator den, and N == len(b) - 1, M == len(a) - 1. Continuous-time TransferFunction systems inherit additional functionality from the lti class.

*system: arguments

The TransferFunction class can be instantiated with 1 or 2 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 2: array_like: (numerator, denominator)

ZerosPolesGain, StateSpace, lti tf2ss, tf2zpk, tf2sos

Changing the value of properties that are not part of the TransferFunction system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_ss() before accessing/changing the A, B, C, D system matrices.

If (numerator, denominator) is passed in for *system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5])

Construct the transfer function:

>>> from scipy import signal
>>> num = [1, 3, 3]
>>> den = [1, 2, 1]
>>> signal.TransferFunction(num, den)
TransferFunctionContinuous(
array([ 1.,  3.,  3.]),
array([ 1.,  2.,  1.]),
dt: None
)
to_discrete(dt, method="zoh", alpha=None)

Returns the discretized TransferFunction system.

Parameters: See cont2discrete for details.

sys: instance of dlti and StateSpace

class TransferFunctionDiscrete

r Discrete-time Linear Time Invariant system in transfer function form.

Represents the system as the transfer function , where are elements of the numerator num, are elements of the denominator den, and N == len(b) - 1, M == len(a) - 1. Discrete-time TransferFunction systems inherit additional functionality from the dlti class.

*system: arguments

The TransferFunction class can be instantiated with 1 or 2 arguments. The following gives the number of input arguments and their interpretation:

  • 1: dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 2: array_like: (numerator, denominator)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to True (unspecified sampling time). Must be specified as a keyword argument, for example, dt=0.1.

ZerosPolesGain, StateSpace, dlti tf2ss, tf2zpk, tf2sos

Changing the value of properties that are not part of the TransferFunction system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies.

If (numerator, denominator) is passed in for *system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g., z^2 + 3z + 5 would be represented as [1, 3, 5]).

Construct the transfer function with a sampling time of 0.5 seconds:

>>> from scipy import signal
>>> num = [1, 3, 3]
>>> den = [1, 2, 1]
>>> signal.TransferFunction(num, den, 0.5)
TransferFunctionDiscrete(
array([ 1.,  3.,  3.]),
array([ 1.,  2.,  1.]),
dt: 0.5
)
class ZerosPolesGain(*system, **kwargs)

r Linear Time Invariant system class in zeros, poles, gain form.

Represents the system as the continuous- or discrete-time transfer function , where is the gain, are the zeros and are the poles. ZerosPolesGain systems inherit additional functionality from the lti, respectively the dlti classes, depending on which system representation is used.

*system : arguments

The ZerosPolesGain class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti or dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 3: array_like: (zeros, poles, gain)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to None (continuous-time). Must be specified as a keyword argument, for example, dt=0.1.

TransferFunction, StateSpace, lti, dlti zpk2ss, zpk2tf, zpk2sos

Changing the value of properties that are not part of the ZerosPolesGain system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_ss() before accessing/changing the A, B, C, D system matrices.

>>> from scipy import signal

Transfer function: H(s) = 5(s - 1)(s - 2) / (s - 3)(s - 4)

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5)
ZerosPolesGainContinuous(
array([1, 2]),
array([3, 4]),
5,
dt: None
)

Transfer function: H(z) = 5(z - 1)(z - 2) / (z - 3)(z - 4)

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5, dt=0.1)
ZerosPolesGainDiscrete(
array([1, 2]),
array([3, 4]),
5,
dt: 0.1
)
__new__(*system, **kwargs)

Handle object conversion if input is an instance of lti

__init__(*system, **kwargs)

Initialize the zeros, poles, gain system.

__repr__()

Return representation of the ZerosPolesGain system.

zeros()

Zeros of the ZerosPolesGain system.

zeros(zeros)
poles()

Poles of the ZerosPolesGain system.

poles(poles)
gain()

Gain of the ZerosPolesGain system.

gain(gain)
_copy(system)

Copy the parameters of another ZerosPolesGain system.

system : instance of ZerosPolesGain
The zeros, poles gain system that is to be copied
to_tf()

Convert system representation to TransferFunction.

sys : instance of TransferFunction
Transfer function of the current system
to_zpk()

Return a copy of the current ‘ZerosPolesGain’ system.

sys : instance of ZerosPolesGain
The current system (copy)
to_ss()

Convert system representation to StateSpace.

sys : instance of StateSpace
State space model of the current system
class ZerosPolesGainContinuous

r Continuous-time Linear Time Invariant system in zeros, poles, gain form.

Represents the system as the continuous time transfer function , where is the gain, are the zeros and are the poles. Continuous-time ZerosPolesGain systems inherit additional functionality from the lti class.

*system : arguments

The ZerosPolesGain class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 3: array_like: (zeros, poles, gain)

TransferFunction, StateSpace, lti zpk2ss, zpk2tf, zpk2sos

Changing the value of properties that are not part of the ZerosPolesGain system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_ss() before accessing/changing the A, B, C, D system matrices.

>>> from scipy import signal

Transfer function: H(s) = 5(s - 1)(s - 2) / (s - 3)(s - 4)

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5)
ZerosPolesGainContinuous(
array([1, 2]),
array([3, 4]),
5,
dt: None
)
to_discrete(dt, method="zoh", alpha=None)

Returns the discretized ZerosPolesGain system.

Parameters: See cont2discrete for details.

sys: instance of dlti and ZerosPolesGain

class ZerosPolesGainDiscrete

r Discrete-time Linear Time Invariant system in zeros, poles, gain form.

Represents the system as the discrete-time transfer function , where is the gain, are the zeros and are the poles. Discrete-time ZerosPolesGain systems inherit additional functionality from the dlti class.

*system : arguments

The ZerosPolesGain class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 3: array_like: (zeros, poles, gain)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to True (unspecified sampling time). Must be specified as a keyword argument, for example, dt=0.1.

TransferFunction, StateSpace, dlti zpk2ss, zpk2tf, zpk2sos

Changing the value of properties that are not part of the ZerosPolesGain system representation (such as the A, B, C, D state-space matrices) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_ss() before accessing/changing the A, B, C, D system matrices.

>>> from scipy import signal

Transfer function: H(s) = 5(s - 1)(s - 2) / (s - 3)(s - 4)

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5)
ZerosPolesGainContinuous(
array([1, 2]),
array([3, 4]),
5,
dt: None
)

Transfer function: H(z) = 5(z - 1)(z - 2) / (z - 3)(z - 4)

>>> signal.ZerosPolesGain([1, 2], [3, 4], 5, dt=0.1)
ZerosPolesGainDiscrete(
array([1, 2]),
array([3, 4]),
5,
dt: 0.1
)
_atleast_2d_or_none(arg)
class StateSpace(*system, **kwargs)

r Linear Time Invariant system in state-space form.

Represents the system as the continuous-time, first order differential equation or the discrete-time difference equation . StateSpace systems inherit additional functionality from the lti, respectively the dlti classes, depending on which system representation is used.

*system: arguments

The StateSpace class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti or dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 4: array_like: (A, B, C, D)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to None (continuous-time). Must be specified as a keyword argument, for example, dt=0.1.

TransferFunction, ZerosPolesGain, lti, dlti ss2zpk, ss2tf, zpk2sos

Changing the value of properties that are not part of the StateSpace system representation (such as zeros or poles) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_zpk() before accessing/changing the zeros, poles or gain.

>>> from scipy import signal
>>> a = np.array([[0, 1], [0, 0]])
>>> b = np.array([[0], [1]])
>>> c = np.array([[1, 0]])
>>> d = np.array([[0]])
>>> sys = signal.StateSpace(a, b, c, d)
>>> print(sys)
StateSpaceContinuous(
array([[0, 1],
       [0, 0]]),
array([[0],
       [1]]),
array([[1, 0]]),
array([[0]]),
dt: None
)
>>> sys.to_discrete(0.1)
StateSpaceDiscrete(
array([[ 1. ,  0.1],
       [ 0. ,  1. ]]),
array([[ 0.005],
       [ 0.1  ]]),
array([[1, 0]]),
array([[0]]),
dt: 0.1
)
>>> a = np.array([[1, 0.1], [0, 1]])
>>> b = np.array([[0.005], [0.1]])
>>> signal.StateSpace(a, b, c, d, dt=0.1)
StateSpaceDiscrete(
array([[ 1. ,  0.1],
       [ 0. ,  1. ]]),
array([[ 0.005],
       [ 0.1  ]]),
array([[1, 0]]),
array([[0]]),
dt: 0.1
)
__new__(*system, **kwargs)

Create new StateSpace object and settle inheritance.

__init__(*system, **kwargs)

Initialize the state space lti/dlti system.

__repr__()

Return representation of the StateSpace system.

A()

State matrix of the StateSpace system.

A(A)
B()

Input matrix of the StateSpace system.

B(B)
C()

Output matrix of the StateSpace system.

C(C)
D()

Feedthrough matrix of the StateSpace system.

D(D)
_copy(system)

Copy the parameters of another StateSpace system.

system : instance of StateSpace
The state-space system that is to be copied
to_tf(**kwargs)

Convert system representation to TransferFunction.

kwargs : dict, optional
Additional keywords passed to ss2zpk
sys : instance of TransferFunction
Transfer function of the current system
to_zpk(**kwargs)

Convert system representation to ZerosPolesGain.

kwargs : dict, optional
Additional keywords passed to ss2zpk
sys : instance of ZerosPolesGain
Zeros, poles, gain representation of the current system
to_ss()

Return a copy of the current StateSpace system.

sys : instance of StateSpace
The current system (copy)
class StateSpaceContinuous

r Continuous-time Linear Time Invariant system in state-space form.

Represents the system as the continuous-time, first order differential equation . Continuous-time StateSpace systems inherit additional functionality from the lti class.

*system: arguments

The StateSpace class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: lti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 4: array_like: (A, B, C, D)

TransferFunction, ZerosPolesGain, lti ss2zpk, ss2tf, zpk2sos

Changing the value of properties that are not part of the StateSpace system representation (such as zeros or poles) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_zpk() before accessing/changing the zeros, poles or gain.

>>> from scipy import signal
>>> a = np.array([[0, 1], [0, 0]])
>>> b = np.array([[0], [1]])
>>> c = np.array([[1, 0]])
>>> d = np.array([[0]])
>>> sys = signal.StateSpace(a, b, c, d)
>>> print(sys)
StateSpaceContinuous(
array([[0, 1],
       [0, 0]]),
array([[0],
       [1]]),
array([[1, 0]]),
array([[0]]),
dt: None
)
to_discrete(dt, method="zoh", alpha=None)

Returns the discretized StateSpace system.

Parameters: See cont2discrete for details.

sys: instance of dlti and StateSpace

class StateSpaceDiscrete

r Discrete-time Linear Time Invariant system in state-space form.

Represents the system as the discrete-time difference equation . StateSpace systems inherit additional functionality from the dlti class.

*system: arguments

The StateSpace class can be instantiated with 1 or 3 arguments. The following gives the number of input arguments and their interpretation:

  • 1: dlti system: (StateSpace, TransferFunction or ZerosPolesGain)
  • 4: array_like: (A, B, C, D)
dt: float, optional
Sampling time [s] of the discrete-time systems. Defaults to True (unspecified sampling time). Must be specified as a keyword argument, for example, dt=0.1.

TransferFunction, ZerosPolesGain, dlti ss2zpk, ss2tf, zpk2sos

Changing the value of properties that are not part of the StateSpace system representation (such as zeros or poles) is very inefficient and may lead to numerical inaccuracies. It is better to convert to the specific system representation first. For example, call sys = sys.to_zpk() before accessing/changing the zeros, poles or gain.

>>> from scipy import signal
>>> a = np.array([[1, 0.1], [0, 1]])
>>> b = np.array([[0.005], [0.1]])
>>> c = np.array([[1, 0]])
>>> d = np.array([[0]])
>>> signal.StateSpace(a, b, c, d, dt=0.1)
StateSpaceDiscrete(
array([[ 1. ,  0.1],
       [ 0. ,  1. ]]),
array([[ 0.005],
       [ 0.1  ]]),
array([[1, 0]]),
array([[0]]),
dt: 0.1
)
lsim2(system, U=None, T=None, X0=None, **kwargs)

Simulate output of a continuous-time linear system, by using the ODE solver scipy.integrate.odeint.

system : an instance of the lti class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1: (instance of lti)
  • 2: (num, den)
  • 3: (zeros, poles, gain)
  • 4: (A, B, C, D)
U : array_like (1D or 2D), optional
An input array describing the input at each time T. Linear interpolation is used between given times. If there are multiple inputs, then each column of the rank-2 array represents an input. If U is not given, the input is assumed to be zero.
T : array_like (1D or 2D), optional
The time steps at which the input is defined and at which the output is desired. The default is 101 evenly spaced points on the interval [0,10.0].
X0 : array_like (1D), optional
The initial condition of the state vector. If X0 is not given, the initial conditions are assumed to be 0.
kwargs : dict
Additional keyword arguments are passed on to the function odeint. See the notes below for more details.
T : 1D ndarray
The time values for the output.
yout : ndarray
The response of the system.
xout : ndarray
The time-evolution of the state-vector.

This function uses scipy.integrate.odeint to solve the system’s differential equations. Additional keyword arguments given to lsim2 are passed on to odeint. See the documentation for scipy.integrate.odeint for the full list of arguments.

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

_cast_to_array_dtype(in1, in2)

Cast array to dtype of other array, while avoiding ComplexWarning.

Those can be raised when casting complex to real.

lsim(system, U, T, X0=None, interp=True)

Simulate output of a continuous-time linear system.

system : an instance of the LTI class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1: (instance of lti)
  • 2: (num, den)
  • 3: (zeros, poles, gain)
  • 4: (A, B, C, D)
U : array_like
An input array describing the input at each time T (interpolation is assumed between given times). If there are multiple inputs, then each column of the rank-2 array represents an input. If U = 0 or None, a zero input is used.
T : array_like
The time steps at which the input is defined and at which the output is desired. Must be nonnegative, increasing, and equally spaced.
X0 : array_like, optional
The initial conditions on the state vector (zero by default).
interp : bool, optional
Whether to use linear (True, the default) or zero-order-hold (False) interpolation for the input array.
T : 1D ndarray
Time values for the output.
yout : 1D ndarray
System response.
xout : ndarray
Time evolution of the state vector.

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

Simulate a double integrator y’’ = u, with a constant input u = 1

>>> from scipy import signal
>>> system = signal.lti([[0., 1.], [0., 0.]], [[0.], [1.]], [[1., 0.]], 0.)
>>> t = np.linspace(0, 5)
>>> u = np.ones_like(t)
>>> tout, y, x = signal.lsim(system, u, t)
>>> import matplotlib.pyplot as plt
>>> plt.plot(t, y)
_default_response_times(A, n)

Compute a reasonable set of time samples for the response time.

This function is used by impulse, impulse2, step and step2 to compute the response time when the T argument to the function is None.

A : array_like
The system matrix, which is square.
n : int
The number of time samples to generate.
t : ndarray
The 1-D array of length n of time samples at which the response is to be computed.
impulse(system, X0=None, T=None, N=None)

Impulse response of continuous-time system.

system : an instance of the LTI class or a tuple of array_like

describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
X0 : array_like, optional
Initial state-vector. Defaults to zero.
T : array_like, optional
Time points. Computed if not given.
N : int, optional
The number of time points to compute (if T is not given).
T : ndarray
A 1-D array of time points.
yout : ndarray
A 1-D array containing the impulse response of the system (except for singularities at zero).

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

impulse2(system, X0=None, T=None, N=None, **kwargs)

Impulse response of a single-input, continuous-time linear system.

system : an instance of the LTI class or a tuple of array_like

describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
X0 : 1-D array_like, optional
The initial condition of the state vector. Default: 0 (the zero vector).
T : 1-D array_like, optional
The time steps at which the input is defined and at which the output is desired. If T is not given, the function will generate a set of time samples automatically.
N : int, optional
Number of time points to compute. Default: 100.
kwargs : various types
Additional keyword arguments are passed on to the function scipy.signal.lsim2, which in turn passes them on to scipy.integrate.odeint; see the latter’s documentation for information about these arguments.
T : ndarray
The time values for the output.
yout : ndarray
The output response of the system.

impulse, lsim2, integrate.odeint

The solution is generated by calling scipy.signal.lsim2, which uses the differential equation solver scipy.integrate.odeint.

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

New in version 0.8.0.

Second order system with a repeated root: x’‘(t) + 2*x(t) + x(t) = u(t)

>>> from scipy import signal
>>> system = ([1.0], [1.0, 2.0, 1.0])
>>> t, y = signal.impulse2(system)
>>> import matplotlib.pyplot as plt
>>> plt.plot(t, y)
step(system, X0=None, T=None, N=None)

Step response of continuous-time system.

system : an instance of the LTI class or a tuple of array_like

describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
X0 : array_like, optional
Initial state-vector (default is zero).
T : array_like, optional
Time points (computed if not given).
N : int, optional
Number of time points to compute if T is not given.
T : 1D ndarray
Output time points.
yout : 1D ndarray
Step response of system.

scipy.signal.step2

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

step2(system, X0=None, T=None, N=None, **kwargs)

Step response of continuous-time system.

This function is functionally the same as scipy.signal.step, but it uses the function scipy.signal.lsim2 to compute the step response.

system : an instance of the LTI class or a tuple of array_like

describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
X0 : array_like, optional
Initial state-vector (default is zero).
T : array_like, optional
Time points (computed if not given).
N : int, optional
Number of time points to compute if T is not given.
kwargs : various types
Additional keyword arguments are passed on the function scipy.signal.lsim2, which in turn passes them on to scipy.integrate.odeint. See the documentation for scipy.integrate.odeint for information about these arguments.
T : 1D ndarray
Output time points.
yout : 1D ndarray
Step response of system.

scipy.signal.step

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

New in version 0.8.0.

bode(system, w=None, n=100)

Calculate Bode magnitude and phase data of a continuous-time system.

system : an instance of the LTI class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
w : array_like, optional
Array of frequencies (in rad/s). Magnitude and phase data is calculated for every value in this array. If not given a reasonable set will be calculated.
n : int, optional
Number of frequency points to compute if w is not given. The n frequencies are logarithmically spaced in an interval chosen to include the influence of the poles and zeros of the system.
w : 1D ndarray
Frequency array [rad/s]
mag : 1D ndarray
Magnitude array [dB]
phase : 1D ndarray
Phase array [deg]

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

New in version 0.11.0.

>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> sys = signal.TransferFunction([1], [1, 1])
>>> w, mag, phase = signal.bode(sys)
>>> plt.figure()
>>> plt.semilogx(w, mag)    # Bode magnitude plot
>>> plt.figure()
>>> plt.semilogx(w, phase)  # Bode phase plot
>>> plt.show()
freqresp(system, w=None, n=10000)

Calculate the frequency response of a continuous-time system.

system : an instance of the lti class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of lti)
  • 2 (num, den)
  • 3 (zeros, poles, gain)
  • 4 (A, B, C, D)
w : array_like, optional
Array of frequencies (in rad/s). Magnitude and phase data is calculated for every value in this array. If not given, a reasonable set will be calculated.
n : int, optional
Number of frequency points to compute if w is not given. The n frequencies are logarithmically spaced in an interval chosen to include the influence of the poles and zeros of the system.
w : 1D ndarray
Frequency array [rad/s]
H : 1D ndarray
Array of complex magnitude values

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. s^2 + 3s + 5 would be represented as [1, 3, 5]).

Generating the Nyquist plot of a transfer function

>>> from scipy import signal
>>> import matplotlib.pyplot as plt

Transfer function: H(s) = 5 / (s-1)^3

>>> s1 = signal.ZerosPolesGain([], [1, 1, 1], [5])
>>> w, H = signal.freqresp(s1)
>>> plt.figure()
>>> plt.plot(H.real, H.imag, "b")
>>> plt.plot(H.real, -H.imag, "r")
>>> plt.show()
class Bunch(**kwds)
__init__(**kwds)
_valid_inputs(A, B, poles, method, rtol, maxiter)

Check the poles come in complex conjugage pairs Check shapes of A, B and poles are compatible. Check the method chosen is compatible with provided poles Return update method to use and ordered poles

_order_complex_poles(poles)

Check we have complex conjugates pairs and reorder P according to YT, ie real_poles, complex_i, conjugate complex_i, …. The lexicographic sort on the complex poles is added to help the user to compare sets of poles.

_KNV0(B, ker_pole, transfer_matrix, j, poles)

Algorithm “KNV0” Kautsky et Al. Robust pole assignment in linear state feedback, Int journal of Control 1985, vol 41 p 1129->1155 http://la.epfl.ch/files/content/sites/la/files/

users/105941/public/KautskyNicholsDooren
_YT_real(ker_pole, Q, transfer_matrix, i, j)

Applies algorithm from YT section 6.1 page 19 related to real pairs

_YT_complex(ker_pole, Q, transfer_matrix, i, j)

Applies algorithm from YT section 6.2 page 20 related to complex pairs

_YT_loop(ker_pole, transfer_matrix, poles, B, maxiter, rtol)

Algorithm “YT” Tits, Yang. Globally Convergent Algorithms for Robust Pole Assignment by State Feedback http://drum.lib.umd.edu/handle/1903/5598 The poles P have to be sorted accordingly to section 6.2 page 20

_KNV0_loop(ker_pole, transfer_matrix, poles, B, maxiter, rtol)

Loop over all poles one by one and apply KNV method 0 algorithm

place_poles(A, B, poles, method="YT", rtol=0.001, maxiter=30)

Compute K such that eigenvalues (A - dot(B, K))=poles.

K is the gain matrix such as the plant described by the linear system AX+BU will have its closed-loop poles, i.e the eigenvalues A - B*K, as close as possible to those asked for in poles.

SISO, MISO and MIMO systems are supported.

A, B : ndarray
State-space representation of linear system AX + BU.
poles : array_like
Desired real poles and/or complex conjugates poles. Complex poles are only supported with method="YT" (default).
method: {‘YT’, ‘KNV0’}, optional

Which method to choose to find the gain matrix K. One of:

  • ‘YT’: Yang Tits
  • ‘KNV0’: Kautsky, Nichols, Van Dooren update method 0

See References and Notes for details on the algorithms.

rtol: float, optional
After each iteration the determinant of the eigenvectors of A - B*K is compared to its previous value, when the relative error between these two values becomes lower than rtol the algorithm stops. Default is 1e-3.
maxiter: int, optional
Maximum number of iterations to compute the gain matrix. Default is 30.
full_state_feedback : Bunch object
full_state_feedback is composed of:
gain_matrix : 1-D ndarray
The closed loop matrix K such as the eigenvalues of A-BK are as close as possible to the requested poles.
computed_poles : 1-D ndarray
The poles corresponding to A-BK sorted as first the real poles in increasing order, then the complex congugates in lexicographic order.
requested_poles : 1-D ndarray
The poles the algorithm was asked to place sorted as above, they may differ from what was achieved.
X : 2-D ndarray
The transfer matrix such as X * diag(poles) = (A - B*K)*X (see Notes)
rtol : float
The relative tolerance achieved on det(X) (see Notes). rtol will be NaN if it is possible to solve the system diag(poles) = (A - B*K), or 0 when the optimization algorithms can’t do anything i.e when B.shape[1] == 1.
nb_iter : int
The number of iterations performed before converging. nb_iter will be NaN if it is possible to solve the system diag(poles) = (A - B*K), or 0 when the optimization algorithms can’t do anything i.e when B.shape[1] == 1.

The Tits and Yang (YT), [2] paper is an update of the original Kautsky et al. (KNV) paper [1]. KNV relies on rank-1 updates to find the transfer matrix X such that X * diag(poles) = (A - B*K)*X, whereas YT uses rank-2 updates. This yields on average more robust solutions (see [2] pp 21-22), furthermore the YT algorithm supports complex poles whereas KNV does not in its original version. Only update method 0 proposed by KNV has been implemented here, hence the name 'KNV0'.

KNV extended to complex poles is used in Matlab’s place function, YT is distributed under a non-free licence by Slicot under the name robpole. It is unclear and undocumented how KNV0 has been extended to complex poles (Tits and Yang claim on page 14 of their paper that their method can not be used to extend KNV to complex poles), therefore only YT supports them in this implementation.

As the solution to the problem of pole placement is not unique for MIMO systems, both methods start with a tentative transfer matrix which is altered in various way to increase its determinant. Both methods have been proven to converge to a stable solution, however depending on the way the initial transfer matrix is chosen they will converge to different solutions and therefore there is absolutely no guarantee that using 'KNV0' will yield results similar to Matlab’s or any other implementation of these algorithms.

Using the default method 'YT' should be fine in most cases; 'KNV0' is only provided because it is needed by 'YT' in some specific cases. Furthermore 'YT' gives on average more robust results than 'KNV0' when abs(det(X)) is used as a robustness indicator.

[2] is available as a technical report on the following URL: http://drum.lib.umd.edu/handle/1903/5598

[1](1, 2) J. Kautsky, N.K. Nichols and P. van Dooren, “Robust pole assignment in linear state feedback”, International Journal of Control, Vol. 41 pp. 1129-1155, 1985.
[2](1, 2, 3) A.L. Tits and Y. Yang, “Globally convergent algorithms for robust pole assignment by state feedback, IEEE Transactions on Automatic Control, Vol. 41, pp. 1432-1452, 1996.

A simple example demonstrating real pole placement using both KNV and YT algorithms. This is example number 1 from section 4 of the reference KNV publication ([1]):

>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> A = np.array([[ 1.380,  -0.2077,  6.715, -5.676  ],
...               [-0.5814, -4.290,   0,      0.6750 ],
...               [ 1.067,   4.273,  -6.654,  5.893  ],
...               [ 0.0480,  4.273,   1.343, -2.104  ]])
>>> B = np.array([[ 0,      5.679 ],
...               [ 1.136,  1.136 ],
...               [ 0,      0,    ],
...               [-3.146,  0     ]])
>>> P = np.array([-0.2, -0.5, -5.0566, -8.6659])

Now compute K with KNV method 0, with the default YT method and with the YT method while forcing 100 iterations of the algorithm and print some results after each call.

>>> fsf1 = signal.place_poles(A, B, P, method='KNV0')
>>> fsf1.gain_matrix
array([[ 0.20071427, -0.96665799,  0.24066128, -0.10279785],
       [ 0.50587268,  0.57779091,  0.51795763, -0.41991442]])
>>> fsf2 = signal.place_poles(A, B, P)  # uses YT method
>>> fsf2.computed_poles
array([-8.6659, -5.0566, -0.5   , -0.2   ])
>>> fsf3 = signal.place_poles(A, B, P, rtol=-1, maxiter=100)
>>> fsf3.X
array([[ 0.52072442+0.j, -0.08409372+0.j, -0.56847937+0.j,  0.74823657+0.j],
       [-0.04977751+0.j, -0.80872954+0.j,  0.13566234+0.j, -0.29322906+0.j],
       [-0.82266932+0.j, -0.19168026+0.j, -0.56348322+0.j, -0.43815060+0.j],
       [ 0.22267347+0.j,  0.54967577+0.j, -0.58387806+0.j, -0.40271926+0.j]])

The absolute value of the determinant of X is a good indicator to check the robustness of the results, both 'KNV0' and 'YT' aim at maximizing it. Below a comparison of the robustness of the results above:

>>> abs(np.linalg.det(fsf1.X)) < abs(np.linalg.det(fsf2.X))
True
>>> abs(np.linalg.det(fsf2.X)) < abs(np.linalg.det(fsf3.X))
True

Now a simple example for complex poles:

>>> A = np.array([[ 0,  7/3.,  0,   0   ],
...               [ 0,   0,    0,  7/9. ],
...               [ 0,   0,    0,   0   ],
...               [ 0,   0,    0,   0   ]])
>>> B = np.array([[ 0,  0 ],
...               [ 0,  0 ],
...               [ 1,  0 ],
...               [ 0,  1 ]])
>>> P = np.array([-3, -1, -2-1j, -2+1j]) / 3.
>>> fsf = signal.place_poles(A, B, P, method='YT')

We can plot the desired and computed poles in the complex plane:

>>> t = np.linspace(0, 2*np.pi, 401)
>>> plt.plot(np.cos(t), np.sin(t), 'k--')  # unit circle
>>> plt.plot(fsf.requested_poles.real, fsf.requested_poles.imag,
...          'wo', label='Desired')
>>> plt.plot(fsf.computed_poles.real, fsf.computed_poles.imag, 'bx',
...          label='Placed')
>>> plt.grid()
>>> plt.axis('image')
>>> plt.axis([-1.1, 1.1, -1.1, 1.1])
>>> plt.legend(bbox_to_anchor=(1.05, 1), loc=2, numpoints=1)
dlsim(system, u, t=None, x0=None)

Simulate output of a discrete-time linear system.

system : tuple of array_like or instance of dlti

A tuple describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1: (instance of dlti)
  • 3: (num, den, dt)
  • 4: (zeros, poles, gain, dt)
  • 5: (A, B, C, D, dt)
u : array_like
An input array describing the input at each time t (interpolation is assumed between given times). If there are multiple inputs, then each column of the rank-2 array represents an input.
t : array_like, optional
The time steps at which the input is defined. If t is given, it must be the same length as u, and the final value in t determines the number of steps returned in the output.
x0 : array_like, optional
The initial conditions on the state vector (zero by default).
tout : ndarray
Time values for the output, as a 1-D array.
yout : ndarray
System response, as a 1-D array.
xout : ndarray, optional
Time-evolution of the state-vector. Only generated if the input is a StateSpace system.

lsim, dstep, dimpulse, cont2discrete

A simple integrator transfer function with a discrete time step of 1.0 could be implemented as:

>>> from scipy import signal
>>> tf = ([1.0,], [1.0, -1.0], 1.0)
>>> t_in = [0.0, 1.0, 2.0, 3.0]
>>> u = np.asarray([0.0, 0.0, 1.0, 1.0])
>>> t_out, y = signal.dlsim(tf, u, t=t_in)
>>> y.T
array([[ 0.,  0.,  0.,  1.]])
dimpulse(system, x0=None, t=None, n=None)

Impulse response of discrete-time system.

system : tuple of array_like or instance of dlti

A tuple describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1: (instance of dlti)
  • 3: (num, den, dt)
  • 4: (zeros, poles, gain, dt)
  • 5: (A, B, C, D, dt)
x0 : array_like, optional
Initial state-vector. Defaults to zero.
t : array_like, optional
Time points. Computed if not given.
n : int, optional
The number of time points to compute (if t is not given).
tout : ndarray
Time values for the output, as a 1-D array.
yout : ndarray
Impulse response of system. Each element of the tuple represents the output of the system based on an impulse in each input.

impulse, dstep, dlsim, cont2discrete

dstep(system, x0=None, t=None, n=None)

Step response of discrete-time system.

system : tuple of array_like

A tuple describing the system. The following gives the number of elements in the tuple and the interpretation:

  • 1: (instance of dlti)
  • 3: (num, den, dt)
  • 4: (zeros, poles, gain, dt)
  • 5: (A, B, C, D, dt)
x0 : array_like, optional
Initial state-vector. Defaults to zero.
t : array_like, optional
Time points. Computed if not given.
n : int, optional
The number of time points to compute (if t is not given).
tout : ndarray
Output time points, as a 1-D array.
yout : ndarray
Step response of system. Each element of the tuple represents the output of the system based on a step response to each input.

step, dimpulse, dlsim, cont2discrete

dfreqresp(system, w=None, n=10000, whole=False)

Calculate the frequency response of a discrete-time system.

system : an instance of the dlti class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of dlti)
  • 2 (numerator, denominator, dt)
  • 3 (zeros, poles, gain, dt)
  • 4 (A, B, C, D, dt)
w : array_like, optional
Array of frequencies (in radians/sample). Magnitude and phase data is calculated for every value in this array. If not given a reasonable set will be calculated.
n : int, optional
Number of frequency points to compute if w is not given. The n frequencies are logarithmically spaced in an interval chosen to include the influence of the poles and zeros of the system.
whole : bool, optional
Normally, if ‘w’ is not given, frequencies are computed from 0 to the Nyquist frequency, pi radians/sample (upper-half of unit-circle). If whole is True, compute frequencies from 0 to 2*pi radians/sample.
w : 1D ndarray
Frequency array [radians/sample]
H : 1D ndarray
Array of complex magnitude values

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. z^2 + 3z + 5 would be represented as [1, 3, 5]).

New in version 0.18.0.

Generating the Nyquist plot of a transfer function

>>> from scipy import signal
>>> import matplotlib.pyplot as plt

Transfer function: H(z) = 1 / (z^2 + 2z + 3)

>>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05)
>>> w, H = signal.dfreqresp(sys)
>>> plt.figure()
>>> plt.plot(H.real, H.imag, "b")
>>> plt.plot(H.real, -H.imag, "r")
>>> plt.show()
dbode(system, w=None, n=100)

Calculate Bode magnitude and phase data of a discrete-time system.

system : an instance of the LTI class or a tuple describing the system.

The following gives the number of elements in the tuple and the interpretation:

  • 1 (instance of dlti)
  • 2 (num, den, dt)
  • 3 (zeros, poles, gain, dt)
  • 4 (A, B, C, D, dt)
w : array_like, optional
Array of frequencies (in radians/sample). Magnitude and phase data is calculated for every value in this array. If not given a reasonable set will be calculated.
n : int, optional
Number of frequency points to compute if w is not given. The n frequencies are logarithmically spaced in an interval chosen to include the influence of the poles and zeros of the system.
w : 1D ndarray
Frequency array [rad/time_unit]
mag : 1D ndarray
Magnitude array [dB]
phase : 1D ndarray
Phase array [deg]

If (num, den) is passed in for system, coefficients for both the numerator and denominator should be specified in descending exponent order (e.g. z^2 + 3z + 5 would be represented as [1, 3, 5]).

New in version 0.18.0.

>>> from scipy import signal
>>> import matplotlib.pyplot as plt

Transfer function: H(z) = 1 / (z^2 + 2z + 3)

>>> sys = signal.TransferFunction([1], [1, 2, 3], dt=0.05)

Equivalent: sys.bode()

>>> w, mag, phase = signal.dbode(sys)
>>> plt.figure()
>>> plt.semilogx(w, mag)    # Bode magnitude plot
>>> plt.figure()
>>> plt.semilogx(w, phase)  # Bode phase plot
>>> plt.show()