88
99
1010from 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):
3233 assert not isinstance (hsv , np .matrix )
3334
3435 def testMarkovSignature (self ):
35- U = np .array ([[1. , 1. , 1. , 1. , 1. ]])
36+ U = np .array ([[1. , 1. , 1. , 1. , 1. , 1. , 1. ]])
3637 Y = U
3738 response = TimeResponseData (time = np .arange (U .shape [- 1 ]),
3839 outputs = Y ,
@@ -41,27 +42,40 @@ def testMarkovSignature(self):
4142 input_labels = 'u' ,
4243 )
4344
44- # Basic usage
45+ # setup
4546 m = 3
4647 Htrue = np .array ([1. , 0. , 0. ])
48+ Htrue_l = np .array ([1. , 0. , 0. , 0. , 0. , 0. , 0. ])
4749
48- 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 ()
5055
51- 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 )
5461
55- # 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 )
5866
59- 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 )
6374
64- # 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
6579 H = markov (Y , U , m )
6680 np .testing .assert_array_almost_equal (H , Htrue )
6781
@@ -74,6 +88,20 @@ def testMarkovSignature(self):
7488 H = markov (response , m = m )
7589 np .testing .assert_array_almost_equal (H , Htrue )
7690
91+ 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):
114142 dt = 0.25
115143 sysd = sys .sample (dt , method = 'zoh' )
116144
117- 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
120149
121150 m = 100
122- H = markov (response , m , dt = dt )
123151 _ , Htrue = impulse_response (sysd , T = dt * (m - 1 ))
124152
153+
154+ # test array_like
155+ H = markov (Y , U , m , dt = dt )
125156 np .testing .assert_array_almost_equal (H , Htrue )
126157
158+ # 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):
168221 ir_true = impulse_response (Hd ,T )
169222 Mtrue_scaled = ir_true [1 ][:m ]
170223
171- 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+
179232 np .testing .assert_allclose (Mtrue , Mcomp , rtol = 1e-6 , atol = 1e-8 )
180233 np .testing .assert_allclose (Mtrue_scaled , Mcomp_scaled , rtol = 1e-6 , atol = 1e-8 )
181234
0 commit comments