Skip to content

Commit 2777de3

Browse files
authored
Fix phase for triv_sigma in examples/robust_mimo.py (#428)
* fix issue #406 * more precise docstrings for *.freqresp()
1 parent c7c7b47 commit 2777de3

File tree

5 files changed

+71
-40
lines changed

5 files changed

+71
-40
lines changed

control/frdata.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,17 +400,30 @@ def _evalfr(self, omega):
400400

401401
# Method for generating the frequency response of the system
402402
def freqresp(self, omega):
403-
"""Evaluate a transfer function at a list of angular frequencies.
404-
405-
mag, phase, omega = self.freqresp(omega)
406-
407-
reports the value of the magnitude, phase, and angular frequency of
408-
the transfer function matrix evaluated at s = i * omega, where omega
409-
is a list of angular frequencies, and is a sorted version of the input
410-
omega.
411-
403+
"""Evaluate the frequency response at a list of angular frequencies.
404+
405+
Reports the value of the magnitude, phase, and angular frequency of
406+
the requency response evaluated at omega, where omega is a list of
407+
angular frequencies, and is a sorted version of the input omega.
408+
409+
Parameters
410+
----------
411+
omega : array_like
412+
A list of frequencies in radians/sec at which the system should be
413+
evaluated. The list can be either a python list or a numpy array
414+
and will be sorted before evaluation.
415+
416+
Returns
417+
-------
418+
mag : (self.outputs, self.inputs, len(omega)) ndarray
419+
The magnitude (absolute value, not dB or log10) of the system
420+
frequency response.
421+
phase : (self.outputs, self.inputs, len(omega)) ndarray
422+
The wrapped phase in radians of the system frequency response.
423+
omega : ndarray or list or tuple
424+
The list of sorted frequencies at which the response was
425+
evaluated.
412426
"""
413-
414427
# Preallocate outputs.
415428
numfreq = len(omega)
416429
mag = empty((self.outputs, self.inputs, numfreq))

control/lti.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ def isdtime(self, strict=False):
5555
Parameters
5656
----------
5757
strict: bool, optional
58-
If strict is True, make sure that timebase is not None. Default
59-
is False.
58+
If strict is True, make sure that timebase is not None. Default
59+
is False.
6060
"""
6161

6262
# If no timebase is given, answer depends on strict flag
@@ -75,8 +75,8 @@ def isctime(self, strict=False):
7575
sys : LTI system
7676
System to be checked
7777
strict: bool, optional
78-
If strict is True, make sure that timebase is not None. Default
79-
is False.
78+
If strict is True, make sure that timebase is not None. Default
79+
is False.
8080
"""
8181
# If no timebase is given, answer depends on strict flag
8282
if self.dt is None:
@@ -421,6 +421,7 @@ def evalfr(sys, x):
421421
return sys.horner(x)[0][0]
422422
return sys.horner(x)
423423

424+
424425
def freqresp(sys, omega):
425426
"""
426427
Frequency response of an LTI system at multiple angular frequencies.
@@ -430,13 +431,20 @@ def freqresp(sys, omega):
430431
sys: StateSpace or TransferFunction
431432
Linear system
432433
omega: array_like
433-
List of frequencies
434+
A list of frequencies in radians/sec at which the system should be
435+
evaluated. The list can be either a python list or a numpy array
436+
and will be sorted before evaluation.
434437
435438
Returns
436439
-------
437-
mag: ndarray
438-
phase: ndarray
439-
omega: list, tuple, or ndarray
440+
mag : (self.outputs, self.inputs, len(omega)) ndarray
441+
The magnitude (absolute value, not dB or log10) of the system
442+
frequency response.
443+
phase : (self.outputs, self.inputs, len(omega)) ndarray
444+
The wrapped phase in radians of the system frequency response.
445+
omega : ndarray or list or tuple
446+
The list of sorted frequencies at which the response was
447+
evaluated.
440448
441449
See Also
442450
--------
@@ -472,9 +480,9 @@ def freqresp(sys, omega):
472480
#>>> # frequency response from the 1st input to the 2nd output, for
473481
#>>> # s = 0.1i, i, 10i.
474482
"""
475-
476483
return sys.freqresp(omega)
477484

485+
478486
def dcgain(sys):
479487
"""Return the zero-frequency (or DC) gain of the given system
480488

control/statesp.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,8 @@ def horner(self, s):
462462
self.B)) + self.D
463463
return array(resp)
464464

