@@ -131,21 +131,26 @@ def frequency_response(self, omega, squeeze=None):
131131
132132 Parameters
133133 ----------
134- omega : float or array_like
134+ omega : float or 1D array_like
135135 A list, tuple, array, or scalar value of frequencies in
136136 radians/sec at which the system will be evaluated.
137137 squeeze : bool, optional
138- If True and the system is single-input single-output (SISO),
139- return a 1D array rather than a 3D array. Default value (True)
140- set by config.defaults['control.squeeze_frequency_response'].
138+ If squeeze=True, remove single-dimensional entries from the shape
139+ of the output even if the system is not SISO. If squeeze=False,
140+ keep all indices (output, input and, if omega is array_like,
141+ frequency) even if the system is SISO. The default value can be
142+ set using config.defaults['control.squeeze_frequency_response'].
141143
142144 Returns
143145 -------
144- mag : (p, m, len(omega)) ndarray or (len(omega),) ndarray
146+ mag : ndarray
145147 The magnitude (absolute value, not dB or log10) of the system
146- frequency response. Array is ``(len(omega), )`` if
147- and only if system is SISO and ``squeeze=True``.
148- phase : (p, m, len(omega)) ndarray or (len(omega),) ndarray
148+ frequency response. If the system is SISO and squeeze is not
149+ True, the array is 1D, indexed by frequency. If the system is not
150+ SISO or squeeze is False, the array is 3D, indexed by the output,
151+ input, and frequency. If ``squeeze`` is True then
152+ single-dimensional axes are removed.
153+ phase : ndarray
149154 The wrapped phase in radians of the system frequency response.
150155 omega : ndarray
151156 The (sorted) frequencies at which the response was evaluated.
@@ -482,18 +487,24 @@ def evalfr(sys, x, squeeze=None):
482487 ----------
483488 sys: StateSpace or TransferFunction
484489 Linear system
485- x : complex scalar or array_like
490+ x : complex scalar or 1D array_like
486491 Complex frequency(s)
487492 squeeze : bool, optional (default=True)
488- If True and the system is single-input single-output (SISO), return a
489- 1D array rather than a 3D array. Default value (True) set by
493+ If squeeze=True, remove single-dimensional entries from the shape of
494+ the output even if the system is not SISO. If squeeze=False, keep all
495+ indices (output, input and, if omega is array_like, frequency) even if
496+ the system is SISO. The default value can be set using
490497 config.defaults['control.squeeze_frequency_response'].
491498
492499 Returns
493500 -------
494- fresp : (p, m, len(x)) complex ndarray or (len(x),) complex ndarray
495- The frequency response of the system. Array is ``(len(x), )`` if
496- and only if system is SISO and ``squeeze=True``.
501+ fresp : complex ndarray
502+ The frequency response of the system. If the system is SISO and
503+ squeeze is not True, the shape of the array matches the shape of
504+ omega. If the system is not SISO or squeeze is False, the first two
505+ dimensions of the array are indices for the output and input and the
506+ remaining dimensions match omega. If ``squeeze`` is True then
507+ single-dimensional axes are removed.
497508
498509 See Also
499510 --------
@@ -519,7 +530,7 @@ def evalfr(sys, x, squeeze=None):
519530
520531def freqresp (sys , omega , squeeze = None ):
521532 """Frequency response of an LTI system at multiple angular frequencies.
522-
533+
523534 In general the system may be multiple input, multiple output (MIMO), where
524535 `m = sys.inputs` number of inputs and `p = sys.outputs` number of
525536 outputs.
@@ -528,23 +539,27 @@ def freqresp(sys, omega, squeeze=None):
528539 ----------
529540 sys: StateSpace or TransferFunction
530541 Linear system
531- omega : float or array_like
542+ omega : float or 1D array_like
532543 A list of frequencies in radians/sec at which the system should be
533544 evaluated. The list can be either a python list or a numpy array
534545 and will be sorted before evaluation.
535- squeeze : bool, optional (default=True)
536- If True and the system is single-input single-output (SISO), return a
537- 1D array rather than a 3D array. Default value (True) set by
546+ squeeze : bool, optional
547+ If squeeze=True, remove single-dimensional entries from the shape of
548+ the output even if the system is not SISO. If squeeze=False, keep all
549+ indices (output, input and, if omega is array_like, frequency) even if
550+ the system is SISO. The default value can be set using
538551 config.defaults['control.squeeze_frequency_response'].
539552
540553 Returns
541554 -------
542- mag : (p, m, len(omega)) ndarray or (len(omega),) ndarray
555+ mag : ndarray
543556 The magnitude (absolute value, not dB or log10) of the system
544- frequency response. Array is ``(len(omega), )`` if and only if system
545- is SISO and ``squeeze=True``.
546-
547- phase : (p, m, len(omega)) ndarray or (len(omega),) ndarray
557+ frequency response. If the system is SISO and squeeze is not True,
558+ the array is 1D, indexed by frequency. If the system is not SISO or
559+ squeeze is False, the array is 3D, indexed by the output, input, and
560+ frequency. If ``squeeze`` is True then single-dimensional axes are
561+ removed.
562+ phase : ndarray
548563 The wrapped phase in radians of the system frequency response.
549564 omega : ndarray
550565 The list of sorted frequencies at which the response was
@@ -601,14 +616,30 @@ def dcgain(sys):
601616
602617# Process frequency responses in a uniform way
603618def _process_frequency_response (sys , omega , out , squeeze = None ):
619+ # Set value of squeeze argument if not set
620+ if squeeze is None :
621+ squeeze = config .defaults ['control.squeeze_frequency_response' ]
622+
604623 if not hasattr (omega , '__len__' ):
605624 # received a scalar x, squeeze down the array along last dim
606625 out = np .squeeze (out , axis = 2 )
607626
627+ #
608628 # Get rid of unneeded dimensions
609- if squeeze is None :
610- squeeze = config .defaults ['control.squeeze_frequency_response' ]
611- if squeeze and sys .issiso ():
629+ #
630+ # There are three possible values for the squeeze keyword at this point:
631+ #
632+ # squeeze=None: squeeze input/output axes iff SISO
633+ # squeeze=True: squeeze all single dimensional axes (ala numpy)
634+ # squeeze-False: don't squeeze any axes
635+ #
636+ if squeeze is True :
637+ # Squeeze everything that we can if that's what the user wants
638+ return np .squeeze (out )
639+ elif squeeze is None and sys .issiso ():
640+ # SISO system output squeezed unless explicitly specified otherwise
612641 return out [0 ][0 ]
613- else :
642+ elif squeeze is False or squeeze is None :
614643 return out
644+ else :
645+ raise ValueError ("unknown squeeze value" )
0 commit comments