Add unit tests to increase code coverage · python-control/python-control@e61ac53
@@ -8,6 +8,7 @@
88991010from control import StateSpace, forced_response, impulse_response, tf, rss, c2d, TimeResponseData
11+from control.exception import ControlArgument, ControlDimension
1112from control.tests.conftest import slycotonly
1213from control.modelsimp import balred, hsvd, markov, modred
1314@@ -32,7 +33,7 @@ def testHSVD(self):
3233assert not isinstance(hsv, np.matrix)
33343435def testMarkovSignature(self):
35-U = np.array([[1., 1., 1., 1., 1.]])
36+U = np.array([[1., 1., 1., 1., 1., 1., 1.]])
3637Y = U
3738response = TimeResponseData(time=np.arange(U.shape[-1]),
3839outputs=Y,
@@ -41,27 +42,40 @@ def testMarkovSignature(self):
4142input_labels='u',
4243 )
434444-# Basic usage
45+# setup
4546m = 3
4647Htrue = np.array([1., 0., 0.])
48+Htrue_l = np.array([1., 0., 0., 0., 0., 0., 0.])
474948-H = markov(Y, U, m=m, transpose=False)
49-np.testing.assert_array_almost_equal(H, Htrue)
50+# test not enough input arguments
51+with pytest.raises(ControlArgument):
52+H = markov(Y)
53+with pytest.raises(ControlArgument):
54+H = markov()
505551-response.transpose=False
52-H = markov(response, m=m)
53-np.testing.assert_array_almost_equal(H, Htrue)
56+# to many positional arguments
57+with pytest.raises(ControlArgument):
58+H = markov(Y,U,m,1)
59+with pytest.raises(ControlArgument):
60+H = markov(response,m,1)
546155-# Make sure that transposed data also works
56-H = markov(Y.T, U.T, m, transpose=True)
57-np.testing.assert_array_almost_equal(H, np.transpose(Htrue))
62+# to many positional arguments
63+with pytest.raises(ControlDimension):
64+U2 = np.hstack([U,U])
65+H = markov(Y,U2,m)
586659-response.transpose=True
60-H = markov(response, m)
61-np.testing.assert_array_almost_equal(H, np.transpose(Htrue))
62-response.transpose=False
67+# not enough data
68+with pytest.warns(Warning):
69+H = markov(Y,U,8)
70+71+# Basic Usage, m=l
72+H = markov(Y, U)
73+np.testing.assert_array_almost_equal(H, Htrue_l)
637464-# Generate Markov parameters without any arguments
75+H = markov(response)
76+np.testing.assert_array_almost_equal(H, Htrue_l)
77+78+# Basic Usage, m
6579H = markov(Y, U, m)
6680np.testing.assert_array_almost_equal(H, Htrue)
6781@@ -74,6 +88,20 @@ def testMarkovSignature(self):
7488H = markov(response, m=m)
7589np.testing.assert_array_almost_equal(H, Htrue)
769091+response.transpose=False
92+H = markov(response, m=m)
93+np.testing.assert_array_almost_equal(H, Htrue)
94+95+# Make sure that transposed data also works, siso
96+HT = markov(Y.T, U.T, m, transpose=True)
97+np.testing.assert_array_almost_equal(HT, np.transpose(Htrue))
98+99+response.transpose = True
100+HT = markov(response, m)
101+np.testing.assert_array_almost_equal(HT, np.transpose(Htrue))
102+response.transpose=False
103+104+77105# Test example from docstring
78106# TODO: There is a problem here, last markov parameter does not fit
79107# the approximation error could be to big
@@ -114,16 +142,41 @@ def testMarkovSignature(self):
114142dt = 0.25
115143sysd = sys.sample(dt, method='zoh')
116144117-t = np.arange(0,100,dt)
118-u = np.random.randn(sysd.B.shape[-1], len(t))
119-response = forced_response(sysd, U=u)
145+T = np.arange(0,100,dt)
146+U = np.random.randn(sysd.B.shape[-1], len(T))
147+response = forced_response(sysd, U=U)
148+Y = response.outputs
120149121150m = 100
122-H = markov(response, m, dt=dt)
123151_, Htrue = impulse_response(sysd, T=dt*(m-1))
124152153+154+# test array_like
155+H = markov(Y, U, m, dt=dt)
125156np.testing.assert_array_almost_equal(H, Htrue)
126157158+# test array_like, truncate
159+H = markov(Y, U, m, dt=dt, truncate=True)
160+np.testing.assert_array_almost_equal(H, Htrue)
161+162+# test array_like, transpose
163+HT = markov(Y.T, U.T, m, dt=dt, transpose=True)
164+np.testing.assert_array_almost_equal(HT, np.transpose(Htrue))
165+166+# test response data
167+H = markov(response, m, dt=dt)
168+np.testing.assert_array_almost_equal(H, Htrue)
169+170+# test response data
171+H = markov(response, m, dt=dt, truncate=True)
172+np.testing.assert_array_almost_equal(H, Htrue)
173+174+# test response data, transpose
175+response.transpose = True
176+HT = markov(response, m, dt=dt)
177+np.testing.assert_array_almost_equal(HT, np.transpose(Htrue))
178+179+127180# Make sure markov() returns the right answer
128181@pytest.mark.parametrize("k, m, n",
129182 [(2, 2, 2),
@@ -168,14 +221,14 @@ def testMarkovResults(self, k, m, n):
168221ir_true = impulse_response(Hd,T)
169222Mtrue_scaled = ir_true[1][:m]
170223171-T, Y = forced_response(Hd, T, U, squeeze=True)
172-Mcomp = markov(Y, U, m, dt=True)
173-Mcomp_scaled = markov(Y, U, m, dt=Ts)
174-175224# Compare to results from markov()
176225# experimentally determined probability to get non matching results
177226# with rtot=1e-6 and atol=1e-8 due to numerical errors
178227# for k=5, m=n=10: 0.015 %
228+T, Y = forced_response(Hd, T, U, squeeze=True)
229+Mcomp = markov(Y, U, m, dt=True)
230+Mcomp_scaled = markov(Y, U, m, dt=Ts)
231+179232np.testing.assert_allclose(Mtrue, Mcomp, rtol=1e-6, atol=1e-8)
180233np.testing.assert_allclose(Mtrue_scaled, Mcomp_scaled, rtol=1e-6, atol=1e-8)
181234