465-
# Method for generating the frequency response of the system
466465
def freqresp(self, omega):
467-
"""Evaluate the system's transfer func. at a list of freqs, omega.
468-
469-
mag, phase, omega = self.freqresp(omega)
466+
"""Evaluate the system's transfer function at a list of frequencies
470467
471468
Reports the frequency response of the system,
472469
@@ -479,26 +476,22 @@ def freqresp(self, omega):
479476
480477
Parameters
481478
----------
482-
omega : array
479+
omega : array_like
483480
A list of frequencies in radians/sec at which the system should be
484481
evaluated. The list can be either a python list or a numpy array
485482
and will be sorted before evaluation.
486483
487484
Returns
488485
-------
489-
mag : float
486+
mag : (self.outputs, self.inputs, len(omega)) ndarray
490487
The magnitude (absolute value, not dB or log10) of the system
491488
frequency response.
492-
493-
phase : float
489+
phase : (self.outputs, self.inputs, len(omega)) ndarray
494490
The wrapped phase in radians of the system frequency response.
495-
496-
omega : array
491+
omega : ndarray
497492
The list of sorted frequencies at which the response was
498493
evaluated.
499-
500494
"""
501-
502495
# In case omega is passed in as a list, rather than a proper array.
503496
omega = np.asarray(omega)
504497

control/xferfcn.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -639,19 +639,36 @@ def horner(self, s):
639639

640640
return out
641641

642-
# Method for generating the frequency response of the system
643642
def freqresp(self, omega):
644-
"""Evaluate a transfer function at a list of angular frequencies.
643+
"""Evaluate the transfer function at a list of angular frequencies.
645644
646-
mag, phase, omega = self.freqresp(omega)
645+
Reports the frequency response of the system,
647646
648-
reports the value of the magnitude, phase, and angular frequency of
649-
the transfer function matrix evaluated at s = i * omega, where omega
650-
is a list of angular frequencies, and is a sorted version of the input
651-
omega.
647+
G(j*omega) = mag*exp(j*phase)
652648
653-
"""
649+
for continuous time. For discrete time systems, the response is
650+
evaluated around the unit circle such that
651+
652+
G(exp(j*omega*dt)) = mag*exp(j*phase).
653+
654+
Parameters
655+
----------
656+
omega : array_like
657+
A list of frequencies in radians/sec at which the system should be
658+
evaluated. The list can be either a python list or a numpy array
659+
and will be sorted before evaluation.
654660
661+
Returns
662+
-------
663+
mag : (self.outputs, self.inputs, len(omega)) ndarray
664+
The magnitude (absolute value, not dB or log10) of the system
665+
frequency response.
666+
phase : (self.outputs, self.inputs, len(omega)) ndarray
667+
The wrapped phase in radians of the system frequency response.
668+
omega : ndarray or list or tuple
669+
The list of sorted frequencies at which the response was
670+
evaluated.
671+
"""
655672
# Preallocate outputs.
656673
numfreq = len(omega)
657674
mag = empty((self.outputs, self.inputs, numfreq))

examples/robust_mimo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def triv_sigma(g, w):
4444
w - frequencies, length m
4545
s - (m,n) array of singular values of g(1j*w)"""
4646
m, p, _ = g.freqresp(w)
47-
sjw = (m*np.exp(1j*p*np.pi/180)).transpose(2, 0, 1)
47+
sjw = (m*np.exp(1j*p)).transpose(2, 0, 1)
4848
sv = np.linalg.svd(sjw, compute_uv=False)
4949
return sv
5050

0 commit comments

Comments
 (0)