Skip to content

Commit dc7d71b

Browse files
authored
Merge pull request #1142 from murrayrm/xferfcn_typecheck-23Mar2025
Add type error checks, unit tests, documentation for real-valued systems
2 parents 394e1c2 + 6b4501e commit dc7d71b

File tree

5 files changed

+16
-6
lines changed

5 files changed

+16
-6
lines changed

control/tests/statesp_test.py

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def test_constructor(self, sys322ABCD, dt, argfun):
136136
((np.ones((3, 3)), np.ones((3, 2)),
137137
np.ones((2, 3)), np.ones((2, 3))), ValueError,
138138
r"Incompatible dimensions of D matrix; expected \(2, 2\)"),
139+
(([1j], 2, 3, 0), TypeError, "real number, not 'complex'"),
139140
])
140141
def test_constructor_invalid(self, args, exc, errmsg):
141142
"""Test invalid input to StateSpace() constructor"""

control/tests/xferfcn_test.py

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def test_constructor_bad_input_type(self):
4949
[[4, 5], [6, 7]]],
5050
[[[6, 7], [4, 5]],
5151
[[2, 3]]])
52+
53+
with pytest.raises(TypeError, match="unsupported data type"):
54+
ct.tf([1j], [1, 2, 3])
55+
5256
# good input
5357
TransferFunction([[[0, 1], [2, 3]],
5458
[[4, 5], [6, 7]]],

control/xferfcn.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,7 @@ def _clean_part(data, name="<unknown>"):
19541954
19551955
"""
19561956
valid_types = (int, float, complex, np.number)
1957+
unsupported_types = (complex, np.complexfloating)
19571958
valid_collection = (list, tuple, ndarray)
19581959

19591960
if isinstance(data, np.ndarray) and data.ndim == 2 and \
@@ -1998,8 +1999,11 @@ def _clean_part(data, name="<unknown>"):
19981999
for i in range(out.shape[0]):
19992000
for j in range(out.shape[1]):
20002001
for k in range(len(out[i, j])):
2001-
if isinstance(out[i, j][k], (int, np.int32, np.int64)):
2002+
if isinstance(out[i, j][k], (int, np.integer)):
20022003
out[i, j][k] = float(out[i, j][k])
2004+
elif isinstance(out[i, j][k], unsupported_types):
2005+
raise TypeError(
2006+
f"unsupported data type: {type(out[i, j][k])}")
20032007
return out
20042008

20052009

doc/linear.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ of linear time-invariant (LTI) systems:
3939
y &= C x + D u
4040
4141
where :math:`u` is the input, :math:`y` is the output, and :math:`x`
42-
is the state.
42+
is the state. All vectors and matrices must be real-valued.
4343

4444
To create a state space system, use the :func:`ss` function:
4545

@@ -94,7 +94,8 @@ transfer functions
9494
{b_0 s^n + b_1 s^{n-1} + \cdots + b_n},
9595
9696
where :math:`n` is greater than or equal to :math:`m` for a proper
97-
transfer function. Improper transfer functions are also allowed.
97+
transfer function. Improper transfer functions are also allowed. All
98+
coefficients must be real-valued.
9899

99100
To create a transfer function, use the :func:`tf` function::
100101

examples/cruise.ipynb

+3-3
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@
420420
"name": "stdout",
421421
"output_type": "stream",
422422
"text": [
423-
"system: a = (0.010124405669387215-0j) , b = (1.3203061238159202+0j)\n",
424-
"pzcancel: kp = 0.5 , ki = (0.005062202834693608+0j) , 1/(kp b) = (1.5148002148317266+0j)\n",
423+
"system: a = 0.010124405669387215 , b = 1.3203061238159202\n",
424+
"pzcancel: kp = 0.5 , ki = 0.005062202834693608 , 1/(kp b) = 1.5148002148317266\n",
425425
"sfb_int: K = 0.5 , ki = 0.1\n"
426426
]
427427
},
@@ -442,7 +442,7 @@
442442
"\n",
443443
"# Construction a controller that cancels the pole\n",
444444
"kp = 0.5\n",
445-
"a = -P.poles()[0]\n",
445+
"a = -P.poles()[0].real\n",
446446
"b = np.real(P(0)) * a\n",
447447
"ki = a * kp\n",
448448
"control_pz = ct.TransferFunction(\n",

0 commit comments

Comments
 (0)