8000 Merge pull request #615 from bnavigator/py39-float-tests · python-control/python-control@a6a5bee · GitHub
[go: up one dir, main page]

Skip to content

Commit a6a5bee

Browse files
authored
Merge pull request #615 from bnavigator/py39-float-tests
allow float precision in result assertions
2 parents e81f648 + 8a56d67 commit a6a5bee

11 files changed

+126
-128
lines changed

control/tests/convert_test.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,7 @@ def testTf2ssStaticSiso(self):
184184
assert 0 == gsiso.nstates
185185
assert 1 == gsiso.ninputs
186186
assert 1 == gsiso.noutputs
187-
# in all cases ratios are exactly representable, so assert_array_equal
188-
# is fine
189-
np.testing.assert_array_equal([[0.5]], gsiso.D)
187+
np.testing.assert_allclose([[0.5]], gsiso.D)
190188

191189
def testTf2ssStaticMimo(self):
192190
"""Regression: tf2ss for MIMO static gain"""
@@ -198,13 +196,13 @@ def testTf2ssStaticMimo(self):
198196
assert 3 == gmimo.ninputs
199197
assert 2 == gmimo.noutputs
200198
d = np.array([[0.5, 30, 0.0625], [-0.5, -1.25, 101.3]])
201-
np.testing.assert_array_equal(d, gmimo.D)
199+
np.testing.assert_allclose(d, gmimo.D)
202 F438 200

203201
def testSs2tfStaticSiso(self):
204202
"""Regression: ss2tf for SISO static gain"""
205203
gsiso = ss2tf(ss([], [], [], 0.5))
206-
np.testing.assert_array_equal([[[0.5]]], gsiso.num)
207-
np.testing.assert_array_equal([[[1.]]], gsiso.den)
204+
np.testing.assert_allclose([[[0.5]]], gsiso.num)
205+
np.testing.assert_allclose([[[1.]]], gsiso.den)
208206

209207
def testSs2tfStaticMimo(self):
210208
"""Regression: ss2tf for MIMO static gain"""
@@ -217,8 +215,8 @@ def testSs2tfStaticMimo(self):
217215

218216
# we need a 3x2x1 array to compare with gtf.num
219217
numref = d[..., np.newaxis]
220-
np.testing.assert_array_equal(numref,
221-
np.array(gtf.num) / np.array(gtf.den))
218+
np.testing.assert_allclose(numref,
219+
np.array(gtf.num) / np.array(gtf.den))
222220

223221
@slycotonly
224222
def testTf2SsDuplicatePoles(self):
@@ -229,7 +227,7 @@ def testTf2SsDuplicatePoles(self):
229227
[[1], [1, 0]]]
230228
g = tf(num, den)
231229
s = ss(g)
232-
np.testing.assert_array_equal(g.pole(), s.pole())
230+
np.testing.assert_allclose(g.pole(), s.pole())
233231

234232
@slycotonly
235233
def test_tf2ss_robustness(self):

control/tests/descfcn_test.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,26 @@ def test_static_nonlinear_call(satsys):
5353
input = [-2, -1, -0.5, 0, 0.5, 1, 2]
5454
desired = [-1, -1, -0.5, 0, 0.5, 1, 1]
5555
for x, y in zip(input, desired):
56-
assert satsys(x) == y
56+
np.testing.assert_allclose(satsys(x), y)
5757

5858
# Test squeeze properties
5959
assert satsys(0.) == 0.
6060
assert satsys([0.], squeeze=True) == 0.
61-
np.testing.assert_array_equal(satsys([0.]), [0.])
61+
np.testing.assert_allclose(satsys([0.]), [0.])
6262

