From 34a7a4924fd2bf91b17d724c3d7d0b4a4b3a6178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Thu, 25 May 2023 20:38:24 -0300 Subject: [PATCH 1/5] Add missing labels when returning TimeResponseData --- control/timeresp.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/control/timeresp.py b/control/timeresp.py index 638a07329..3ce4318b2 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -1111,6 +1111,8 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False, return TimeResponseData( tout, yout, xout, U, issiso=sys.issiso(), + output_labels=sys.output_labels, input_labels=sys.input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1374,8 +1376,16 @@ def step_response(sys, T=None, X0=0., input=None, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given input and output, if any + input_labels = sys.input_labels if input is None \ + else sys.input_labels[input] + output_labels = sys.output_labels if output is None \ + else sys.output_labels[output] + return TimeResponseData( response.time, yout, xout, uout, issiso=issiso, + output_labels=output_labels, input_labels=input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1704,9 +1714,15 @@ def initial_response(sys, T=None, X0=0., input=0, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given output, if any + output_labels = sys.output_labels if output is None \ + else sys.output_labels[0] + # Store the response without an input return TimeResponseData( response.t, response.y, response.x, None, issiso=issiso, + output_labels=output_labels, input_labels=None, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1798,7 +1814,7 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None, ----- This function uses the `forced_response` function to compute the time response. For continuous time systems, the initial condition is altered to - account for the initial impulse. For discrete-time aystems, the impulse is + account for the initial impulse. For discrete-time aystems, the impulse is sized so that it has unit area. Examples @@ -1869,8 +1885,16 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given input and output, if any + input_labels = sys.input_labels if input is None \ + else sys.input_labels[input] + output_labels = sys.output_labels if output is None \ + else sys.output_labels[output] + return TimeResponseData( response.time, yout, xout, uout, issiso=issiso, + output_labels=output_labels, input_labels=input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) From a78e85c3345154384f09ef7fd3cbd462caa92b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Sat, 20 May 2023 16:26:40 -0300 Subject: [PATCH 2/5] Test if labels are transferred to the response and we can still relabel them --- control/tests/trdata_test.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/control/tests/trdata_test.py b/control/tests/trdata_test.py index 734d35599..028e53580 100644 --- a/control/tests/trdata_test.py +++ b/control/tests/trdata_test.py @@ -196,15 +196,20 @@ def test_response_copy(): with pytest.raises(ValueError, match="not enough"): t, y, x = response_mimo - # Labels - assert response_mimo.output_labels is None - assert response_mimo.state_labels is None - assert response_mimo.input_labels is None + # Make sure labels are transferred to the response + assert response_siso.output_labels == sys_siso.output_labels + assert response_siso.state_labels == sys_siso.state_labels + assert response_siso.input_labels == sys_siso.input_labels + assert response_mimo.output_labels == sys_mimo.output_labels + assert response_mimo.state_labels == sys_mimo.state_labels + assert response_mimo.input_labels == sys_mimo.input_labels + + # Check relabelling response = response_mimo( output_labels=['y1', 'y2'], input_labels='u', - state_labels=["x[%d]" % i for i in range(4)]) + state_labels=["x%d" % i for i in range(4)]) assert response.output_labels == ['y1', 'y2'] - assert response.state_labels == ['x[0]', 'x[1]', 'x[2]', 'x[3]'] + assert response.state_labels == ['x0', 'x1', 'x2', 'x3'] assert response.input_labels == ['u'] # Unknown keyword @@ -231,6 +236,17 @@ def test_trdata_labels(): np.testing.assert_equal( response.input_labels, ["u[%d]" % i for i in range(sys.ninputs)]) + # Make sure the selected input and output are both correctly transferred to the response + for nu in range(sys.ninputs): + for ny in range(sys.noutputs): + step_response = ct.step_response(sys, T, input=nu, output=ny) + assert step_response.input_labels == [sys.input_labels[nu]] + assert step_response.output_labels == [sys.output_labels[ny]] + + init_response = ct.initial_response(sys, T, input=nu, output=ny) + assert init_response.input_labels == None + assert init_response.output_labels == [sys.output_labels[ny]] + def test_trdata_multitrace(): # From 56c72c7d34093df9deb143143e0e3f33882e9922 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Sat, 27 May 2023 09:59:32 -0700 Subject: [PATCH 3/5] use *_labels in input_output_response for consistency --- control/iosys.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/control/iosys.py b/control/iosys.py index 78444f7c1..dca00d3e5 100644 --- a/control/iosys.py +++ b/control/iosys.py @@ -1862,7 +1862,7 @@ def ufun(t): return TimeResponseData( t_eval, y, None, u, issiso=sys.issiso(), - output_labels=sys.output_index, input_labels=sys.input_index, + output_labels=sys.output_labels, input_labels=sys.input_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) # Create a lambda function for the right hand side @@ -1941,8 +1941,8 @@ def ivp_rhs(t, x): return TimeResponseData( soln.t, y, soln.y, u, issiso=sys.issiso(), - output_labels=sys.output_index, input_labels=sys.input_index, - state_labels=sys.state_index, + output_labels=sys.output_labels, input_labels=sys.input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -2881,7 +2881,7 @@ def interconnect( # Look for the signal name as a system input for sys in syslist: - if signal_name in sys.input_index.keys(): + if signal_name in sys.input_labels: connection.append(sign + sys.name + "." + signal_name) # Make sure we found the name From d744a5423901f2fefb3544adac41847388d9778d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Sat, 27 May 2023 14:32:04 -0300 Subject: [PATCH 4/5] Propagate labels and names when converting between mimo/siso/simo --- control/statesp.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/control/statesp.py b/control/statesp.py index 41f92ae21..8661d8741 100644 --- a/control/statesp.py +++ b/control/statesp.py @@ -1777,7 +1777,9 @@ def _mimo2siso(sys, input, output, warn_conversion=False): new_B = sys.B[:, input] new_C = sys.C[output, :] new_D = sys.D[output, input] - sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt) + sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt, + name=sys.name, + inputs=sys.input_labels[input], outputs=sys.output_labels[output]) return sys @@ -1826,7 +1828,9 @@ def _mimo2simo(sys, input, warn_conversion=False): # Y = C*X + D*U new_B = sys.B[:, input:input+1] new_D = sys.D[:, input:input+1] - sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt) + sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt, + name=sys.name, + inputs=sys.input_labels[input], outputs=sys.output_labels) return sys From bd83e8c9060f69d9e87afd861dda4b4bf3223bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ant=C3=B4nio=20Cardoso?= Date: Sat, 27 May 2023 15:36:04 -0300 Subject: [PATCH 5/5] Fix _process_labels to accept a single str label --- control/timeresp.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/control/timeresp.py b/control/timeresp.py index 3ce4318b2..bd8595cfe 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -694,7 +694,10 @@ def _process_labels(labels, signal, length): raise ValueError("Name dictionary for %s is incomplete" % signal) # Convert labels to a list - labels = list(labels) + if isinstance(labels, str): + labels = [labels] + else: + labels = list(labels) # Make sure the signal list is the right length and type if len(labels) != length: 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