8
8
9
9
10
10
from control import StateSpace , forced_response , impulse_response , tf , rss , c2d , TimeResponseData
11
+ from control .exception import ControlArgument , ControlDimension
11
12
from control .tests .conftest import slycotonly
12
13
from control .modelsimp import balred , hsvd , markov , modred
13
14
@@ -32,7 +33,7 @@ def testHSVD(self):
32
33
assert not isinstance (hsv , np .matrix )
33
34
34
35
def testMarkovSignature (self ):
35
- U = np .array ([[1. , 1. , 1. , 1. , 1. ]])
36
+ U = np .array ([[1. , 1. , 1. , 1. , 1. , 1. , 1. ]])
36
37
Y = U
37
38
response = TimeResponseData (time = np .arange (U .shape [- 1 ]),
38
39
outputs = Y ,
@@ -41,27 +42,40 @@ def testMarkovSignature(self):
41
42
input_labels = 'u' ,
42
43
)
43
44
44
- # Basic usage
45
+ # setup
45
46
m = 3
46
47
Htrue = np .array ([1. , 0. , 0. ])
48
+ Htrue_l = np .array ([1. , 0. , 0. , 0. , 0. , 0. , 0. ])
47
49
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 ()
50
55
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 )
54
61
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 )
58
66
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 )
63
74
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
65
79
H = markov (Y , U , m )
66
80
np .testing .assert_array_almost_equal (H , Htrue )
67
81
@@ -74,6 +88,20 @@ def testMarkovSignature(self):
74
88
H = markov (response , m = m )
75
89
np .testing .assert_array_almost_equal (H , Htrue )
76
90
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
+
77
105
# Test example from docstring
78
106
# TODO: There is a problem here, last markov parameter does not fit
79
107
# the approximation error could be to big
@@ -114,16 +142,41 @@ def testMarkovSignature(self):
114
142
dt = 0.25
115
143
sysd = sys .sample (dt , method = 'zoh' )
116
144
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
120
149
121
150
m = 100
122
- H = markov (response , m , dt = dt )
123
151
_ , Htrue = impulse_response (sysd , T = dt * (m - 1 ))
124
152
153
+
154
+ # test array_like
155
+ H = markov (Y , U , m , dt = dt )
125
156
np .testing .assert_array_almost_equal (H , Htrue )
126
157
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
+
127
180
# Make sure markov() returns the right answer
128
181
@pytest .mark .parametrize ("k, m, n" ,
129
182
[(2 , 2 , 2 ),
@@ -168,14 +221,14 @@ def testMarkovResults(self, k, m, n):
168
221
ir_true = impulse_response (Hd ,T )
169
222
Mtrue_scaled = ir_true [1 ][:m ]
170
223
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
-
175
224
# Compare to results from markov()
176
225
# experimentally determined probability to get non matching results
177
226
# with rtot=1e-6 and atol=1e-8 due to numerical errors
178
227
# 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
+
179
232
np .testing .assert_allclose (Mtrue , Mcomp , rtol = 1e-6 , atol = 1e-8 )
180
233
np .testing .assert_allclose (Mtrue_scaled , Mcomp_scaled , rtol = 1e-6 , atol = 1e-8 )
181
234
0 commit comments