Skip to content
Open
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
23dc966
propagate and allow overriding of signal labels in StateSpace lft fun…
tomaantjes Sep 6, 2026
e6a3e1b
add a check for validity of given nu and ny variables to statespace l…
tomaantjes Sep 6, 2026
37153cf
update Statespace lft function docstring to directly reflect its func…
tomaantjes Sep 9, 2026
6007d4d
add general lft function that can be used with any InputOutputSystem
tomaantjes Sep 12, 2026
47205b1
add lft function to kwarg tests
tomaantjes Sep 12, 2026
6776e2d
add unittests for lft function with LTI systems
tomaantjes Sep 12, 2026
bb06493
add unittest for lft function with general InputOutputSystem input
tomaantjes Sep 12, 2026
d74973d
add lft to function reference
tomaantjes Sep 12, 2026
1694287
add narrative documentation for lft function
tomaantjes Sep 12, 2026
3c9752f
make lft be able to use scalar, array and tf inputs
tomaantjes Sep 13, 2026
351ba99
add lft to see also of other bdalg functions
tomaantjes Sep 13, 2026
b72c3e0
reorder checks to be more logical in lft function
tomaantjes Sep 13, 2026
3262a35
compute maximal values before dimension check in ss.lft
tomaantjes Sep 13, 2026
2f65871
reorder bdalg lft tests
tomaantjes Sep 13, 2026
4cc8e24
add examples to lft functions
tomaantjes Sep 13, 2026
842a10c
fallback to default names if duplicate input or output names occur af…
tomaantjes Sep 13, 2026
7522036
make definition of ny and nu more general in lft docstrings
tomaantjes Sep 13, 2026
66d1f20
align FRD and non-LTI system input error test for lft function
tomaantjes Sep 13, 2026
d2264c6
remove unnecessary blank line
tomaantjes Sep 14, 2026
5a59926
mark lft test that requires slycot
tomaantjes Sep 15, 2026
7502973
add link to CDC article in lft functions
tomaantjes Sep 23, 2026
b2a59e0
add link to MATLAB lft function documentation in lft functions
tomaantjes Sep 23, 2026
76016cd
add fallback behavior for duplicate input and output labels to docstring
tomaantjes Sep 23, 2026
17d4262
remove extra spaces
tomaantjes Sep 23, 2026
c0c778e
use single backticks for Matlab lft function reference
tomaantjes Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add unittest for lft function with general InputOutputSystem input
update iosys_test test_lft docstring
  • Loading branch information
tomaantjes committed Sep 13, 2026
commit bb06493a0b406e2f1962112ef8a8efdb8214bc83
76 changes: 76 additions & 0 deletions control/tests/iosys_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,76 @@ def test_feedback(self, tsys):
lti_t, lti_y = ct.forced_response(linsys, T, U, X0)
np.testing.assert_allclose(ios_y, lti_y,atol=0.002,rtol=0.)

def test_lft(self, tsys):
"""Test that lft() with a NonlinearIOSystem matches a hand-built
LFT using interconnect() and labels propagate correctly."""
# Set up parameters for simulation
T, U, X0 = tsys.T, tsys.U, tsys.X0

sys1_ss = ct.rss(states=2, inputs=2, outputs=3, strictly_proper=True)
sys2_ss = ct.rss(states=2, inputs=2, outputs=3, strictly_proper=True)

sys1_nl = ct.NonlinearIOSystem(
lambda t, x, u, params: sys1_ss.A @ x + sys1_ss.B @ u,
lambda t, x, u, params: sys1_ss.C @ x + sys1_ss.D @ u,
states=2, inputs=['u1a', 'u1b'], outputs=['y1a', 'y1b', 'y1c'],
name='sys1')
sys2_nl = ct.NonlinearIOSystem(
lambda t, x, u, params: sys2_ss.A @ x + sys2_ss.B @ u,
lambda t, x, u, params: sys2_ss.C @ x + sys2_ss.D @ u,
states=2, inputs=['u2a', 'u2b'], outputs=['y2a', 'y2b', 'y2c'],
name='sys2')

# case 1: nu = -1, ny = -1
sys_lft = ct.lft(sys1_nl, sys2_nl)
sys_interconnect = ct.interconnect(
[sys1_nl, sys2_nl],
connections=[
['sys1.u1a', 'sys2.y2a'],
['sys1.u1b', 'sys2.y2b'],
['sys2.u2a', 'sys1.y1b'],
['sys2.u2b', 'sys1.y1c'],
],
inplist=[],
outlist=['sys1.y1a', 'sys2.y2c'],
)

lft_t, lft_y = ct.input_output_response(sys_lft, T, X0=X0)
ic_t, ic_y = ct.input_output_response(sys_interconnect, T, X0=X0)
np.testing.assert_allclose(lft_y, ic_y, atol=1e-10)
# check label propagation
assert sys_lft.output_labels == ['y1a', 'y2c']

# case 2: nu = 1, ny = 2
sys_lft = ct.lft(sys1_nl, sys2_nl, 1, 2)
sys_interconnect = ct.interconnect(
[sys1_nl, sys2_nl],
connections=[
['sys1.u1b', 'sys2.y2a'],
['sys2.u2a', 'sys1.y1b'],
['sys2.u2b', 'sys1.y1c'],
],
inplist=['sys1.u1a'],
outlist=['sys1.y1a', 'sys2.y2b', 'sys2.y2c'],
)
lft_t, lft_y = ct.input_output_response(sys_lft, T, U)
ic_t, ic_y = ct.input_output_response(sys_interconnect, T, U)
np.testing.assert_allclose(lft_y, ic_y, atol=1e-10)
# check label propagation
assert sys_lft.input_labels == ['u1a']
assert sys_lft.output_labels == ['y1a', 'y2b', 'y2c']

# check input, output and name overriding
sys_lft = ct.lft(
sys1_nl, sys2_nl, 1, 2,
inputs=['u'],
outputs=['y1','y2','y3'],
name='new_sys'
)
assert sys_lft.input_labels == ['u']
assert sys_lft.output_labels == ['y1', 'y2', 'y3']
assert sys_lft.name == 'new_sys'

def test_bdalg_functions(self, tsys):
"""Test block diagram functions algebra on I/O systems"""
# Set up parameters for simulation
Expand Down Expand Up @@ -640,6 +710,12 @@ def test_bdalg_functions(self, tsys):
ios_t, ios_y = ct.input_output_response(iosys_feedback, T, U, X0)
np.testing.assert_allclose(ios_y, lin_y,atol=0.002,rtol=0.)

linsys_lft = ct.lft(linsys1, linsys2, nu=1, ny=1)
iosys_lft = ct.lft(linio1, linio2, nu=1, ny=1)
lin_t, lin_y = ct.forced_response(linsys_lft, T, U, X0)
ios_t, ios_y = ct.input_output_response(iosys_lft, T, U, X0)
np.testing.assert_allclose(ios_y, lin_y,atol=0.002,rtol=0.)

def test_algebraic_functions(self, tsys):
"""Test algebraic operations on I/O systems"""
# Set up parameters for simulation
Expand Down