Skip to content

Commit 77c3b40

Browse files
committed
reactivate the the fast forced_response(U=0) algorithm and test it
1 parent d87a0d1 commit 77c3b40

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

control/tests/timeresp_test.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def tsystem(self, request):
5151
siso_ss1.ystep = np.array([9., 17.6457, 24.7072, 30.4855, 35.2234,
5252
39.1165, 42.3227, 44.9694, 47.1599,
5353
48.9776])
54+
# X0 = [0.5, 1]
5455
siso_ss1.yinitial = np.array([11., 8.1494, 5.9361, 4.2258, 2.9118,
5556
1.9092, 1.1508, 0.5833, 0.1645, -0.1391])
5657
ss1 = siso_ss1.sys
@@ -135,6 +136,7 @@ def tsystem(self, request):
135136

136137
siso_dss1 = copy(siso_dtf1)
137138
siso_dss1.sys = tf2ss(siso_dtf1.sys)
139+
siso_dss1.yinitial = np.array([-1., -0.5, 0.75, -0.625, 0.4375])
138140

139141
siso_dss2 = copy(siso_dtf2)
140142
siso_dss2.sys = tf2ss(siso_dtf2.sys)
@@ -634,19 +636,23 @@ def test_forced_response_legacy(self):
634636
[pytest.param("siso_ss1",
635637
{'X0': [0.5, 1], 'T': np.linspace(0, 1, 10)},
636638
'yinitial',
637-
id="ctime no T"),
639+
id="ctime no U"),
640+
pytest.param("siso_dss1",
641+
{'T': np.arange(0, 5, 1,),
642+
'X0': [0.5, 1]}, 'yinitial',
643+
id="dt=True, no U"),
638644
pytest.param("siso_dtf1",
639645
{'U': np.ones(5,)}, 'ystep',
640-
id="dt=True, no U"),
646+
id="dt=True, no T"),
641647
pytest.param("siso_dtf2",
642648
{'U': np.ones(25,)}, 'ystep',
643-
id="dt=0.2, no U"),
649+
id="dt=0.2, no T"),
644650
pytest.param("siso_ss2_dtnone",
645651
{'U': np.ones(10,)}, 'ystep',
646-
id="dt=None, no U"),
652+
id="dt=None, no T"),
647653
pytest.param("siso_dtf3",
648654
{'U': np.ones(10,)}, 'ystep',
649-
id="dt with rounding error"),
655+
id="dt with rounding error, no T"),
650656
],
651657
indirect=["tsystem"])
652658
def test_forced_response_T_U(self, tsystem, fr_kwargs, refattr):
@@ -661,13 +667,13 @@ def test_forced_response_invalid_c(self, tsystem):
661667
with pytest.raises(TypeError,
662668
match="StateSpace.*or.*TransferFunction"):
663669
forced_response("not a system")
664-
665-
# ctime
666670
with pytest.raises(ValueError, match="T.*is mandatory for continuous"):
667671
forced_response(tsystem.sys)
668672
with pytest.raises(ValueError, match="time values must be equally "
669673
"spaced"):
670674
forced_response(tsystem.sys, [0, 0.1, 0.12, 0.4])
675+
with pytest.raises(ValueError, match="must start with 0"):
676+
forced_response(tsystem.sys, [1, 1.1, 1.2, 1.3])
671677

672678
@pytest.mark.parametrize("tsystem", ["siso_dss2"], indirect=True)
673679
def test_forced_response_invalid_d(self, tsystem):

control/timeresp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
379379
dot = np.dot # Faster and shorter code
380380

381381
# Faster algorithm if U is zero
382-
if U is None or (isinstance(U, (int, float)) and U == 0):
382+
# (was converted to arrqy above if not None)
383+
if U is None or np.all(U == 0):
383384
# Solve using matrix exponential
384385
expAdt = sp.linalg.expm(A * dt)
385386
for i in range(1, n_steps):

0 commit comments

Comments
 (0)