diff --git a/control/tests/xferfcn_test.py b/control/tests/xferfcn_test.py index a9be040ab..89ceb9490 100644 --- a/control/tests/xferfcn_test.py +++ b/control/tests/xferfcn_test.py @@ -28,6 +28,21 @@ class TestXferFcn: # Tests for raising exceptions. + def test_zpk_complex_dtypes(self): + """Test zpk with complex64 and complex128 zeros/poles (Issue #1188).""" + P = ct.rss(5) + q1 = ct.zpk(zeros=P.zeros().astype(np.complex64), + poles=P.poles().astype(np.complex64), + gain=1, dt=0) + assert isinstance(q1, ct.TransferFunction) + assert "s^5" in str(q1) + + q2 = ct.zpk(zeros=P.zeros().astype(np.complex128), + poles=P.poles().astype(np.complex128), + gain=1, dt=0) + assert isinstance(q2, ct.TransferFunction) + assert "s^5" in str(q2) + def test_constructor_bad_input_type(self): """Give the constructor invalid input types.""" # Single argument of the wrong type diff --git a/control/xferfcn.py b/control/xferfcn.py index ad9ea0554..fa792643b 100644 --- a/control/xferfcn.py +++ b/control/xferfcn.py @@ -1379,6 +1379,7 @@ def _tf_polynomial_to_string(coeffs, var='s'): thestr = "0" # Apply NumPy formatting + coeffs = np.asarray(coeffs, dtype=float) with np.printoptions(threshold=sys.maxsize): coeffs = eval(repr(coeffs)) @@ -2015,6 +2016,12 @@ def _clean_part(data, name=""): # Check for coefficients that are ints and convert to floats for i in range(out.shape[0]): for j in range(out.shape[1]): + if np.iscomplexobj(out[i, j]): + if np.allclose(np.imag(out[i, j]), 0.0, atol=1e-10): + out[i, j] = np.real(out[i, j]).astype(float) + else: + raise TypeError( + f"unsupported data type: {type(out[i, j][0])}") for k in range(len(out[i, j])): if isinstance(out[i, j][k], (int, np.integer)): out[i, j][k] = float(out[i, j][k])