Skip to content

Commit bdfed54

Browse files
committed
add tf() support for array of SISO [combine_tf] + documentation updates
1 parent 2d56ecf commit bdfed54

File tree

4 files changed

+168
-128
lines changed

4 files changed

+168
-128
lines changed

control/tests/docstrings_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
control.series: '9aede1459667738f05cf4fc46603a4f6',
3838
control.ss: '1b9cfad5dbdf2f474cfdeadf5cb1ad80',
3939
control.ss2tf: '48ff25d22d28e7b396e686dd5eb58831',
40-
control.tf: '53a13f4a7f75a31c81800e10c88730ef',
40+
control.tf: '155a19afb95452ed19966c8d8ae23a84',
4141
control.tf2ss: '086a3692659b7321c2af126f79f4bc11',
4242
control.markov: 'a4199c54cb50f07c0163d3790739eafe',
4343
control.gangof4: '0e52eb6cf7ce024f9a41f3ae3ebf04f7',

control/tests/xferfcn_input_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ def test_clean_part(num, fun, dtype):
7272
np.testing.assert_allclose(numj, ref_[i, j, ...])
7373

7474

75-
@pytest.mark.parametrize("badinput", [[[0., 1.], [2., 3.]], "a"])
75+
@pytest.mark.parametrize("badinput", [
76+
# [[0., 1.], [2., 3.]], # OK: treated as static array
77+
np.ones((2, 2, 2, 2)),
78+
"a"])
7679
def test_clean_part_bad_input(badinput):
7780
"""Give the part cleaner invalid input type."""
7881
with pytest.raises(TypeError):

control/tests/xferfcn_test.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ class TestXferFcn:
3131
def test_constructor_bad_input_type(self):
3232
"""Give the constructor invalid input types."""
3333
# MIMO requires lists of lists of vectors (not lists of vectors)
34-
with pytest.raises(TypeError):
35-
TransferFunction([[0., 1.], [2., 3.]], [[5., 2.], [3., 0.]])
34+
# 13 Dec 2024: This now works correctly: creates static array (as tf)
35+
# with pytest.raises(TypeError):
36+
# TransferFunction([[0., 1.], [2., 3.]], [[5., 2.], [3., 0.]])
3637
# good input
3738
TransferFunction([[[0., 1.], [2., 3.]]],
3839
[[[5., 2.], [3., 0.]]])
@@ -1298,3 +1299,35 @@ def test_copy_names(create, args, kwargs, convert):
12981299
cpy = convert(sys, inputs='myin', outputs='myout')
12991300
assert cpy.input_labels == ['myin']
13001301
assert cpy.output_labels == ['myout']
1302+
1303+
s = ct.TransferFunction.s
1304+
@pytest.mark.parametrize("args, num, den", [
1305+
(('s', ), [[[1, 0]]], [[[1]]]), # ctime
1306+
(('z', ), [[[1, 0]]], [[[1]]]), # dtime
1307+
((1, 1), [[[1]]], [[[1]]]), # scalars as scalars
1308+
(([[1]], [[1]]), [[[1]]], [[[1]]]), # scalars as lists
1309+
(([[[1, 2]]], [[[3, 4]]]), [[[1, 2]]], [[[3, 4]]]), # SISO as lists
1310+
(([[np.array([1, 2])]], [[np.array([3, 4])]]), # SISO as arrays
1311+
[[[1, 2]]], [[[3, 4]]]),
1312+
(([[ [1], [2] ], [[1, 1], [1, 0] ]], # MIMO
1313+
[[ [1, 0], [1, 0] ], [[1, 2], [1] ]]),
1314+
[[ [1], [2] ], [[1, 1], [1, 0] ]],
1315+
[[ [1, 0], [1, 0] ], [[1, 2], [1] ]]),
1316+
(([[[1, 2], [3, 4]]], [[[5, 6]]]), # common denominator
1317+
[[[1, 2], [3, 4]]], [[[5, 6], [5, 6]]]),
1318+
(([ [1/s, 2/s], [(s+1)/(s+2), s]], ), # 2x2 from SISO
1319+
[[ [1], [2] ], [[1, 1], [1, 0] ]], # num
1320+
[[ [1, 0], [1, 0] ], [[1, 2], [1] ]]), # den
1321+
(([[1, 2], [3, 4]], [[[1, 0], [1, 0]]]), ValueError,
1322+
r"numerator has 2 output\(s\), but the denominator has 1 output"),
1323+
])
1324+
def test_tf_args(args, num, den):
1325+
if isinstance(num, type):
1326+
exception, match = num, den
1327+
with pytest.raises(exception, match=match):
1328+
sys = ct.tf(*args)
1329+
else:
1330+
sys = ct.tf(*args)
1331+
chk = ct.tf(num, den)
1332+
np.testing.assert_equal(sys.num, chk.num)
1333+
np.testing.assert_equal(sys.den, chk.den)

0 commit comments

Comments
 (0)