|
48 | 48 | """ |
49 | 49 |
|
50 | 50 | import math |
| 51 | +from collections.abc import Iterable |
51 | 52 | from copy import deepcopy |
52 | 53 | from warnings import warn |
53 | | -from collections.abc import Iterable |
54 | 54 |
|
55 | 55 | import numpy as np |
56 | 56 | import scipy as sp |
57 | 57 | import scipy.linalg |
58 | | -from numpy import (any, asarray, concatenate, cos, delete, empty, exp, eye, |
59 | | - isinf, ones, pad, sin, squeeze, zeros) |
| 58 | +from numpy import any, asarray, concatenate, cos, delete, empty, exp, eye, \ |
| 59 | + isinf, ones, pad, sin, squeeze, zeros |
60 | 60 | from numpy.linalg import LinAlgError, eigvals, matrix_rank, solve |
61 | 61 | from numpy.random import rand, randn |
62 | 62 | from scipy.signal import StateSpace as signalStateSpace |
|
65 | 65 | from . import config |
66 | 66 | from .exception import ControlMIMONotImplemented, ControlSlycot, slycot_check |
67 | 67 | from .frdata import FrequencyResponseData |
68 | | -from .iosys import (InputOutputSystem, _process_dt_keyword, |
69 | | - _process_iosys_keywords, _process_signal_list, |
70 | | - common_timebase, isdtime, issiso) |
| 68 | +from .iosys import InputOutputSystem, NamedSignal, _process_dt_keyword, \ |
| 69 | + _process_iosys_keywords, _process_signal_list, _process_subsys_index, \ |
| 70 | + common_timebase, isdtime, issiso |
71 | 71 | from .lti import LTI, _process_frequency_response |
72 | 72 | from .nlsys import InterconnectedSystem, NonlinearIOSystem |
73 | 73 |
|
@@ -1214,25 +1214,25 @@ def append(self, other): |
1214 | 1214 | D[self.noutputs:, self.ninputs:] = other.D |
1215 | 1215 | return StateSpace(A, B, C, D, self.dt) |
1216 | 1216 |
|
1217 | | - def __getitem__(self, indices): |
| 1217 | + def __getitem__(self, key): |
1218 | 1218 | """Array style access""" |
1219 | | - if not isinstance(indices, Iterable) or len(indices) != 2: |
1220 | | - raise IOError('must provide indices of length 2 for state space') |
1221 | | - outdx, inpdx = indices |
1222 | | - |
1223 | | - # Convert int to slice to ensure that numpy doesn't drop the dimension |
1224 | | - if isinstance(outdx, int): outdx = slice(outdx, outdx+1, 1) |
1225 | | - if isinstance(inpdx, int): inpdx = slice(inpdx, inpdx+1, 1) |
| 1219 | + if not isinstance(key, Iterable) or len(key) != 2: |
| 1220 | + raise IOError("must provide indices of length 2 for state space") |
1226 | 1221 |
|
1227 | | - if not isinstance(outdx, slice) or not isinstance(inpdx, slice): |
1228 | | - raise TypeError(f"system indices must be integers or slices") |
| 1222 | + # Convert signal names to integer offsets |
| 1223 | + iomap = NamedSignal(self.D, self.output_labels, self.input_labels) |
| 1224 | + indices = iomap._parse_key(key) |
| 1225 | + outdx, output_labels = _process_subsys_index( |
| 1226 | + indices[0], self.output_labels) |
| 1227 | + inpdx, input_labels = _process_subsys_index( |
| 1228 | + indices[1], self.input_labels) |
1229 | 1229 |
|
1230 | 1230 | sysname = config.defaults['iosys.indexed_system_name_prefix'] + \ |
1231 | 1231 | self.name + config.defaults['iosys.indexed_system_name_suffix'] |
1232 | 1232 | return StateSpace( |
1233 | | - self.A, self.B[:, inpdx], self.C[outdx, :], self.D[outdx, inpdx], |
1234 | | - self.dt, name=sysname, |
1235 | | - inputs=self.input_labels[inpdx], outputs=self.output_labels[outdx]) |
| 1233 | + self.A, self.B[:, inpdx], self.C[outdx, :], |
| 1234 | + self.D[outdx, :][:, inpdx], self.dt, |
| 1235 | + name=sysname, inputs=input_labels, outputs=output_labels) |
1236 | 1236 |
|
1237 | 1237 | def sample(self, Ts, method='zoh', alpha=None, prewarp_frequency=None, |
1238 | 1238 | name=None, copy_names=True, **kwargs): |
|
0 commit comments