8000 Allow division by scalar for StateSpace & InputOutputSystem · python-control/python-control@f81b6d2 · GitHub
[go: up one dir, main page]

Skip to content

Commit f81b6d2

Browse files
committed
Allow division by scalar for StateSpace & InputOutputSystem
Attempt division by any non-LTI and non-NameIOSystem by translating G / k to G * (1/k). Division of StateSpace by TransferFunction, etc., unchanged.
1 parent 9d65bf8 commit f81b6d2

File tree

4 files changed

+33
-14
lines changed

4 files changed

+33
-14
lines changed

control/iosys.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,17 @@ def __neg__(sys):
346346
# Return the newly created system
347347
return newsys
348348

349+
def __truediv__(sys2, sys1):
350+
"""Multiply two input/output systems (series interconnection)"""
351+
# Note: order of arguments is flipped so that self = sys2,
352+
# corresponding to the ordering convention of sys2 * sys1
353+
354+
if not isinstance(sys1, (LTI, NamedIOSystem)):
355+
return sys2 * (1/sys1)
356+
else:
357+
return NotImplemented
358+
359+
349360
# Update parameters used for _rhs, _out (used by subclasses)
350361
def _update_params(self, params, warning=False):
351362
if warning:
Collapse file

control/statesp.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
from .frdata import FrequencyResponseData
6565
from .lti import LTI, _process_frequency_response
6666
from .namedio import common_timebase, isdtime, _process_namedio_keywords, \
67-
_process_dt_keyword
67+
_process_dt_keyword, NamedIOSystem
6868
from . import config
6969
from copy import deepcopy
7070

@@ -794,17 +794,14 @@ def __rmul__(self, other):
794794
pass
795795
raise TypeError("can't interconnect systems")
796796

797-
# TODO: __div__ and __rdiv__ are not written yet.
798-
def __div__(self, other):
799-
"""Divide two LTI systems."""
800-
801-
raise NotImplementedError("StateSpace.__div__ is not implemented yet.")
802-
803-
def __rdiv__(self, other):
804-
"""Right divide two LTI systems."""
797+
# TODO: general __truediv__, and __rtruediv__; requires descriptor system support
798+
def __truediv__(self, other):
799+
"""Divide a StateSpace object; only division by scalars is supported"""
800+
if not isinstance(other, (LTI, NamedIOSystem)):
801+
return self * (1/other)
802+
else:
803+
return NotImplemented
805804

806-
raise NotImplementedError(
807-
"StateSpace.__rdiv__ is not implemented yet.")
808805

809806
def __call__(self, x, squeeze=None, warn_infinite=True):
810807
"""Evaluate system's transfer function at complex frequency.

control/tests/statesp_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,17 @@ def test_multiply_ss(self, sys222, sys322):
333333
np.testing.assert_array_almost_equal(sys.C, C)
334334
np.testing.assert_array_almost_equal(sys.D, D)
335335

336+
@pytest.mark.parametrize("k", [2, -3.141, np.float32(2.718), np.array([[4.321], [5.678]])])
337+
def test_truediv_ss_scalar(self, sys322, k):
338+
"""Divide SS by scalar."""
339+
sys = sys322 / k
340+
syscheck = sys322 * (1/k)
341+
342+
np.testing.assert_array_almost_equal(sys.A, syscheck.A)
343+
np.testing.assert_array_almost_equal(sys.B, syscheck.B)
344+
np.testing.assert_array_almost_equal(sys.C, syscheck.C)
345+
np.testing.assert_array_almost_equal(sys.D, syscheck.D)
346+
336347
@pytest.mark.parametrize("omega, resp",
337348
[(1.,
338349
np.array([[ 4.37636761e-05-0.01522976j,

control/tests/type_conversion_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ def sys_dict():
8888
('mul', 'flt', ['ss', 'tf', 'frd', 'lio', 'ios', 'arr', 'flt']),
8989

9090
# op left ss tf frd lio ios arr flt
91-
('truediv', 'ss', ['xs', 'tf', 'frd', 'xio', 'xos', 'xs', 'xs' ]),
91+
('truediv', 'ss', ['xs', 'tf', 'frd', 'xio', 'xos', 'ss', 'ss' ]),
9292
('truediv', 'tf', ['tf', 'tf', 'xrd', 'tf', 'xos', 'tf', 'tf' ]),
9393
('truediv', 'frd', ['frd', 'frd', 'frd', 'frd', 'E', 'frd', 'frd']),
94-
('truediv', 'lio', ['xio', 'tf', 'frd', 'xio', 'xio', 'xio', 'xio']),
95-
('truediv', 'ios', ['xos', 'xos', 'E', 'xos', 'xos' 'xos', 'xos']),
94+
('truediv', 'lio', ['xio', 'tf', 'frd', 'xio', 'xio', 'lio', 'lio']),
95+
('truediv', 'ios', ['xos', 'xos', 'E', 'xos', 'xos', 'ios', 'ios']),
9696
('truediv', 'arr', ['xs', 'tf', 'frd', 'xio', 'xos', 'arr', 'arr']),
9797
('truediv', 'flt', ['xs', 'tf', 'frd', 'xio', 'xos', 'arr', 'flt'])]
9898

0 commit comments

Comments
 (0)
0