Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions control/frdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,17 +400,30 @@ def _evalfr(self, omega):

# Method for generating the frequency response of the system
def freqresp(self, omega):
"""Evaluate a transfer function at a list of angular frequencies.

mag, phase, omega = self.freqresp(omega)

reports the value of the magnitude, phase, and angular frequency of
the transfer function matrix evaluated at s = i * omega, where omega
is a list of angular frequencies, and is a sorted version of the input
omega.

"""Evaluate the frequency response at a list of angular frequencies.

Reports the value of the magnitude, phase, and angular frequency of
the requency response evaluated at omega, where omega is a list of
angular frequencies, and is a sorted version of the input omega.

Parameters
----------
omega : array_like
A list of frequencies in radians/sec at which the system should be
evaluated. The list can be either a python list or a numpy array
and will be sorted before evaluation.

Returns
-------
mag : (self.outputs, self.inputs, len(omega)) ndarray
The magnitude (absolute value, not dB or log10) of the system
frequency response.
phase : (self.outputs, self.inputs, len(omega)) ndarray
The wrapped phase in radians of the system frequency response.
omega : ndarray or list or tuple
The list of sorted frequencies at which the response was
evaluated.
"""

# Preallocate outputs.
numfreq = len(omega)
mag = empty((self.outputs, self.inputs, numfreq))
Expand Down
26 changes: 17 additions & 9 deletions control/lti.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def isdtime(self, strict=False):
Parameters
----------
strict: bool, optional
If strict is True, make sure that timebase is not None. Default
is False.
If strict is True, make sure that timebase is not None. Default
is False.
"""

# If no timebase is given, answer depends on strict flag
Expand All @@ -75,8 +75,8 @@ def isctime(self, strict=False):
sys : LTI system
System to be checked
strict: bool, optional
If strict is True, make sure that timebase is not None. Default
is False.
If strict is True, make sure that timebase is not None. Default
is False.
"""
# If no timebase is given, answer depends on strict flag
if self.dt is None:
Expand Down Expand Up @@ -421,6 +421,7 @@ def evalfr(sys, x):
return sys.horner(x)[0][0]
return sys.horner(x)


def freqresp(sys, omega):
"""
Frequency response of an LTI system at multiple angular frequencies.
Expand All @@ -430,13 +431,20 @@ def freqresp(sys, omega):
sys: StateSpace or TransferFunction
Linear system
omega: array_like
List of frequencies
A list of frequencies in radians/sec at which the system should be
evaluated. The list can be either a python list or a numpy array
and will be sorted before evaluation.

Returns
-------
mag: ndarray
phase: ndarray
omega: list, tuple, or ndarray
mag : (self.outputs, self.inputs, len(omega)) ndarray
The magnitude (absolute value, not dB or log10) of the system
frequency response.
phase : (self.outputs, self.inputs, len(omega)) ndarray
The wrapped phase in radians of the system frequency response.
omega : ndarray or list or tuple
The list of sorted frequencies at which the response was
evaluated.

See Also
--------
Expand Down Expand Up @@ -472,9 +480,9 @@ def freqresp(sys, omega):
#>>> # frequency response from the 1st input to the 2nd output, for
#>>> # s = 0.1i, i, 10i.
"""

return sys.freqresp(omega)


def dcgain(sys):
"""Return the zero-frequency (or DC) gain of the given system

Expand Down
17 changes: 5 additions & 12 deletions control/statesp.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,8 @@ def horner(self, s):
self.B)) + self.D
return array(resp)

# Method for generating the frequency response of the system
def freqresp(self, omega):
"""Evaluate the system's transfer func. at a list of freqs, omega.

mag, phase, omega = self.freqresp(omega)
"""Evaluate the system's transfer function at a list of frequencies

Reports the frequency response of the system,

Expand All @@ -479,26 +476,22 @@ def freqresp(self, omega):

Parameters
----------
omega : array
omega : array_like
A list of frequencies in radians/sec at which the system should be
evaluated. The list can be either a python list or a numpy array
and will be sorted before evaluation.

Returns
-------
mag : float
mag : (self.outputs, self.inputs, len(omega)) ndarray
The magnitude (absolute value, not dB or log10) of the system
frequency response.

phase : float
phase : (self.outputs, self.inputs, len(omega)) ndarray
The wrapped phase in radians of the system frequency response.

omega : array
omega : ndarray
The list of sorted frequencies at which the response was
evaluated.

"""

# In case omega is passed in as a list, rather than a proper array.
omega = np.asarray(omega)

Expand Down
33 changes: 25 additions & 8 deletions control/xferfcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,19 +639,36 @@ def horner(self, s):

return out

# Method for generating the frequency response of the system
def freqresp(self, omega):
"""Evaluate a transfer function at a list of angular frequencies.
"""Evaluate the transfer function at a list of angular frequencies.

mag, phase, omega = self.freqresp(omega)
Reports the frequency response of the system,

reports the value of the magnitude, phase, and angular frequency of
the transfer function matrix evaluated at s = i * omega, where omega
is a list of angular frequencies, and is a sorted version of the input
omega.
G(j*omega) = mag*exp(j*phase)

"""
for continuous time. For discrete time systems, the response is
evaluated around the unit circle such that

G(exp(j*omega*dt)) = mag*exp(j*phase).

Parameters
----------
omega : array_like
A list of frequencies in radians/sec at which the system should be
evaluated. The list can be either a python list or a numpy array
and will be sorted before evaluation.

Returns
-------
mag : (self.outputs, self.inputs, len(omega)) ndarray
The magnitude (absolute value, not dB or log10) of the system
frequency response.
phase : (self.outputs, self.inputs, len(omega)) ndarray
The wrapped phase in radians of the system frequency response.
omega : ndarray or list or tuple
The list of sorted frequencies at which the response was
evaluated.
"""
# Preallocate outputs.
numfreq = len(omega)
mag = empty((self.outputs, self.inputs, numfreq))
Expand Down
2 changes: 1 addition & 1 deletion examples/robust_mimo.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def triv_sigma(g, w):
w - frequencies, length m
s - (m,n) array of singular values of g(1j*w)"""
m, p, _ = g.freqresp(w)
sjw = (m*np.exp(1j*p*np.pi/180)).transpose(2, 0, 1)
sjw = (m*np.exp(1j*p)).transpose(2, 0, 1)
sv = np.linalg.svd(sjw, compute_uv=False)
return sv

Expand Down