@@ -52,3 +52,47 @@ def test_unreachable_system(self):
52
52
53
53
# Check if an exception is raised
54
54
np .testing .assert_raises (ValueError ,canonical_form ,sys ,"reachable" )
55
+
56
+ def test_observable_form (self ):
57
+ """Test the observable canonical form"""
58
+
59
+ # Create a system in the observable canonical form
60
+ coeffs = [1.0 ,2.0 ,3.0 ,4.0 ,1.0 ]
61
+ A_true = np .polynomial .polynomial .polycompanion (coeffs )
62
+ A_true = np .fliplr (np .flipud (A_true ))
63
+ B_true = np .matrix ("1.0 1.0 1.0 1.0" ).T
64
+ C_true = np .matrix ("1.0 0.0 0.0 0.0" )
65
+ D_true = 42.0
66
+
67
+ # Perform a coordinate transform with a random invertible matrix
68
+ T_true = np .matrix ([[- 0.27144004 ,- 0.39933167 ,0.75634684 ,0.44135471 ],
69
+ [- 0.74855725 ,- 0.39136285 ,- 0.18142339 ,- 0.50356997 ],
70
+ [- 0.40688007 ,0.81416369 ,0.38002113 ,- 0.16483334 ],
71
+ [- 0.44769516 ,0.15654653 ,- 0.50060858 ,0.72419146 ]])
72
+ A = np .linalg .solve (T_true ,A_true )* T_true
73
+ B = np .linalg .solve (T_true ,B_true )
74
+ C = C_true * T_true
75
+ D = D_true
76
+
77
+ # Create a state space system and convert it to the observable canonical form
78
+ sys_check ,T_check = canonical_form (ss (A ,B ,C ,D ),"observable" )
79
+
80
+ # Check against the true values
81
+ np .testing .assert_array_almost_equal (sys_check .A ,A_true )
82
+ np .testing .assert_array_almost_equal (sys_check .B ,B_true )
83
+ np .testing .assert_array_almost_equal (sys_check .C ,C_true )
84
+ np .testing .assert_array_almost_equal (sys_check .D ,D_true )
85
+ np .testing .assert_array_almost_equal (T_check ,T_true )
86
+
87
+ def test_unobservable_system (self ):
88
+ """Test observable canonical form with an unobservable system"""
89
+
90
+ # Create an unobservable system
91
+ A = np .matrix ("1.0 2.0 2.0; 4.0 5.0 5.0; 7.0 8.0 8.0" )
92
+ B = np .matrix ("1.0 1.0 1.0" ).T
93
+ C = np .matrix ("1.0 1.0 1.0" )
94
+ D = 42.0
95
+ sys = ss (A ,B ,C ,D )
96
+
97
+ # Check if an exception is raised
98
+ np .testing .assert_raises (ValueError ,canonical_form ,sys ,"observable" )