Skip to content

Commit 13441f9

Browse files
committed
added additional tests for minreal.
1 parent 7063eef commit 13441f9

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

tests/minreal_test.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python
2+
#
3+
# minreal_test.py - test state space class
4+
# Rvp, 13 Jun 2013
5+
6+
import unittest
7+
import numpy as np
8+
from scipy.linalg import eigvals
9+
import control.matlab as matlab
10+
from control.statesp import StateSpace, _convertToStateSpace
11+
from control.xferfcn import TransferFunction
12+
from itertools import permutations
13+
14+
class TestMinreal(unittest.TestCase):
15+
"""Tests for the StateSpace class."""
16+
17+
def setUp(self):
18+
np.random.seed(5)
19+
# depending on the seed and minreal performance, a number of
20+
# reductions is produced. If random gen or minreal change, this
21+
# will be likely to fail
22+
self.nreductions = 0
23+
24+
def assert_numden_almost_equal(self, n1, n2, d1, d2):
25+
n1[np.abs(n1) < 1e-10] = 0.
26+
n1 = np.trim_zeros(n1)
27+
d1[np.abs(d1) < 1e-10] = 0.
28+
d1 = np.trim_zeros(d1)
29+
n2[np.abs(n2) < 1e-10] = 0.
30+
n2 = np.trim_zeros(n2)
31+
d2[np.abs(d2) < 1e-10] = 0.
32+
d2 = np.trim_zeros(d2)
33+
np.testing.assert_array_almost_equal(n1, n2)
34+
np.testing.assert_array_almost_equal(d2, d2)
35+
36+
37+
def testMinrealBrute(self):
38+
for n, m, p in permutations(range(1,6), 3):
39+
s = matlab.rss(n, p, m)
40+
sr = s.minreal()
41+
if s.states > sr.states:
42+
self.nreductions += 1
43+
else:
44+
np.testing.assert_array_almost_equal(
45+
np.sort(eigvals(s.A)), np.sort(eigvals(sr.A)))
46+
for i in range(m):
47+
for j in range(p):
48+
ht1 = matlab.tf(
49+
matlab.ss(s.A, s.B[:,i], s.C[j,:], s.D[j,i]))
50+
ht2 = matlab.tf(
51+
matlab.ss(sr.A, sr.B[:,i], sr.C[j,:], sr.D[j,i]))
52+
try:
53+
self.assert_numden_almost_equal(
54+
ht1.num[0][0], ht2.num[0][0],
55+
ht1.den[0][0], ht2.den[0][0])
56+
except Exception, e:
57+
# for larger systems, the tf minreal's
58+
# the original rss, but not the balanced one
59+
if n < 6:
60+
raise e
61+
#if n > 6:
62+
# continue
63+
#print n, m, p
64+
#print s
65+
#print sr
66+
#print ht1
67+
#print ht2
68+
#print ht1.pole(), ht1.zero()
69+
#print ht2.pole(), ht2.zero()
70+
71+
#np.testing.assert_array_almost_equal(
72+
# ht1.num[0][0], ht2.num[0][0])
73+
#np.testing.assert_array_almost_equal(
74+
# ht1.den[0][0], ht2.den[0][0])
75+
76+
self.assertEqual(self.nreductions, 7)
77+
78+
def testMinrealSS(self):
79+
"""Test a minreal model reduction"""
80+
#A = [-2, 0.5, 0; 0.5, -0.3, 0; 0, 0, -0.1]
81+
A = [[-2, 0.5, 0], [0.5, -0.3, 0], [0, 0, -0.1]]
82+
#B = [0.3, -1.3; 0.1, 0; 1, 0]
83+
B = [[0.3, -1.3], [0.1, 0.], [1.0, 0.0]]
84+
#C = [0, 0.1, 0; -0.3, -0.2, 0]
85+
C = [[0., 0.1, 0.0], [-0.3, -0.2, 0.0]]
86+
#D = [0 -0.8; -0.3 0]
87+
D = [[0., -0.8], [-0.3, 0.]]
88+
# sys = ss(A, B, C, D)
89+
90+
sys = StateSpace(A, B, C, D)
91+
sysr = sys.minreal()
92+
self.assertEqual(sysr.states, 2)
93+
self.assertEqual(sysr.inputs, sys.inputs)
94+
self.assertEqual(sysr.outputs, sys.outputs)
95+
np.testing.assert_array_almost_equal(
96+
eigvals(sysr.A), [-2.136154, -0.1638459])
97+
98+
def testMinrealtf(self):
99+
"""Try the minreal function, and also test easy entry by creation
100+
of a Laplace variable s"""
101+
s = TransferFunction([1, 0], [1])
102+
h = (s+1)*(s+2.00000000001)/(s+2)/(s**2+s+1)
103+
hm = h.minreal()
104+
hr = (s+1)/(s**2+s+1)
105+
np.testing.assert_array_almost_equal(hm.num[0][0], hr.num[0][0])
106+
np.testing.assert_array_almost_equal(hm.den[0][0], hr.den[0][0])
107+
108+
def suite():
109+
return unittest.TestLoader().loadTestsFromTestCase(TestStateSpace)
110+
111+
112+
if __name__ == "__main__":
113+
unittest.main()

0 commit comments

Comments
 (0)