8000 Move linfnorm reference data to pytest fixtures · python-control/python-control@f529721 · GitHub
[go: up one dir, main page]

Skip to content

Commit f529721

Browse files
committed
Move linfnorm reference data to pytest fixtures
This avoids the PendingDeprecationWarning from numpy.matrix. Also moved all linfnorm tests into a class to make them easier to run together.
1 parent 64bdb10 commit f529721

File tree

3 files changed

+196
-136
lines changed

3 files changed

+196
-136
lines changed

control/tests/linfnorm_mimo_testcases.py

Lines changed: 85 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
"""Generated reference data for linfnorm MIMO tests
22
Don't edit this file!
33
See <python-control-source-root>/tools/make_linfnorm_mimo_testcases.py"""
4-
from control import StateSpace
54
from numpy import inf
6-
continuous_time = [('gdamped',
7-
StateSpace([[ -2., 5., 1., 17.],
5+
import pytest
6+
from control import StateSpace
7+
8+
@pytest.fixture(params=[
9+
('gdamped',
10+
StateSpace,
11+
([[ -2., 5., 1., 17.],
812
[ 0., 11., 17., 1.],
913
[ 0., 0., 8., 9.],
1014
[ 0., 0., 0.,-10.]],[[ 28., 23., 12.],
@@ -17,10 +21,11 @@
1721
[-11., 1.,-14.],
1822
[ 16., -1., 0.],
1923
[-11.,-11.,-15.]]),
20-
386.1087766295148,
21-
0.0),
22-
('ghigh',
23-
StateSpace([[ 3.,-12., 2.,-16.],
24+
386.1087766295148,
25+
0.0),
26+
('ghigh',
27+
StateSpace,
28+
([[ 3.,-12., 2.,-16.],
2429
[ 0., 8., -0., -2.],
2530
[ 0., 0., 11., -2.],
2631
[ 0., 0., 0., -2.]],[[ -7., 10., 11.],
@@ -33,10 +38,11 @@
3338
[-172., 112., 17.],
3439
[ 625.,-418., -86.],
3540
[-510., 377., 99.]]),
36-
1242.6678452759131,
37-
inf),
38-
('gint',
39-
StateSpace([[ 0., 2.,-11.,-18.],
41+
1242.6678452759131,
42+
inf),
43+
('gint',
44+
StateSpace,
45+
([[ 0., 2.,-11.,-18.],
4046
[ 0., 2.,-10.,-17.],
4147
[ 0., 0., -0., 19.],
4248
[ 0., 0., 0., -7.]],[[ -5., 13., -1.],
@@ -49,10 +55,11 @@
4955
[ 13., 4., -0.],
5056
[ 13., -2., 7.],
5157
[ 11.,-21.,-16.]]),
52-
inf,
53-
0.0),
54-
('gunder',
55-
StateSpace([[ -0.15375000000000003, 12.299039024960447 , -7. ,
58+
inf,
59+
0.0),
60+
('gunder',
61+
StateSpace,
62+
([[ -0.15375000000000003, 12.299039024960447 , -7. ,
5663
10. ],
5764
[-12.299039024960447 , -0.15375000000000003, -5. ,
5865
-11. ],
@@ -69,10 +76,11 @@
6976
[-11., 12., -1.],
7077
[-11., 8., 5.],
7178
[ 6., -6., 9.]]),
72-
2132.537616682341,
73-
12.296890463172536),
74-
('gun',
75-
StateSpace([[ 0. , 57.2, -4. , 9. ],
79+
2132.537616682341,
80+
12.296890463172536),
81+
('gun',
82+
StateSpace,
83+
([[ 0. , 57.2, -4. , 9. ],
7684
[-57.2, 0. , 4. , 12. ],
7785
[ 0. , 0. , -5. , -3. ],
7886
[ 0. , 0. , 0. , 12. ]],[[ 5.,-13., -3.],
@@ -85,11 +93,16 @@
8593
[-19., 4., 9.],
8694
[ 2., 15.,-12.],
8795
[ -2., 11., 4.]]),
88-
inf,
89-
57.20000000000001),
90-
('gstatic', StateSpace([],[],[],[[-0.,-1., 1.]]), 1.4142135623730951, 0),
91-
('gzero',
92-
StateSpace([[ 5., -4.,-21., -6.],
96+
inf,
97+
57.20000000000001),
98+
('gstatic',
99+
StateSpace,
100+
([],[],[],[[-0.,-1., 1.]]),
101+
1.4142135623730951,
102+
0),
103+
('gzero',
104+
StateSpace,
105+
([[ 5., -4.,-21., -6.],
93106
[ -7., -7., 3.,-21.],
94107
[ -5.,-14.,-13., -5.],
95108
[ 5., -1., 13., 12.]],[[12.,-6., 1.],
@@ -102,11 +115,18 @@
102115
[0.,0.,0.],
103116
[0.,0.,0.],
104117
[0.,0.,0.]]),
105-
0.0,
106-
0.0)]
118+
0.0,
119+
0.0),
120+
])
121+
def continuous_time_mimo(request):
122+
name, sys, sysargs, gpeak, fpeak = request.param
123+
return sys(*sysargs), gpeak, fpeak
107124

108-
discrete_time = [('gdamped',
109-
StateSpace([[0.9819824738582276 ,0.04738017085285391,0.01304472802238469,
125+
126+
@pytest.fixture(params=[
127+
('gdamped',
128+
StateSpace,
129+
([[0.9819824738582276 ,0.04738017085285391,0.01304472802238469,
110130
0.1470448917373791 ],
111131
[0. ,1.1051709180756477 ,0.16849109254370773,
112132
0.01564904563135911],
@@ -123,10 +143,11 @@
123143
[-11., 1.,-14.],
124144
[ 16., -1., 0.],
125145
[-11.,-11.,-15.]],0.009090909090909092),
126-
386.10877662951657,
127-
0.0),
128-
('ghigh',
129-
StateSpace([[ 1.027648032193792 ,-0.11469399280382421, 0.01938072147046389,
146+
386.10877662951657,
147+
0.0),
148+
('ghigh',
149+
StateSpace,
150+
([[ 1.027648032193792 ,-0.11469399280382421, 0.01938072147046389,
130151
-0.14528191736584178],
131152
[ 0. , 1.075437195862052 , 0. ,
132153
-0.01869094440076494],
@@ -143,10 +164,11 @@
143164
[-172., 112., 17.],
144165
[ 625.,-418., -86.],
145166
[-510., 377., 99.]],0.009090909090909092),
146-
1242.1155726933578,
147-
345.5751918948772),
148-
('gint',
149-
StateSpace([[ 1. , 0.0289835070315593 ,-0.1592032494435108 ,
167+
1242.1155726933578,
168+
345.5751918948772),
169+
('gint',
170+
StateSpace,
171+
([[ 1. , 0.0289835070315593 ,-0.1592032494435108 ,
150172
-0.26890731179354416],
151173
[ 0. , 1.0289835070315594 ,-0.1449175351577965 ,
152174
-0.25343692370310505],
@@ -163,10 +185,11 @@
163185
[ 13., 4., -0.],
164186
[ 13., -2., 7.],
165187
[ 11.,-21.,-16.]],0.014285714285714287),
166-
inf,
167-
0.0),
168-
('gunder',
169-
StateSpace([[ 0.9937619660689812 , 0.09970093877277594,-0.06000817801207847,
188+
inf,
189+
0.0),
190+
('gunder',
191+
StateSpace,
192+
([[ 0.9937619660689812 , 0.09970093877277594,-0.06000817801207847,
170193
0.0780263338524106 ],
171194
[-0.09970093877277594, 0.9937619660689814 ,-0.03851439054957319,
172195
-0.09715770014616815],
@@ -183,10 +206,11 @@
183206
[-11., 12., -1.],
184207
[-11., 8., 5.],
185208
[ 6., -6., 9.]],0.008130081300813009),
186-
2131.625673152001,
187-
12.296903265202138),
188-
('gun',
189-
StateSpace([[ 0.9950041652780258 , 0.09983341664682814,-0.0066025652360765 ,
209+
2131.625673152001,
210+
12.296903265202138),
211+
('gun',
212+
StateSpace,
213+
([[ 0.9950041652780258 , 0.09983341664682814,-0.0066025652360765 ,
190214
0.0169473549277053 ],
191215
[-0.09983341664682815, 0.9950041652780258 , 0.00729925125163074,
192216
0.02035489919552947],
@@ -203,11 +227,16 @@
203227
[-19., 4., 9.],
204228
[ 2., 15.,-12.],
205229
[ -2., 11., 4.]],0.001748251748251748),
206-
inf,
207-
57.19999999999999),
208-
('gstatic', StateSpace([],[],[],[[-0.,-1., 1.]],0.1), 1.4142135623730951, 0),
209-
('gzero',
210-
StateSpace([[ 1.0303043647406893 ,-0.01781959428593542,-0.11765779072192348,
230+
inf,
231+
57.19999999999999),
232+
('gstatic',
233+
StateSpace,
234+
([],[],[],[[-0.,-1., 1.]],0.1),
235+
1.4142135623730951,
236+
0),
237+
('gzero',
238+
StateSpace,
239+
([[ 1.0303043647406893 ,-0.01781959428593542,-0.11765779072192348,
211240
-0.03276338055744957],
212241
[-0.04132960349200208, 0.9613575174517476 , 0.014113316237035 ,
213242
-0.12012463024982983],
@@ -224,5 +253,10 @@
224253
[0.,0.,0.],
225254
[0.,0.,0.],
226255
[0.,0.,0.]],0.0056597835333160335),
227-
0.0,
228-
0.0)]
256+
0.0,
257+
0.0),
258+
])
259+
def discrete_time_mimo(request):
260+
name, sys, sysargs, gpeak, fpeak = request.param
261+
return sys(*sysargs), gpeak, fpeak
262+

control/tests/statesp_test.py

Lines changed: 67 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
from .conftest import editsdefaults
2929

30-
from . import linfnorm_mimo_testcases
30+
from .linfnorm_mimo_testcases import continuous_time_mimo, discrete_time_mimo
3131

3232
class TestStateSpace:
3333
"""Tests for the StateSpace class."""
@@ -1102,72 +1102,69 @@ def test_latex_repr_testsize(editsdefaults):
11021102
assert gstatic._repr_latex_() is None
11031103

11041104

1105-
# these are relatively simple examples
1106-
# the underdamped gpeak and fpeak are found from
1107-
# gpeak = 1/(2*zeta*(1-zeta**2)**0.5
1108-
# fpeak = wn*(1-2*zeta**2)**0.5
1109-
@slycotonly
1110-
@pytest.mark.parametrize(
1111-
"name, sys, refgpeak, reffpeak",
1112-
[
1113-
('lpf', ct.tf([1],[1,1]), 1, 0),
1114-
('static', ct.tf([1.23],[1]), 1.23, 0),
1115-
('underdamped', ct.tf([100],[1, 2*0.1*10, 100]), 5.02518907629606, 9.89949493661),
1116-
('hpf', ct.tf([1, 0], [1, 1]), 1, np.inf),
1117-
('integrator', ct.tf([1],[1,0]), np.inf, 0),
1118-
('undamped', ct.tf([1],[1, 0, 144]), np.inf, 12),
1119-
('zero', ct.tf([0],[1, 0, 144]), 0, 0),
1120-
])
1121-
def test_linfnorm_siso_continuoustime(name, sys, refgpeak, reffpeak):
1122-
gpeak, fpeak = linfnorm(sys)
1123-
np.testing.assert_allclose(gpeak, refgpeak)
1124-
np.testing.assert_allclose(fpeak, reffpeak)
1125-
1126-
1127-
# these are the continuous-time examples with some tweaks
1128-
@slycotonly
1129-
@pytest.mark.parametrize(
1130-
"name, sys, refgpeak, reffpeak",
1131-
[
1132-
('lpf', ct.c2d(ct.tf([1],[1,1]), 0.1), 1, 0),
1133-
('static', ct.c2d(ct.tf([1.23],[1]), 0.1), 1.23, 0),
1134-
# the gain and frequency don't quite match the continuous-time case,
1135-
# I assume due to c2d imperfection
1136-
('underdamped', ct.c2d(ct.tf([100],[1, 2*0.1*10, 100]), 0.01), 5.023137, 9.899412),
1137-
# The HPF fpeak is the Nyquist frequency
1138-
# Assume gpeak mismatch is again c2d mismatch
1139-
('hpf', ct.c2d(ct.tf([1, 0], [1, 1]), 0.1), 1.04995845, np.pi * 10),
1140-
('integrator', ct.c2d(ct.tf([1],[1,0]), 0.1), np.inf, 0),
1141-
('undamped', ct.c2d(ct.tf([1],[1, 0, 144]), 0.003), np.inf, 12),
1142-
# ss call works around Scipy's "Badly conditioned filter coefficients" warning
1143-
('zero', ct.c2d(ct.ss(ct.tf([0],[1, 0, 144])), 0.003), 0, 0),
1144-
])
1145-
def test_linfnorm_siso_discretetime(name, sys, refgpeak, reffpeak):
1146-
gpeak, fpeak = linfnorm(sys)
1147-
np.testing.assert_allclose(gpeak, refgpeak)
1148-
np.testing.assert_allclose(fpeak, reffpeak)
1149-
1150-
1151-
@slycotonly
1152-
@pytest.mark.parametrize("name, sys, refgpeak, reffpeak",
1153-
linfnorm_mimo_testcases.continuous_time)
1154-
def test_linfnorm_mimo_continuoustime(name, sys, refgpeak, reffpeak):
1155-
gpeak, fpeak = linfnorm(sys)
1156-
np.testing.assert_allclose(gpeak, refgpeak)
1157-
np.testing.assert_allclose(fpeak, reffpeak)
1158-
1159-
1160-
@slycotonly
1161-
@pytest.mark.parametrize("name, sys, refgpeak, reffpeak",
1162-
linfnorm_mimo_testcases.discrete_time)
1163-
def test_linfnorm_mimo_discretetime(name, sys, refgpeak, reffpeak):
1164-
gpeak, fpeak = linfnorm(sys)
1165-
np.testing.assert_allclose(gpeak, refgpeak)
1166-
np.testing.assert_allclose(fpeak, reffpeak)
1167-
1168-
1169-
@slycotonly
1170-
def test_linfnorm_notimebase():
1171-
g = ct.ss(-0.1,1,1,0,dt=None)
1172-
with pytest.raises(ValueError):
1173-
linfnorm(g)
1105+
class TestLinfnorm:
1106+
# these are relatively simple examples
1107+
# the underdamped gpeak and fpeak are found from
1108+
# gpeak = 1/(2*zeta*(1-zeta**2)**0.5
1109+
# fpeak = wn*(1-2*zeta**2)**0.5
1110+
@slycotonly
1111+
@pytest.mark.parametrize(
1112+
"name, sys, refgpeak, reffpeak",
1113+
[
1114+
('lpf', ct.tf([1],[1,1]), 1, 0),
1115+
('static', ct.tf([1.23],[1]), 1.23, 0),
1116+
('underdamped', ct.tf([100],[1, 2*0.1*10, 100]), 5.02518907629606, 9.89949493661),
1117+
('hpf', ct.tf([1, 0], [1, 1]), 1, np.inf),
1118+
('integrator', ct.tf([1],[1,0]), np.inf, 0),
1119+
('undamped', ct.tf([1],[1, 0, 144]), np.inf, 12),
1120+
('zero', ct.tf([0],[1, 0, 144]), 0, 0),
1121+
])
1122+
def test_linfnorm_siso_continuoustime(self, name, sys, refgpeak, reffpeak):
1123+
gpeak, fpeak = linfnorm(sys)
1124+
np.testing.assert_allclose(gpeak, refgpeak)
1125+
np.testing.assert_allclose(fpeak, reffpeak)
1126+
1127+
1128+
# these are the continuous-time examples with some tweaks
1129+
@slycotonly
1130+
@pytest.mark.parametrize(
1131+
"name, sys, refgpeak, reffpeak",
1132+
[
1133+
('lpf', ct.c2d(ct.tf([1],[1,1]), 0.1), 1, 0),
1134+
('static', ct.c2d(ct.tf([1.23],[1]), 0.1), 1.23, 0),
1135+
# the gain and frequency don't quite match the continuous-time case,
1136+
# I assume due to c2d imperfection
1137+
('underdamped', ct.c2d(ct.tf([100],[1, 2*0.1*10, 100]), 0.01), 5.023137, 9.899412),
1138+
# The HPF fpeak is the Nyquist frequency
1139+
# Assume gpeak mismatch is again c2d mismatch
1140+
('hpf', ct.c2d(ct.tf([1, 0], [1, 1]), 0.1), 1.04995845, np.pi * 10),
1141+
('integrator', ct.c2d(ct.tf([1],[1,0]), 0.1), np.inf, 0),
1142+
('undamped', ct.c2d(ct.tf([1],[1, 0, 144]), 0.003), np.inf, 12),
1143+
# ss call works around Scipy's "Badly conditioned filter coefficients" warning
1144+
('zero', ct.c2d(ct.ss(ct.tf([0],[1, 0, 144])), 0.003), 0, 0),
1145+
])
1146+
def test_linfnorm_siso_discretetime(self, name, sys, refgpeak, reffpeak):
1147+
gpeak, fpeak = linfnorm(sys)
1148+
np.testing.assert_allclose(gpeak, refgpeak)
1149+
np.testing.assert_allclose(fpeak, reffpeak)
1150+
1151+
1152+
@slycotonly
1153+
def test_linfnorm_mimo_continuoustime(self, continuous_time_mimo):
1154+
sys, refgpeak, reffpeak = continuous_time_mimo
1155+
gpeak, fpeak = linfnorm(sys)
1156+
np.testing.assert_allclose(gpeak, refgpeak)
1157+
np.testing.assert_allclose(fpeak, reffpeak)
1158+
1159+
@slycotonly
1160+
def test_linfnorm_mimo_discretetime(self, discrete_time_mimo):
1161+
sys, refgpeak, reffpeak = discrete_time_mimo
1162+
gpeak, fpeak = linfnorm(sys)
1163+
np.testing.assert_allclose(gpeak, refgpeak)
1164+
np.testing.assert_allclose(fpeak, reffpeak)
1165+
1166+
@slycotonly
1167+
def test_linfnorm_notimebase(self):
1168+
g = ct.ss(-0.1,1,1,0,dt=None)
1169+
with pytest.raises(ValueError):
1170+
linfnorm(g)

0 commit comments

Comments
 (0)
0