6363
# Test SIMO nonlinearity
6464
def _simofcn(t, x, u, params):
6565
return np.array([np.cos(u), np.sin(u)])
6666
simo_sys = ct.NonlinearIOSystem(None, outfcn=_simofcn, input=1, output=2)
67-
np.testing.assert_array_equal(simo_sys([0.]), [1, 0])
68-
np.testing.assert_array_equal(simo_sys([0.], squeeze=True), [1, 0])
67+
np.testing.assert_allclose(simo_sys([0.]), [1, 0])
68+
np.testing.assert_allclose(simo_sys([0.], squeeze=True), [1, 0])
6969

7070
# Test MISO nonlinearity
7171
def _misofcn(t, x, u, params={}):
7272
return np.array([np.sin(u[0]) * np.cos(u[1])])
7373
miso_sys = ct.NonlinearIOSystem(None, outfcn=_misofcn, input=2, output=1)
74-
np.testing.assert_array_equal(miso_sys([0, 0]), [0])
75-
np.testing.assert_array_equal(miso_sys([0, 0], squeeze=True), [0])
74+
np.testing.assert_allclose(miso_sys([0, 0]), [0])
75+
np.testing.assert_allclose(miso_sys([0, 0], squeeze=True), [0])
7676

7777

7878
# Test saturation describing function in multiple ways

control/tests/interconnect_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ def test_summing_junction(inputs, output, dimension, D):
3636
sum = ct.summing_junction(
3737
inputs=inputs, output=output, dimension=dimension)
3838
dim = 1 if dimension is None else dimension
39-
np.testing.assert_array_equal(sum.A, np.ndarray((0, 0)))
40-
np.testing.assert_array_equal(sum.B, np.ndarray((0, ninputs*dim)))
41-
np.testing.assert_array_equal(sum.C, np.ndarray((dim, 0)))
42-
np.testing.assert_array_equal(sum.D, D)
39+
np.testing.assert_allclose(sum.A, np.ndarray((0, 0)))
40+
np.testing.assert_allclose(sum.B, np.ndarray((0, ninputs*dim)))
41+
np.testing.assert_allclose(sum.C, np.ndarray((dim, 0)))
42+
np.testing.< 10000 span class="pl-c1 x x-first x-last">assert_allclose(sum.D, D)
4343

4444

4545
def test_summation_exceptions():
@@ -96,7 +96,7 @@ def test_interconnect_implicit():
9696
# Setting connections to False should lead to an empty connection map
9797
empty = ct.interconnect(
9898
(C, P, sumblk), connections=False, inplist=['r'], outlist=['y'])
99-
np.testing.assert_array_equal(empty.connect_map, np.zeros((4, 3)))
99+
np.testing.assert_allclose(empty.connect_map, np.zeros((4, 3)))
100100

101101
# Implicit summation across repeated signals
102102
kp_io = ct.tf2io(kp, inputs='e', outputs='u', name='kp')

control/tests/iosys_test.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ def test_ss2io(self, tsys):
8989
# Create an input/output system from the linear system
9090
linsys = tsys.siso_linsys
9191
iosys = ct.ss2io(linsys)
92-
np.testing.assert_array_equal(linsys.A, iosys.A)
93-
np.testing.assert_array_equal(linsys.B, iosys.B)
94-
np.testing.assert_array_equal(linsys.C, iosys.C)
95-
np.testing.assert_array_equal(linsys.D, iosys.D)
92+
np.testing.assert_allclose(linsys.A, iosys.A)
93+
np.testing.assert_allclose(linsys.B, iosys.B)
94+
np.testing.assert_allclose(linsys.C, iosys.C)
95+
np.testing.assert_allclose(linsys.D, iosys.D)
9696

