diff --git a/control/tests/statesp_test.py b/control/tests/statesp_test.py index e3d78bbdd..3c1411f04 100644 --- a/control/tests/statesp_test.py +++ b/control/tests/statesp_test.py @@ -136,6 +136,7 @@ def test_constructor(self, sys322ABCD, dt, argfun): ((np.ones((3, 3)), np.ones((3, 2)), np.ones((2, 3)), np.ones((2, 3))), ValueError, r"Incompatible dimensions of D matrix; expected \(2, 2\)"), + (([1j], 2, 3, 0), TypeError, "real number, not 'complex'"), ]) def test_constructor_invalid(self, args, exc, errmsg): """Test invalid input to StateSpace() constructor""" diff --git a/control/tests/xferfcn_test.py b/control/tests/xferfcn_test.py index 87c852395..d3db08ef6 100644 --- a/control/tests/xferfcn_test.py +++ b/control/tests/xferfcn_test.py @@ -49,6 +49,10 @@ def test_constructor_bad_input_type(self): [[4, 5], [6, 7]]], [[[6, 7], [4, 5]], [[2, 3]]]) + + with pytest.raises(TypeError, match="unsupported data type"): + ct.tf([1j], [1, 2, 3]) + # good input TransferFunction([[[0, 1], [2, 3]], [[4, 5], [6, 7]]], diff --git a/control/xferfcn.py b/control/xferfcn.py index 16d7c5054..02ba72df4 100644 --- a/control/xferfcn.py +++ b/control/xferfcn.py @@ -1954,6 +1954,7 @@ def _clean_part(data, name=""): """ valid_types = (int, float, complex, np.number) + unsupported_types = (complex, np.complexfloating) valid_collection = (list, tuple, ndarray) if isinstance(data, np.ndarray) and data.ndim == 2 and \ @@ -1998,8 +1999,11 @@ def _clean_part(data, name=""): for i in range(out.shape[0]): for j in range(out.shape[1]): for k in range(len(out[i, j])): - if isinstance(out[i, j][k], (int, np.int32, np.int64)): + if isinstance(out[i, j][k], (int, np.integer)): out[i, j][k] = float(out[i, j][k]) + elif isinstance(out[i, j][k], unsupported_types): + raise TypeError( + f"unsupported data type: {type(out[i, j][k])}") return out diff --git a/doc/linear.rst b/doc/linear.rst index b7b8f7137..a9960feca 100644 --- a/doc/linear.rst +++ b/doc/linear.rst @@ -39,7 +39,7 @@ of linear time-invariant (LTI) systems: y &= C x + D u where :math:`u` is the input, :math:`y` is the output, and :math:`x` -is the state. +is the state. All vectors and matrices must be real-valued. To create a state space system, use the :func:`ss` function: @@ -94,7 +94,8 @@ transfer functions {b_0 s^n + b_1 s^{n-1} + \cdots + b_n}, where :math:`n` is greater than or equal to :math:`m` for a proper -transfer function. Improper transfer functions are also allowed. +transfer function. Improper transfer functions are also allowed. All +coefficients must be real-valued. To create a transfer function, use the :func:`tf` function:: diff --git a/examples/cruise.ipynb b/examples/cruise.ipynb index 16935b15e..08a1583ac 100644 --- a/examples/cruise.ipynb +++ b/examples/cruise.ipynb @@ -420,8 +420,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "system: a = (0.010124405669387215-0j) , b = (1.3203061238159202+0j)\n", - "pzcancel: kp = 0.5 , ki = (0.005062202834693608+0j) , 1/(kp b) = (1.5148002148317266+0j)\n", + "system: a = 0.010124405669387215 , b = 1.3203061238159202\n", + "pzcancel: kp = 0.5 , ki = 0.005062202834693608 , 1/(kp b) = 1.5148002148317266\n", "sfb_int: K = 0.5 , ki = 0.1\n" ] }, @@ -442,7 +442,7 @@ "\n", "# Construction a controller that cancels the pole\n", "kp = 0.5\n", - "a = -P.poles()[0]\n", + "a = -P.poles()[0].real\n", "b = np.real(P(0)) * a\n", "ki = a * kp\n", "control_pz = ct.TransferFunction(\n", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy