Allow signal names to be used for time/freq responses and subsystem indexing by murrayrm · Pull Request #1069 · python-control/python-control

This PR adds the ability to access response signals and subsystem inputs and outputs using signal names. As described in the documentation:

Time signal indexing:

The input, output, and state elements of the response can be access using signal names in place of integer offsets::

plt.plot(response. time, response.states['x[1]']

For multi-trace systems generated by :func:step_response and :func:impulse_response, the input name used to generate the trace can be used to access the appropriate input output pair::

plt.plot(response.time, response.outputs['y[0]', 'u[1]'])

Frequency response indexing:

Frequency response objects are also available as named properties of the response object: response.magnitude, response.phase, and response.response (for the complex response). For MIMO systems, these elements of the frequency response can be accessed using the names of the inputs and outputs::

response.magnitude['y[0]', 'u[1]']

where the signal names are based on the system that generated the frequency response.

Subsystem indexing:

Subsets of input/output pairs for LTI systems can be obtained by indexing the system using either numerical indices (including slices) or signal names::

subsys = sys[[0, 2], 0:2]
subsys = sys[['y[0]', 'y[2]'], ['u[0]', 'u[1]']]

Signal names for an indexed subsystem are preserved from the original system and the subsystem name is set according to the values of control.config.defaults['iosys.indexed_system_name_prefix'] and control.config.defaults['iosys.indexed_system_name_suffix']`. The default subsystem name is the original system name with '$indexed' appended.

Summary of changes:

  • Signals are now returned as a NamedSignal object, which is a subclass of np.ndarray that overrides the __getitem__ method to allow processing of signal names via the _parse_key method.
  • All signal/subsystem indexing now allows integers, strings (new), lists of integers or strings (new), or slices.
  • Refactored code for processing signal names to make everything consistent across time and frequency domain signals as well as state and input/output vectors. See iosys.NamedSignal._parse_key and changes in frdata.py and timeresp.py.
  • Refactored code for processing subsystem indices and made index processing consistent for StateSpace, TransferFunction, and FrequencyResponseData systems. See iosys._process_subsys_index and changes in frdata.py, statesp.py, and xferfcn.py.
  • Unit tests, docstrings, and user documentation updated to cover new functiionality.