9797
# Try adding names to things
9898
iosys_named = ct.ss2io(linsys, inputs='u', outputs='y',
@@ -104,10 +104,10 @@ def test_ss2io(self, tsys):
104104
assert iosys_named.find_state('x0') is None
105105
assert iosys_named.find_state('x1') == 0
106106
assert iosys_named.find_state('x2') == 1
107-
np.testing.assert_array_equal(linsys.A, iosys_named.A)
108-
np.testing.assert_array_equal(linsys.B, iosys_named.B)
109-
np.testing.assert_array_equal(linsys.C, iosys_named.C)
110-
np.testing.assert_array_equal(linsys.D, iosys_named.D)
107+
np.testing.assert_allclose(linsys.A, iosys_named.A)
108+
np.testing.assert_allclose(linsys.B, iosys_named.B)
109+
np.testing.assert_allclose(linsys.C, iosys_named.C)
110+
np.testing.assert_allclose(linsys.D, iosys_named.D)
111111

112112
def test_iosys_unspecified(self, tsys):
113113
"""System with unspecified inputs and outputs"""
@@ -1132,14 +1132,14 @@ def test_lineariosys_statespace(self, tsys):
11321132
assert isinstance(iosys_siso, ct.StateSpace)
11331133

11341134
# Make sure that state space functions work for LinearIOSystems
1135-
np.testing.assert_array_equal(
1135+
np.testing.assert_allclose(
11361136
iosys_siso.pole(), tsys.siso_linsys.pole())
11371137
omega = np.logspace(.1, 10, 100)
11381138
mag_io, phase_io, omega_io = iosys_siso.frequency_response(omega)
11391139
mag_ss, phase_ss, omega_ss = tsys.siso_linsys.frequency_response(omega)
1140-
np.testing.assert_array_equal(mag_io, mag_ss)
1141-
np.testing.assert_array_equal(phase_io, phase_ss)
1142-
np.testing.assert_array_equal(omega_io, omega_ss)
1140+
np.testing.assert_allclose(mag_io, mag_ss)
1141+
np.testing.assert_allclose(phase_io, phase_ss)
1142+
np.testing.assert_allclose(omega_io, omega_ss)
11431143

11441144
# LinearIOSystem methods should override StateSpace methods
11451145
io_mul = iosys_siso * iosys_siso2
@@ -1150,19 +1150,19 @@ def test_lineariosys_statespace(self, tsys):
11501150

11511151
# And make sure the systems match
11521152
ss_series = tsys.siso_linsys * tsys.siso_linsys
1153-
np.testing.assert_array_equal(io_mul.A, ss_series.A)
1154-
np.testing.assert_array_equal(io_mul.B, ss_series.B)
1155-
np.testing.assert_array_equal(io_mul.C, ss_series.C)
1156-
np.testing.assert_array_equal(io_mul.D, ss_series.D)
1153+
np.testing.assert_allclose(io_mul.A, ss_series.A)
1154+
np.testing.assert_allclose(io_mul.B, ss_series.B)
1155+
np.testing.assert_allclose(io_mul.C, ss_series.C)
1156+
np.testing.assert_allclose(io_mul.D, ss_series.D)
11571157

11581158
# Make sure that series does the same thing
11591159
io_series = ct.series(iosys_siso, iosys_siso2)
11601160
assert isinstance(io_series, ct.InputOutputSystem)
11611161
assert isinstance(io_series, ct.StateSpace)
1162-
np.testing.assert_array_equal(io_series.A, ss_series.A)
1163-
np.testing.assert_array_equal(io_series.B, ss_series.B)
1164-
np.testing.assert_array_equal(io_series.C, ss_series.C)
1165-
np.testing.assert_array_equal(io_series.D, ss_series.D)
1162+
np.testing.assert_allclose(io_series.A, ss_series.A)
1163+
np.testing.assert_allclose(io_series.B, ss_series.B)
1164+
np.testing.assert_allclose(io_series.C, ss_series.C)
1165+
np.testing.assert_allclose(io_series.D, ss_series.D)
11661166

11671167
# Test out feedback as well
11681168
io_feedback = ct.feedback(iosys_siso, iosys_siso2)
@@ -1173,10 +1173,10 @@ def test_lineariosys_statespace(self, tsys):
11731173

11741174
# And make sure the systems match
11751175
ss_feedback = ct.feedback(tsys.siso_linsys, tsys.siso_linsys)
1176-
np.testing.assert_array_equal(io_feedback.A, ss_feedback.A)
1177-
np.testing.assert_array_equal(io_feedback.B, ss_feedback.B)
1178-
np.testing.assert_array_equal(io_feedback.C, ss_feedback.C)
1179-
np.testing.assert_array_equal(io_feedback.D, ss_feedback.D)
1176+
np.testing.assert_allclose(io_feedback.A, ss_feedback.A)
1177+
np.testing.assert_allclose(io_feedback.B, ss_feedback.B)
1178+
np.testing.assert_allclose(io_feedback.C, ss_feedback.C)
1179+
np.testing.assert_allclose(io_feedback.D, ss_feedback.D)
11801180

11811181
# Make sure series interconnections are done in the right order
11821182
ss_sys1 = ct.rss(2, 3, 2)
@@ -1190,10 +1190,10 @@ def test_lineariosys_statespace(self, tsys):
11901190

11911191
# While we are at it, check that the state space matrices match
11921192
ss_series = ss_sys2 * ss_sys1
1193-
np.testing.assert_array_equal(io_series.A, ss_series.A)
1194-
np.testing.assert_array_equal(io_series.B, ss_series.B)
1195-
np.testing.assert_array_equal(io_series.C, ss_series.C)
1196-
np.testing.assert_array_equal(io_series.D, ss_series.D)
1193+
np.testing.assert_allclose(io_series.A, ss_series.A)
1194+
np.testing.assert_allclose(io_series.B, ss_series.B)
1195+
np.testing.assert_allclose(io_series.C, ss_series.C)
1196+
np.testing.assert_allclose(io_series.D, ss_series.D)
11971197

11981198
def test_docstring_example(self):
11991199
P = ct.LinearIOSystem(

control/tests/lti_test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ class TestLTI:
1515

1616
def test_pole(self):
1717
sys = tf(126, [-1, 42])
18-
np.testing.assert_equal(sys.pole(), 42)
19-
np.testing.assert_equal(pole(sys), 42)
18+
np.testing.assert_allclose(sys.pole(), 42)
19+
np.testing.assert_allclose(pole(sys), 42)
2020

2121
def test_zero(self):
2222
sys = tf([-1, 42], [1, 10])
23-
np.testing.assert_equal(sys.zero(), 42)
24-
np.testing.assert_equal(zero(sys), 42)
23+
np.testing.assert_allclose(sys.zero(), 42)
24+
np.testing.assert_allclose(zero(sys), 42)
2525

2626
def test_issiso(self):
2727
assert issiso(1)
@@ -58,8 +58,8 @@ def test_damp(self):
5858
p = -wn * zeta + 1j * wn * np.sqrt(1 - zeta**2)
5959
sys = tf(1, [1, 2 * zeta * wn, wn**2])
6060
expected = ([wn, wn], [zeta, zeta], [p, p.conjugate()])
61-
np.testing.assert_equal(sys.damp(), expected)
62-
np.testing.assert_equal(damp(sys), expected)
61+
np.testing.assert_allclose(sys.damp(), expected)
62+
np.testing.assert_allclose(damp(sys), expected)
6363

6464
# Also test the discrete time case.
6565
dt = 0.001
@@ -72,8 +72,8 @@ def test_damp(self):
7272

7373
def test_dcgain(self):
7474
sys = tf(84, [1, 2])
75-
np.testing.assert_equal(sys.dcgain(), 42)
76-
np.testing.assert_equal(dcgain(sys), 42)
75+
np.testing.assert_allclose(sys.dcgain(), 42)
76+
np.testing.assert_allclose(dcgain(sys), 42)
7777

7878
@pytest.mark.parametrize("dt1, dt2, expected",
7979
[(None, None, True),

control/tests/matlab_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ def testRlocus_list(self, siso, mplcleanup):
420420
klist = [1, 10, 100]
421421
rlist, klist_out = rlocus(siso.tf2, klist, plot=False)
422422
np.testing.assert_equal(len(rlist), len(klist))
423-
np.testing.assert_array_equal(klist, klist_out)
423+
np.testing.assert_allclose(klist, klist_out)
424424

425425
def testNyquist(self, siso):
426426
"""Call nyquist()"""

control/tests/rlocus_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def testRootLocus(self, sys):
4242

4343
roots, k_out = root_locus(sys, klist, plot=False)
4444
np.testing.assert_equal(len(roots), len(klist))
45-
np.testing.assert_array_equal(klist, k_out)
45+
np.testing.assert_allclose(klist, k_out)
4646
self.check_cl_poles(sys, roots, klist)
4747

4848
def test_without_gains(self, sys):

control/tests/statesp_test.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ def test_copy_constructor(self):
172172

173173
# Change the original A matrix
174174
A[0, 0] = -2
175-
np.testing.assert_array_equal(linsys.A, [[-1]]) # original value
176-
np.testing.assert_array_equal(cpysys.A, [[-1]]) # original value
175+
np.testing.assert_allclose(linsys.A, [[-1]]) # original value
176+
np.testing.assert_allclose(cpysys.A, [[-1]]) # original value
177177

178178
# Change the A matrix for the original system
179179
linsys.A[0, 0] = -3
180-
np.testing.assert_array_equal(cpysys.A, [[-1]]) # original value
180+
np.testing.assert_allclose(cpysys.A, [[-1]]) # original value
181181

182182
def test_copy_constructor_nodt(self, sys322):
183183
"""Test the copy constructor when an object without dt is passed"""
@@ -207,24 +207,24 @@ def test_D_broadcast(self, sys623):
207207
"""Test broadcast of D=0 to the right shape"""
208208
# Giving D as a scalar 0 should broadcast to the right shape
209209
sys = StateSpace(sys623.A, sys623.B, sys623.C, 0)
210-
np.testing.assert_array_equal(sys623.D, sys.D)
210+
np.testing.assert_allclose(sys623.D, sys.D)
211211

212212
# Giving D as a matrix of the wrong size should generate an error
213213
with pytest.raises(ValueError):
214214
sys = StateSpace(sys.A, sys.B, sys.C, np.array([[0]]))
215215

216216
# Make sure that empty systems still work
217217
sys = StateSpace([], [], [], 1)
218-
np.testing.assert_array_equal(sys.D, [[1]])
218+
np.testing.assert_allclose(sys.D, [[1]])
219219

220220
sys = StateSpace([], [], [], [[0]])
221-
np.testing.assert_array_equal(sys.D, [[0]])
221+
np.testing.assert_allclose(sys.D, [[0]])
222222

223223
sys = StateSpace([], [], [], [0])
224-
np.testing.assert_array_equal(sys.D, [[0]])
224+
np.testing.assert_allclose(sys.D, [[0]])
225225

226226
sys = StateSpace([], [], [], 0)
227-
np.testing.assert_array_equal(sys.D, [[0]])
227+
np.testing.assert_allclose(sys.D, [[0]])
228228

229229
def test_pole(self, sys322):
230230
"""Evaluate the poles of a MIMO system."""
@@ -388,7 +388,7 @@ def test_freq_resp(self):
388388

389389
np.testing.assert_almost_equal(mag, true_mag)
390390
np.testing.assert_almost_equal(phase, true_phase)
391-
np.testing.assert_equal(omega, true_omega)
391+
np.testing.assert_almost_equal(omega, true_omega)
392392

393393
# Deprecated version of the call (should return warning)
394394
with pytest.warns(DeprecationWarning, match="will be removed"):
@@ -516,15 +516,15 @@ def test_dc_gain_discr(self):
516516
"""Test DC gain for discrete-time state-space systems."""
517517
# static gain
518518
sys = StateSpace([], [], [], 2, True)
519-
np.testing.assert_equal(sys.dcgain(), 2)
519+
np.testing.assert_allclose(sys.dcgain(), 2)
520520

521521
# averaging filter
522522
sys = StateSpace(0.5, 0.5, 1, 0, True)
523523
np.testing.assert_allclose(sys.dcgain(), 1)
524524

525525
# differencer
526526
sys = StateSpace(0, 1, -1, 1, True)
527-
np.testing.assert_equal(sys.dcgain(), 0)
527+
np.testing.assert_allclose(sys.dcgain(), 0)
528528

529529
# summer
530530
sys = StateSpace(1, 1, 1, 0, True)
@@ -592,14 +592,14 @@ def test_matrix_static_gain(self):
592592
g3 = StateSpace([], [], [], d2.T)
593593

594594
h1 = g1 * g2
595-
np.testing.assert_array_equal(np.dot(d1, d2), h1.D)
595+
np.testing.assert_allclose(np.dot(d1, d2), h1.D)
596596
h2 = g1 + g3
597-
np.testing.assert_array_equal(d1 + d2.T, h2.D)
597+
np.testing.assert_allclose(d1 + d2.T, h2.D)
598598
h3 = g1.feedback(g2)
599599
np.testing.assert_array_almost_equal(
600600
solve(np.eye(2) + np.dot(d1, d2), d1), h3.D)
601601
h4 = g1.append(g2)
602-
np.testing.assert_array_equal(block_diag(d1, d2), h4.D)
602+
np.testing.assert_allclose(block_diag(d1, d2), h4.D)
603603

604604
def test_remove_useless_states(self):
605605
"""Regression: _remove_useless_states gives correct ABC sizes."""
@@ -633,7 +633,7 @@ def test_minreal_static_gain(self):
633633
np.testing.assert_array_equal(g1.A, g2.A)
634634
np.testing.assert_array_equal(g1.B, g2.B)
635635
np.testing.assert_array_equal(g1.C, g2.C)
636-
np.testing.assert_array_equal(g1.D, g2.D)
636+
np.testing.assert_allclose(g1.D, g2.D)
637637

638638
def test_empty(self):
639639
"""Regression: can we create an empty StateSpace object?"""
@@ -651,7 +651,7 @@ def test_matrix_to_state_space(self):
651651
np.testing.assert_array_equal(np.empty((0, 0)), g.A)
652652
np.testing.assert_array_equal(np.empty((0, D.shape[1])), g.B)
653653
np.testing.assert_array_equal(np.empty((D.shape[0], 0)), g.C)
654-
np.testing.assert_array_equal(D, g.D)
654+
np.testing.assert_allclose(D, g.D)
655655

656656
def test_lft(self):
657657
""" test lft function with result obtained from matlab implementation"""

control/tests/timeresp_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ def test_step_nostates(self, dt):
364364
"""
365365
sys = TransferFunction([1], [1], dt)
366366
t, y = step_response(sys)
367-
np.testing.assert_array_equal(y, np.ones(len(t)))
367+
np.testing.assert_allclose(y, np.ones(len(t)))
368368

369369
def assert_step_info_match(self, sys, info, info_ref):
370370
"""Assert reasonable step_info accuracy."""

control/tests/xferfcn_input_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_clean_part(num, fun, dtype):
6969
for i, numi in enumerate(num_):
7070
assert len(numi) == ref_.shape[1]
7171
for j, numj in enumerate(numi):
72-
np.testing.assert_array_equal(numj, ref_[i, j, ...])
72+
np.testing.assert_allclose(numj, ref_[i, j, ...])
7373

7474

7575
@pytest.mark.parametrize("badinput", [[[0., 1.], [2., 3.]], "a"])

0 commit comments

Comments
 (0)
0