@@ -131,21 +131,26 @@ def frequency_response(self, omega, squeeze=None):
131
131
132
132
Parameters
133
133
----------
134
- omega : float or array_like
134
+ omega : float or 1D array_like
135
135
A list, tuple, array, or scalar value of frequencies in
136
136
radians/sec at which the system will be evaluated.
137
137
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'].
141
143
142
144
Returns
143
145
-------
144
- mag : (p, m, len(omega)) ndarray or (len(omega),) ndarray
146
+ mag : ndarray
145
147
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
149
154
The wrapped phase in radians of the system frequency response.
150
155
omega : ndarray
151
156
The (sorted) frequencies at which the response was evaluated.
@@ -482,18 +487,24 @@ def evalfr(sys, x, squeeze=None):
482
487
----------
483
488
sys: StateSpace or TransferFunction
484
489
Linear system
485
- x : complex scalar or array_like
490
+ x : complex scalar or 1D array_like
486
491
Complex frequency(s)
487
492
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
490
497
config.defaults['control.squeeze_frequency_response'].
491
498
492
499
Returns
493
500
-------
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.
497
508
498
509
See Also
499
510
--------
@@ -519,7 +530,7 @@ def evalfr(sys, x, squeeze=None):
519
530
520
531
def freqresp (sys , omega , squeeze = None ):
521
532
"""Frequency response of an LTI system at multiple angular frequencies.
522
-
533
+
523
534
In general the system may be multiple input, multiple output (MIMO), where
524
535
`m = sys.inputs` number of inputs and `p = sys.outputs` number of
525
536
outputs.
@@ -528,23 +539,27 @@ def freqresp(sys, omega, squeeze=None):
528
539
----------
529
540
sys: StateSpace or TransferFunction
530
541
Linear system
531
- omega : float or array_like
542
+ omega : float or 1D array_like
532
543
A list of frequencies in radians/sec at which the system should be
533
544
evaluated. The list can be either a python list or a numpy array
534
545
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
538
551
config.defaults['control.squeeze_frequency_response'].
539
552
540
553
Returns
541
554
-------
542
- mag : (p, m, len(omega)) ndarray or (len(omega),) ndarray
555
+ mag : ndarray
543
556
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
548
563
The wrapped phase in radians of the system frequency response.
549
564
omega : ndarray
550
565
The list of sorted frequencies at which the response was
@@ -601,14 +616,30 @@ def dcgain(sys):
601
616
602
617
# Process frequency responses in a uniform way
603
618
def _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
+
604
623
if not hasattr (omega , '__len__' ):
605
624
# received a scalar x, squeeze down the array along last dim
606
625
out = np .squeeze (out , axis = 2 )
607
626
627
+ #
608
628
# 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
612
641
return out [0 ][0 ]
613
- else :
642
+ elif squeeze is False or squeeze is None :
614
643
return out
644
+ else :
645
+ raise ValueError ("unknown squeeze value" )
0 commit comments