Skip to content

Commit 4b712a4

Browse files
authored
Merge pull request #811 from roryyorke/rory/ss-div-scalar
Enable scalar division of state-space objects
2 parents 900d56e + cc3fb2f commit 4b712a4

File tree

6 files changed

+38
-29
lines changed

6 files changed

+38
-29
lines changed

control/frdata.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,6 @@ def __truediv__(self, other):
408408
smooth=(self.ifunc is not None) and
409409
(other.ifunc is not None))
410410

411-
# TODO: Remove when transition to python3 complete
412-
def __div__(self, other):
413-
return self.__truediv__(other)
414-
415411
# TODO: Division of MIMO transfer function objects is not written yet.
416412
def __rtruediv__(self, other):
417413
"""Right divide two LTI objects."""
@@ -429,10 +425,6 @@ def __rtruediv__(self, other):
429425

430426
return other / self
431427

432-
# TODO: Remove when transition to python3 complete
433-
def __rdiv__(self, other):
434-
return self.__rtruediv__(other)
435-
436428
def __pow__(self, other):
437429
if not type(other) == int:
438430
raise ValueError("Exponent must be an integer")

control/iosys.py

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

349+
def __truediv__(sys2, sys1):
350+
"""Division of input/output systems
351+
352+
Only division by scalars and arrays of scalars is supported"""
353+
# Note: order of arguments is flipped so that self = sys2,
354+
# corresponding to the ordering convention of sys2 * sys1
355+
356+
if not isinstance(sys1, (LTI, NamedIOSystem)):
357+
return sys2 * (1/sys1)
358+
else:
359+
return NotImplemented
360+
361+
349362
# Update parameters used for _rhs, _out (used by subclasses)
350363
def _update_params(self, params, warning=False):
351364
if warning:

control/statesp.py

Lines changed: 11 additions & 10 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,18 @@ 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."""
797+
# TODO: general __truediv__, and __rtruediv__; requires descriptor system support
798+
def __truediv__(self, other):
799+
"""Division of StateSpace systems
800800
801-
raise NotImplementedError("StateSpace.__div__ is not implemented yet.")
802-
803-
def __rdiv__(self, other):
804-
"""Right divide two LTI systems."""
801+
Only division by TFs, FRDs, scalars, and arrays of scalars is
802+
supported.
803+
"""
804+
if not isinstance(other, (LTI, NamedIOSystem)):
805+
return self * (1/other)
806+
else:
807+
return NotImplemented
805808

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

809810
def __call__(self, x, squeeze=None, warn_infinite=True):
810811
"""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

control/xferfcn.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -702,10 +702,6 @@ def __truediv__(self, other):
702702

703703
return TransferFunction(num, den, dt)
704704

705-
# TODO: Remove when transition to python3 complete
706-
def __div__(self, other):
707-
return TransferFunction.__truediv__(self, other)
708-
709705
# TODO: Division of MIMO transfer function objects is not written yet.
710706
def __rtruediv__(self, other):
711707
"""Right divide two LTI objects."""
@@ -724,10 +720,6 @@ def __rtruediv__(self, other):
724720

725721
return other / self
726722

727-
# TODO: Remove when transition to python3 complete
728-
def __rdiv__(self, other):
729-
return TransferFunction.__rtruediv__(self, other)
730-
731723
def __pow__(self, other):
732724
if not type(other) == int:
733725
raise ValueError("Exponent must be an integer")

0 commit comments

Comments
 (0)