proposal to standardize squeezing output from systems
See original GitHub issueProposal: When computing frequency and time response output of systems, standardize on indexing first element so output is a 1D array if system is SISO and squeeze=True. This is instead of applying numpy.squeeze to output.
Currently, there are two ways that python-control squeezes output:
-
apply ‘squeeze’ to the output at the end. This is what functions in
timeresp.pydo, e.g.forced_response(edit: andiosystime responses). An m x n MIMO system (m-output, n-input, m,n>1) produces a [m x n x k] array, where k is the number of data points in time. But a 1 x n system’s output gets squeezed to [n x k] and a m x 1 is squeezed to [m x k]. -
use indexing to extract the first element if SISO, otherwise leave a full array. This is what the frequency response functions
evalfr,freqrespdo. If SISO, give [k] length array; MIMO systems always produce [m x n x k] arrays.
I propose to standardize on the latter: a MIMO system should always output [m x n x k] arrays. Rationale: this facilitates interconnection and keeps indexing the system and its outputs consistent. Along with the proposal: retain the squeeze=True keyword argument because it’s already in use, but do the ‘squeeze’ by indexing the first element, and only do it if SISO.
Documentation would read something like:
“If squeeze is True (default) and sys is single input single output (SISO), returns a 1D array equal to the length k of the input, otherwise returns an (n_outputs, n_inputs, k) array for multiple input multiple output (MIMO) systems.”
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:30 (28 by maintainers)

Top Related StackOverflow Question
Nice synopsis. I agree on the four main points. and in particular agree that a frequency response of a siso system to a scalar should probably be a scalar.
I think 5 is interesting but too complicated.
1 is probably good combo of simplicity & least change.
My favorite is still 6 because it feels most object oriented, is opinionated, and would require the shortest docstring.
But advocates of a feature have a responsibility to implement it, and my doc says it will be a few more weeks till I can type with both hands again (broken bone). And as @murrayrm suggested, the devil may be in the details. Changes I foresee include an update to the ‘conventions’ section to describe the ‘as_mimo’ feature and adding links to conventions on the time and freq response functions.
My suggestion: do 1 and if a few weeks have gone by and 0.9 still isn’t released then maybe a PR will appear & you can take a look. But this isn’t important enough to hold up a a release waiting on my PR.
I think the following are all agreeable:
For SISO systems, the default should be that you don’t need to subscript inputs, outputs, etc. I think all variants have this property.
It should be possible to treat a SISO system like a MIMO systems (the current
squeeze=Falsebehavior currently satisfies that).H(s) should return a scalar for SISO and 2D array for non-SISO (including SIMO and MISO).
Time and frequency responses should be handled in a consistent fashion, so that that the behavior of
squeezein “understandable” across those classes of functions.Assuming those are agreeable, a couple of possibilities:
Full numpy: when
squeezeis true, all single dimensional entries in the shape are removed (with anaxiskeyword if you want to only squeeze certain axes?).Modified numpy: when
squeezeis true, all single dimensional input/output entries in the shape of the output variables are removed, but single dimensional entries in time/frequency are maintained.Current behavior: when
squeezeis true, if all input/output entries are single dimensional, then single dimensional input/output entries are removed in the shape. This one pushes a bit on “consistency” because for a MISO system, the frequency response would return a 3D system ([input][output][freq]) but a time response would return a 1D system (indexed by time alone).SISO-only: if
squeezeis true and the system is SISO, then single dimensional input/output entries are removed in the shape. This one pushes a bit on “understandable” because for a MISO system, the “squeezed” forced response would return a 2D system ([output][time]) even if though there is only one output.More customizable: we can of course use the
squeezekeyword more flexibly, so that we could havesqueeze='all',squeeze='inputs', etc to pick up the different cases.Additional variant: allow a SISO system to be “locked” as a MIMO system (this would probably require a lot of care since I suspect we have various places where we check the value of
inputsandoutputsinstead of callingissiso.Preferences? Other options?