From e3b964bd5c7c518b7e1c36e047d48c772aca6625 Mon Sep 17 00:00:00 2001 From: Ben Greiner Date: Sat, 24 Apr 2021 10:42:42 +0200 Subject: [PATCH 1/3] allow float precision in test_damp --- control/tests/lti_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/control/tests/lti_test.py b/control/tests/lti_test.py index d4d5ec786..15e622d5d 100644 --- a/control/tests/lti_test.py +++ b/control/tests/lti_test.py @@ -58,8 +58,8 @@ def test_damp(self): p = -wn * zeta + 1j * wn * np.sqrt(1 - zeta**2) sys = tf(1, [1, 2 * zeta * wn, wn**2]) expected = ([wn, wn], [zeta, zeta], [p, p.conjugate()]) - np.testing.assert_equal(sys.damp(), expected) - np.testing.assert_equal(damp(sys), expected) + np.testing.assert_allclose(sys.damp(), expected) + np.testing.assert_allclose(damp(sys), expected) # Also test the discrete time case. dt = 0.001 From 13f2ce132d12b5329055ce86ce7fbd73e82efb54 Mon Sep 17 00:00:00 2001 From: Ben Greiner Date: Sat, 24 Apr 2021 10:54:27 +0200 Subject: [PATCH 2/3] replace more assert_equal comparing possible float results --- control/tests/lti_test.py | 12 ++++++------ control/tests/matlab_test.py | 2 +- control/tests/rlocus_test.py | 2 +- control/tests/statesp_test.py | 6 +++--- control/tests/xferfcn_test.py | 12 ++++++------ 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/control/tests/lti_test.py b/control/tests/lti_test.py index 15e622d5d..9156ecb7e 100644 --- a/control/tests/lti_test.py +++ b/control/tests/lti_test.py @@ -15,13 +15,13 @@ class TestLTI: def test_pole(self): sys = tf(126, [-1, 42]) - np.testing.assert_equal(sys.pole(), 42) - np.testing.assert_equal(pole(sys), 42) + np.testing.assert_allclose(sys.pole(), 42) + np.testing.assert_allclose(pole(sys), 42) def test_zero(self): sys = tf([-1, 42], [1, 10]) - np.testing.assert_equal(sys.zero(), 42) - np.testing.assert_equal(zero(sys), 42) + np.testing.assert_allclose(sys.zero(), 42) + np.testing.assert_allclose(zero(sys), 42) def test_issiso(self): assert issiso(1) @@ -72,8 +72,8 @@ def test_damp(self): def test_dcgain(self): sys = tf(84, [1, 2]) - np.testing.assert_equal(sys.dcgain(), 42) - np.testing.assert_equal(dcgain(sys), 42) + np.testing.assert_allclose(sys.dcgain(), 42) + np.testing.assert_allclose(dcgain(sys), 42) @pytest.mark.parametrize("dt1, dt2, expected", [(None, None, True), diff --git a/control/tests/matlab_test.py b/control/tests/matlab_test.py index 61bc3bdcb..6957e0bfe 100644 --- a/control/tests/matlab_test.py +++ b/control/tests/matlab_test.py @@ -420,7 +420,7 @@ def testRlocus_list(self, siso, mplcleanup): klist = [1, 10, 100] rlist, klist_out = rlocus(siso.tf2, klist, plot=False) np.testing.assert_equal(len(rlist), len(klist)) - np.testing.assert_array_equal(klist, klist_out) + np.testing.assert_allclose(klist, klist_out) def testNyquist(self, siso): """Call nyquist()""" diff --git a/control/tests/rlocus_test.py b/control/tests/rlocus_test.py index aa25cd2b7..f7aff9ebe 100644 --- a/control/tests/rlocus_test.py +++ b/control/tests/rlocus_test.py @@ -42,7 +42,7 @@ def testRootLocus(self, sys): roots, k_out = root_locus(sys, klist, plot=False) np.testing.assert_equal(len(roots), len(klist)) - np.testing.assert_array_equal(klist, k_out) + np.testing.assert_allclose(klist, k_out) self.check_cl_poles(sys, roots, klist) def test_without_gains(self, sys): diff --git a/control/tests/statesp_test.py b/control/tests/statesp_test.py index 71e7cc4bc..93d397d9a 100644 --- a/control/tests/statesp_test.py +++ b/control/tests/statesp_test.py @@ -388,7 +388,7 @@ def test_freq_resp(self): np.testing.assert_almost_equal(mag, true_mag) np.testing.assert_almost_equal(phase, true_phase) - np.testing.assert_equal(omega, true_omega) + np.testing.assert_almost_equal(omega, true_omega) # Deprecated version of the call (should return warning) with pytest.warns(DeprecationWarning, match="will be removed"): @@ -516,7 +516,7 @@ def test_dc_gain_discr(self): """Test DC gain for discrete-time state-space systems.""" # static gain sys = StateSpace([], [], [], 2, True) - np.testing.assert_equal(sys.dcgain(), 2) + np.testing.assert_allclose(sys.dcgain(), 2) # averaging filter sys = StateSpace(0.5, 0.5, 1, 0, True) @@ -524,7 +524,7 @@ def test_dc_gain_discr(self): # differencer sys = StateSpace(0, 1, -1, 1, True) - np.testing.assert_equal(sys.dcgain(), 0) + np.testing.assert_allclose(sys.dcgain(), 0) # summer sys = StateSpace(1, 1, 1, 0, True) diff --git a/control/tests/xferfcn_test.py b/control/tests/xferfcn_test.py index 06e7fc9d8..29f6b034a 100644 --- a/control/tests/xferfcn_test.py +++ b/control/tests/xferfcn_test.py @@ -693,8 +693,8 @@ def test_minreal_4(self): h = (z - 1.00000000001) * (z + 1.0000000001) / (z**2 - 1) hm = h.minreal() hr = TransferFunction([1], [1], T) - np.testing.assert_array_almost_equal(hm.num[0][0], hr.num[0][0]) - np.testing.assert_equal(hr.dt, hm.dt) + np.testing.assert_allclose(hm.num[0][0], hr.num[0][0]) + np.testing.assert_allclose(hr.dt, hm.dt) @slycotonly def test_state_space_conversion_mimo(self): @@ -801,10 +801,10 @@ def test_matrix_array_multiply(self, matarrayin, X_, ij): def test_dcgain_cont(self): """Test DC gain for continuous-time transfer functions""" sys = TransferFunction(6, 3) - np.testing.assert_equal(sys.dcgain(), 2) + np.testing.assert_allclose(sys.dcgain(), 2) sys2 = TransferFunction(6, [1, 3]) - np.testing.assert_equal(sys2.dcgain(), 2) + np.testing.assert_allclose(sys2.dcgain(), 2) sys3 = TransferFunction(6, [1, 0]) np.testing.assert_equal(sys3.dcgain(), np.inf) @@ -819,7 +819,7 @@ def test_dcgain_discr(self): """Test DC gain for discrete-time transfer functions""" # static gain sys = TransferFunction(6, 3, True) - np.testing.assert_equal(sys.dcgain(), 2) + np.testing.assert_allclose(sys.dcgain(), 2) # averaging filter sys = TransferFunction(0.5, [1, -0.5], True) @@ -837,7 +837,7 @@ def test_dcgain_discr(self): # summer sys = TransferFunction([1, -1], [1], True) - np.testing.assert_equal(sys.dcgain(), 0) + np.testing.assert_allclose(sys.dcgain(), 0) def test_ss2tf(self): """Test SISO ss2tf""" From 8a56d677838e2359015cb4d092db71ee4df27601 Mon Sep 17 00:00:00 2001 From: Ben Greiner Date: Sat, 24 Apr 2021 11:16:12 +0200 Subject: [PATCH 3/3] replace assert_array_equal comparing possible float results --- control/tests/convert_test.py | 16 +++-- control/tests/descfcn_test.py | 12 ++-- control/tests/interconnect_test.py | 10 ++-- control/tests/iosys_test.py | 56 +++++++++--------- control/tests/statesp_test.py | 26 ++++---- control/tests/timeresp_test.py | 2 +- control/tests/xferfcn_input_test.py | 2 +- control/tests/xferfcn_test.py | 92 ++++++++++++++--------------- 8 files changed, 107 insertions(+), 109 deletions(-) diff --git a/control/tests/convert_test.py b/control/tests/convert_test.py index d5d4cbfab..7570b07b4 100644 --- a/control/tests/convert_test.py +++ b/control/tests/convert_test.py @@ -184,9 +184,7 @@ def testTf2ssStaticSiso(self): assert 0 == gsiso.nstates assert 1 == gsiso.ninputs assert 1 == gsiso.noutputs - # in all cases ratios are exactly representable, so assert_array_equal - # is fine - np.testing.assert_array_equal([[0.5]], gsiso.D) + np.testing.assert_allclose([[0.5]], gsiso.D) def testTf2ssStaticMimo(self): """Regression: tf2ss for MIMO static gain""" @@ -198,13 +196,13 @@ def testTf2ssStaticMimo(self): assert 3 == gmimo.ninputs assert 2 == gmimo.noutputs d = np.array([[0.5, 30, 0.0625], [-0.5, -1.25, 101.3]]) - np.testing.assert_array_equal(d, gmimo.D) + np.testing.assert_allclose(d, gmimo.D) def testSs2tfStaticSiso(self): """Regression: ss2tf for SISO static gain""" gsiso = ss2tf(ss([], [], [], 0.5)) - np.testing.assert_array_equal([[[0.5]]], gsiso.num) - np.testing.assert_array_equal([[[1.]]], gsiso.den) + np.testing.assert_allclose([[[0.5]]], gsiso.num) + np.testing.assert_allclose([[[1.]]], gsiso.den) def testSs2tfStaticMimo(self): """Regression: ss2tf for MIMO static gain""" @@ -217,8 +215,8 @@ def testSs2tfStaticMimo(self): # we need a 3x2x1 array to compare with gtf.num numref = d[..., np.newaxis] - np.testing.assert_array_equal(numref, - np.array(gtf.num) / np.array(gtf.den)) + np.testing.assert_allclose(numref, + np.array(gtf.num) / np.array(gtf.den)) @slycotonly def testTf2SsDuplicatePoles(self): @@ -229,7 +227,7 @@ def testTf2SsDuplicatePoles(self): [[1], [1, 0]]] g = tf(num, den) s = ss(g) - np.testing.assert_array_equal(g.pole(), s.pole()) + np.testing.assert_allclose(g.pole(), s.pole()) @slycotonly def test_tf2ss_robustness(self): diff --git a/control/tests/descfcn_test.py b/control/tests/descfcn_test.py index d26e2c67a..796ad9034 100644 --- a/control/tests/descfcn_test.py +++ b/control/tests/descfcn_test.py @@ -53,26 +53,26 @@ def test_static_nonlinear_call(satsys): input = [-2, -1, -0.5, 0, 0.5, 1, 2] desired = [-1, -1, -0.5, 0, 0.5, 1, 1] for x, y in zip(input, desired): - assert satsys(x) == y + np.testing.assert_allclose(satsys(x), y) # Test squeeze properties assert satsys(0.) == 0. assert satsys([0.], squeeze=True) == 0. - np.testing.assert_array_equal(satsys([0.]), [0.]) + np.testing.assert_allclose(satsys([0.]), [0.]) # Test SIMO nonlinearity def _simofcn(t, x, u, params): return np.array([np.cos(u), np.sin(u)]) simo_sys = ct.NonlinearIOSystem(None, outfcn=_simofcn, input=1, output=2) - np.testing.assert_array_equal(simo_sys([0.]), [1, 0]) - np.testing.assert_array_equal(simo_sys([0.], squeeze=True), [1, 0]) + np.testing.assert_allclose(simo_sys([0.]), [1, 0]) + np.testing.assert_allclose(simo_sys([0.], squeeze=True), [1, 0]) # Test MISO nonlinearity def _misofcn(t, x, u, params={}): return np.array([np.sin(u[0]) * np.cos(u[1])]) miso_sys = ct.NonlinearIOSystem(None, outfcn=_misofcn, input=2, output=1) - np.testing.assert_array_equal(miso_sys([0, 0]), [0]) - np.testing.assert_array_equal(miso_sys([0, 0], squeeze=True), [0]) + np.testing.assert_allclose(miso_sys([0, 0]), [0]) + np.testing.assert_allclose(miso_sys([0, 0], squeeze=True), [0]) # Test saturation describing function in multiple ways diff --git a/control/tests/interconnect_test.py b/control/tests/interconnect_test.py index 302c45278..c927bf0f6 100644 --- a/control/tests/interconnect_test.py +++ b/control/tests/interconnect_test.py @@ -36,10 +36,10 @@ def test_summing_junction(inputs, output, dimension, D): sum = ct.summing_junction( inputs=inputs, output=output, dimension=dimension) dim = 1 if dimension is None else dimension - np.testing.assert_array_equal(sum.A, np.ndarray((0, 0))) - np.testing.assert_array_equal(sum.B, np.ndarray((0, ninputs*dim))) - np.testing.assert_array_equal(sum.C, np.ndarray((dim, 0))) - np.testing.assert_array_equal(sum.D, D) + np.testing.assert_allclose(sum.A, np.ndarray((0, 0))) + np.testing.assert_allclose(sum.B, np.ndarray((0, ninputs*dim))) + np.testing.assert_allclose(sum.C, np.ndarray((dim, 0))) + np.testing.assert_allclose(sum.D, D) def test_summation_exceptions(): @@ -96,7 +96,7 @@ def test_interconnect_implicit(): # Setting connections to False should lead to an empty connection map empty = ct.interconnect( (C, P, sumblk), connections=False, inplist=['r'], outlist=['y']) - np.testing.assert_array_equal(empty.connect_map, np.zeros((4, 3))) + np.testing.assert_allclose(empty.connect_map, np.zeros((4, 3))) # Implicit summation across repeated signals kp_io = ct.tf2io(kp, inputs='e', outputs='u', name='kp') diff --git a/control/tests/iosys_test.py b/control/tests/iosys_test.py index 9a15e83f4..c1c4d8006 100644 --- a/control/tests/iosys_test.py +++ b/control/tests/iosys_test.py @@ -89,10 +89,10 @@ def test_ss2io(self, tsys): # Create an input/output system from the linear system linsys = tsys.siso_linsys iosys = ct.ss2io(linsys) - np.testing.assert_array_equal(linsys.A, iosys.A) - np.testing.assert_array_equal(linsys.B, iosys.B) - np.testing.assert_array_equal(linsys.C, iosys.C) - np.testing.assert_array_equal(linsys.D, iosys.D) + np.testing.assert_allclose(linsys.A, iosys.A) + np.testing.assert_allclose(linsys.B, iosys.B) + np.testing.assert_allclose(linsys.C, iosys.C) + np.testing.assert_allclose(linsys.D, iosys.D) # Try adding names to things iosys_named = ct.ss2io(linsys, inputs='u', outputs='y', @@ -104,10 +104,10 @@ def test_ss2io(self, tsys): assert iosys_named.find_state('x0') is None assert iosys_named.find_state('x1') == 0 assert iosys_named.find_state('x2') == 1 - np.testing.assert_array_equal(linsys.A, iosys_named.A) - np.testing.assert_array_equal(linsys.B, iosys_named.B) - np.testing.assert_array_equal(linsys.C, iosys_named.C) - np.testing.assert_array_equal(linsys.D, iosys_named.D) + np.testing.assert_allclose(linsys.A, iosys_named.A) + np.testing.assert_allclose(linsys.B, iosys_named.B) + np.testing.assert_allclose(linsys.C, iosys_named.C) + np.testing.assert_allclose(linsys.D, iosys_named.D) def test_iosys_unspecified(self, tsys): """System with unspecified inputs and outputs""" @@ -1132,14 +1132,14 @@ def test_lineariosys_statespace(self, tsys): assert isinstance(iosys_siso, ct.StateSpace) # Make sure that state space functions work for LinearIOSystems - np.testing.assert_array_equal( + np.testing.assert_allclose( iosys_siso.pole(), tsys.siso_linsys.pole()) omega = np.logspace(.1, 10, 100) mag_io, phase_io, omega_io = iosys_siso.frequency_response(omega) mag_ss, phase_ss, omega_ss = tsys.siso_linsys.frequency_response(omega) - np.testing.assert_array_equal(mag_io, mag_ss) - np.testing.assert_array_equal(phase_io, phase_ss) - np.testing.assert_array_equal(omega_io, omega_ss) + np.testing.assert_allclose(mag_io, mag_ss) + np.testing.assert_allclose(phase_io, phase_ss) + np.testing.assert_allclose(omega_io, omega_ss) # LinearIOSystem methods should override StateSpace methods io_mul = iosys_siso * iosys_siso2 @@ -1150,19 +1150,19 @@ def test_lineariosys_statespace(self, tsys): # And make sure the systems match ss_series = tsys.siso_linsys * tsys.siso_linsys - np.testing.assert_array_equal(io_mul.A, ss_series.A) - np.testing.assert_array_equal(io_mul.B, ss_series.B) - np.testing.assert_array_equal(io_mul.C, ss_series.C) - np.testing.assert_array_equal(io_mul.D, ss_series.D) + np.testing.assert_allclose(io_mul.A, ss_series.A) + np.testing.assert_allclose(io_mul.B, ss_series.B) + np.testing.assert_allclose(io_mul.C, ss_series.C) + np.testing.assert_allclose(io_mul.D, ss_series.D) # Make sure that series does the same thing io_series = ct.series(iosys_siso, iosys_siso2) assert isinstance(io_series, ct.InputOutputSystem) assert isinstance(io_series, ct.StateSpace) - np.testing.assert_array_equal(io_series.A, ss_series.A) - np.testing.assert_array_equal(io_series.B, ss_series.B) - np.testing.assert_array_equal(io_series.C, ss_series.C) - np.testing.assert_array_equal(io_series.D, ss_series.D) + np.testing.assert_allclose(io_series.A, ss_series.A) + np.testing.assert_allclose(io_series.B, ss_series.B) + np.testing.assert_allclose(io_series.C, ss_series.C) + np.testing.assert_allclose(io_series.D, ss_series.D) # Test out feedback as well io_feedback = ct.feedback(iosys_siso, iosys_siso2) @@ -1173,10 +1173,10 @@ def test_lineariosys_statespace(self, tsys): # And make sure the systems match ss_feedback = ct.feedback(tsys.siso_linsys, tsys.siso_linsys) - np.testing.assert_array_equal(io_feedback.A, ss_feedback.A) - np.testing.assert_array_equal(io_feedback.B, ss_feedback.B) - np.testing.assert_array_equal(io_feedback.C, ss_feedback.C) - np.testing.assert_array_equal(io_feedback.D, ss_feedback.D) + np.testing.assert_allclose(io_feedback.A, ss_feedback.A) + np.testing.assert_allclose(io_feedback.B, ss_feedback.B) + np.testing.assert_allclose(io_feedback.C, ss_feedback.C) + np.testing.assert_allclose(io_feedback.D, ss_feedback.D) # Make sure series interconnections are done in the right order ss_sys1 = ct.rss(2, 3, 2) @@ -1190,10 +1190,10 @@ def test_lineariosys_statespace(self, tsys): # While we are at it, check that the state space matrices match ss_series = ss_sys2 * ss_sys1 - np.testing.assert_array_equal(io_series.A, ss_series.A) - np.testing.assert_array_equal(io_series.B, ss_series.B) - np.testing.assert_array_equal(io_series.C, ss_series.C) - np.testing.assert_array_equal(io_series.D, ss_series.D) + np.testing.assert_allclose(io_series.A, ss_series.A) + np.testing.assert_allclose(io_series.B, ss_series.B) + np.testing.assert_allclose(io_series.C, ss_series.C) + np.testing.assert_allclose(io_series.D, ss_series.D) def test_docstring_example(self): P = ct.LinearIOSystem( diff --git a/control/tests/statesp_test.py b/control/tests/statesp_test.py index 93d397d9a..762a74b5e 100644 --- a/control/tests/statesp_test.py +++ b/control/tests/statesp_test.py @@ -172,12 +172,12 @@ def test_copy_constructor(self): # Change the original A matrix A[0, 0] = -2 - np.testing.assert_array_equal(linsys.A, [[-1]]) # original value - np.testing.assert_array_equal(cpysys.A, [[-1]]) # original value + np.testing.assert_allclose(linsys.A, [[-1]]) # original value + np.testing.assert_allclose(cpysys.A, [[-1]]) # original value # Change the A matrix for the original system linsys.A[0, 0] = -3 - np.testing.assert_array_equal(cpysys.A, [[-1]]) # original value + np.testing.assert_allclose(cpysys.A, [[-1]]) # original value def test_copy_constructor_nodt(self, sys322): """Test the copy constructor when an object without dt is passed""" @@ -207,7 +207,7 @@ def test_D_broadcast(self, sys623): """Test broadcast of D=0 to the right shape""" # Giving D as a scalar 0 should broadcast to the right shape sys = StateSpace(sys623.A, sys623.B, sys623.C, 0) - np.testing.assert_array_equal(sys623.D, sys.D) + np.testing.assert_allclose(sys623.D, sys.D) # Giving D as a matrix of the wrong size should generate an error with pytest.raises(ValueError): @@ -215,16 +215,16 @@ def test_D_broadcast(self, sys623): # Make sure that empty systems still work sys = StateSpace([], [], [], 1) - np.testing.assert_array_equal(sys.D, [[1]]) + np.testing.assert_allclose(sys.D, [[1]]) sys = StateSpace([], [], [], [[0]]) - np.testing.assert_array_equal(sys.D, [[0]]) + np.testing.assert_allclose(sys.D, [[0]]) sys = StateSpace([], [], [], [0]) - np.testing.assert_array_equal(sys.D, [[0]]) + np.testing.assert_allclose(sys.D, [[0]]) sys = StateSpace([], [], [], 0) - np.testing.assert_array_equal(sys.D, [[0]]) + np.testing.assert_allclose(sys.D, [[0]]) def test_pole(self, sys322): """Evaluate the poles of a MIMO system.""" @@ -592,14 +592,14 @@ def test_matrix_static_gain(self): g3 = StateSpace([], [], [], d2.T) h1 = g1 * g2 - np.testing.assert_array_equal(np.dot(d1, d2), h1.D) + np.testing.assert_allclose(np.dot(d1, d2), h1.D) h2 = g1 + g3 - np.testing.assert_array_equal(d1 + d2.T, h2.D) + np.testing.assert_allclose(d1 + d2.T, h2.D) h3 = g1.feedback(g2) np.testing.assert_array_almost_equal( solve(np.eye(2) + np.dot(d1, d2), d1), h3.D) h4 = g1.append(g2) - np.testing.assert_array_equal(block_diag(d1, d2), h4.D) + np.testing.assert_allclose(block_diag(d1, d2), h4.D) def test_remove_useless_states(self): """Regression: _remove_useless_states gives correct ABC sizes.""" @@ -633,7 +633,7 @@ def test_minreal_static_gain(self): np.testing.assert_array_equal(g1.A, g2.A) np.testing.assert_array_equal(g1.B, g2.B) np.testing.assert_array_equal(g1.C, g2.C) - np.testing.assert_array_equal(g1.D, g2.D) + np.testing.assert_allclose(g1.D, g2.D) def test_empty(self): """Regression: can we create an empty StateSpace object?""" @@ -651,7 +651,7 @@ def test_matrix_to_state_space(self): np.testing.assert_array_equal(np.empty((0, 0)), g.A) np.testing.assert_array_equal(np.empty((0, D.shape[1])), g.B) np.testing.assert_array_equal(np.empty((D.shape[0], 0)), g.C) - np.testing.assert_array_equal(D, g.D) + np.testing.assert_allclose(D, g.D) def test_lft(self): """ test lft function with result obtained from matlab implementation""" diff --git a/control/tests/timeresp_test.py b/control/tests/timeresp_test.py index a91507a83..c74c0c06d 100644 --- a/control/tests/timeresp_test.py +++ b/control/tests/timeresp_test.py @@ -364,7 +364,7 @@ def test_step_nostates(self, dt): """ sys = TransferFunction([1], [1], dt) t, y = step_response(sys) - np.testing.assert_array_equal(y, np.ones(len(t))) + np.testing.assert_allclose(y, np.ones(len(t))) def assert_step_info_match(self, sys, info, info_ref): """Assert reasonable step_info accuracy.""" diff --git a/control/tests/xferfcn_input_test.py b/control/tests/xferfcn_input_test.py index 00024ba4c..46efbd257 100644 --- a/control/tests/xferfcn_input_test.py +++ b/control/tests/xferfcn_input_test.py @@ -69,7 +69,7 @@ def test_clean_part(num, fun, dtype): for i, numi in enumerate(num_): assert len(numi) == ref_.shape[1] for j, numj in enumerate(numi): - np.testing.assert_array_equal(numj, ref_[i, j, ...]) + np.testing.assert_allclose(numj, ref_[i, j, ...]) @pytest.mark.parametrize("badinput", [[[0., 1.], [2., 3.]], "a"]) diff --git a/control/tests/xferfcn_test.py b/control/tests/xferfcn_test.py index 29f6b034a..bd073e0f3 100644 --- a/control/tests/xferfcn_test.py +++ b/control/tests/xferfcn_test.py @@ -145,15 +145,15 @@ def test_truncate_coefficients_non_null_numerator(self): """Remove extraneous zeros in polynomial representations.""" sys1 = TransferFunction([0., 0., 1., 2.], [[[0., 0., 0., 3., 2., 1.]]]) - np.testing.assert_array_equal(sys1.num, [[[1., 2.]]]) - np.testing.assert_array_equal(sys1.den, [[[3., 2., 1.]]]) + np.testing.assert_allclose(sys1.num, [[[1., 2.]]]) + np.testing.assert_allclose(sys1.den, [[[3., 2., 1.]]]) def test_truncate_coefficients_null_numerator(self): """Remove extraneous zeros in polynomial representations.""" sys1 = TransferFunction([0., 0., 0.], 1.) - np.testing.assert_array_equal(sys1.num, [[[0.]]]) - np.testing.assert_array_equal(sys1.den, [[[1.]]]) + np.testing.assert_allclose(sys1.num, [[[0.]]]) + np.testing.assert_allclose(sys1.den, [[[1.]]]) # Tests for TransferFunction.__neg__ @@ -162,16 +162,16 @@ def test_reverse_sign_scalar(self): sys1 = TransferFunction(2., np.array([-3.])) sys2 = - sys1 - np.testing.assert_array_equal(sys2.num, [[[-2.]]]) - np.testing.assert_array_equal(sys2.den, [[[-3.]]]) + np.testing.assert_allclose(sys2.num, [[[-2.]]]) + np.testing.assert_allclose(sys2.den, [[[-3.]]]) def test_reverse_sign_siso(self): """Negate a SISO system.""" sys1 = TransferFunction([1., 3., 5], [1., 6., 2., -1.]) sys2 = - sys1 - np.testing.assert_array_equal(sys2.num, [[[-1., -3., -5.]]]) - np.testing.assert_array_equal(sys2.den, [[[1., 6., 2., -1.]]]) + np.testing.assert_allclose(sys2.num, [[[-1., -3., -5.]]]) + np.testing.assert_allclose(sys2.den, [[[1., 6., 2., -1.]]]) @slycotonly def test_reverse_sign_mimo(self): @@ -189,8 +189,8 @@ def test_reverse_sign_mimo(self): for i in range(sys3.noutputs): for j in range(sys3.ninputs): - np.testing.assert_array_equal(sys2.num[i][j], sys3.num[i][j]) - np.testing.assert_array_equal(sys2.den[i][j], sys3.den[i][j]) + np.testing.assert_allclose(sys2.num[i][j], sys3.num[i][j]) + np.testing.assert_allclose(sys2.den[i][j], sys3.den[i][j]) # Tests for TransferFunction.__add__ @@ -200,8 +200,8 @@ def test_add_scalar(self): sys2 = TransferFunction(np.array([2.]), [1.]) sys3 = sys1 + sys2 - np.testing.assert_array_equal(sys3.num, 3.) - np.testing.assert_array_equal(sys3.den, 1.) + np.testing.assert_allclose(sys3.num, 3.) + np.testing.assert_allclose(sys3.den, 1.) def test_add_siso(self): """Add two SISO systems.""" @@ -210,8 +210,8 @@ def test_add_siso(self): sys3 = sys1 + sys2 # If sys3.num is [[[0., 20., 4., -8.]]], then this is wrong! - np.testing.assert_array_equal(sys3.num, [[[20., 4., -8]]]) - np.testing.assert_array_equal(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) + np.testing.assert_allclose(sys3.num, [[[20., 4., -8]]]) + np.testing.assert_allclose(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) @slycotonly def test_add_mimo(self): @@ -235,8 +235,8 @@ def test_add_mimo(self): for i in range(sys3.noutputs): for j in range(sys3.ninputs): - np.testing.assert_array_equal(sys3.num[i][j], num3[i][j]) - np.testing.assert_array_equal(sys3.den[i][j], den3[i][j]) + np.testing.assert_allclose(sys3.num[i][j], num3[i][j]) + np.testing.assert_allclose(sys3.den[i][j], den3[i][j]) # Tests for TransferFunction.__sub__ @@ -246,8 +246,8 @@ def test_subtract_scalar(self): sys2 = TransferFunction(np.array([2.]), [1.]) sys3 = sys1 - sys2 - np.testing.assert_array_equal(sys3.num, -1.) - np.testing.assert_array_equal(sys3.den, 1.) + np.testing.assert_allclose(sys3.num, -1.) + np.testing.assert_allclose(sys3.den, 1.) def test_subtract_siso(self): """Subtract two SISO systems.""" @@ -256,10 +256,10 @@ def test_subtract_siso(self): sys3 = sys1 - sys2 sys4 = sys2 - sys1 - np.testing.assert_array_equal(sys3.num, [[[2., 6., -12., -10., -2.]]]) - np.testing.assert_array_equal(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) - np.testing.assert_array_equal(sys4.num, [[[-2., -6., 12., 10., 2.]]]) - np.testing.assert_array_equal(sys4.den, [[[1., 6., 1., -7., -2., 1.]]]) + np.testing.assert_allclose(sys3.num, [[[2., 6., -12., -10., -2.]]]) + np.testing.assert_allclose(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) + np.testing.assert_allclose(sys4.num, [[[-2., -6., 12., 10., 2.]]]) + np.testing.assert_allclose(sys4.den, [[[1., 6., 1., -7., -2., 1.]]]) @slycotonly def test_subtract_mimo(self): @@ -283,8 +283,8 @@ def test_subtract_mimo(self): for i in range(sys3.noutputs): for j in range(sys3.ninputs): - np.testing.assert_array_equal(sys3.num[i][j], num3[i][j]) - np.testing.assert_array_equal(sys3.den[i][j], den3[i][j]) + np.testing.assert_allclose(sys3.num[i][j], num3[i][j]) + np.testing.assert_allclose(sys3.den[i][j], den3[i][j]) # Tests for TransferFunction.__mul__ @@ -295,10 +295,10 @@ def test_multiply_scalar(self): sys3 = sys1 * sys2 sys4 = sys1 * sys2 - np.testing.assert_array_equal(sys3.num, [[[2.]]]) - np.testing.assert_array_equal(sys3.den, [[[4.]]]) - np.testing.assert_array_equal(sys3.num, sys4.num) - np.testing.assert_array_equal(sys3.den, sys4.den) + np.testing.assert_allclose(sys3.num, [[[2.]]]) + np.testing.assert_allclose(sys3.den, [[[4.]]]) + np.testing.assert_allclose(sys3.num, sys4.num) + np.testing.assert_allclose(sys3.den, sys4.den) def test_multiply_siso(self): """Multiply two SISO systems.""" @@ -307,10 +307,10 @@ def test_multiply_siso(self): sys3 = sys1 * sys2 sys4 = sys2 * sys1 - np.testing.assert_array_equal(sys3.num, [[[-1., 0., 4., 15.]]]) - np.testing.assert_array_equal(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) - np.testing.assert_array_equal(sys3.num, sys4.num) - np.testing.assert_array_equal(sys3.den, sys4.den) + np.testing.assert_allclose(sys3.num, [[[-1., 0., 4., 15.]]]) + np.testing.assert_allclose(sys3.den, [[[1., 6., 1., -7., -2., 1.]]]) + np.testing.assert_allclose(sys3.num, sys4.num) + np.testing.assert_allclose(sys3.den, sys4.den) @slycotonly def test_multiply_mimo(self): @@ -339,8 +339,8 @@ def test_multiply_mimo(self): for i in range(sys3.noutputs): for j in range(sys3.ninputs): - np.testing.assert_array_equal(sys3.num[i][j], num3[i][j]) - np.testing.assert_array_equal(sys3.den[i][j], den3[i][j]) + np.testing.assert_allclose(sys3.num[i][j], num3[i][j]) + np.testing.assert_allclose(sys3.den[i][j], den3[i][j]) # Tests for TransferFunction.__div__ @@ -350,8 +350,8 @@ def test_divide_scalar(self): sys2 = TransferFunction(5., 2.) sys3 = sys1 / sys2 - np.testing.assert_array_equal(sys3.num, [[[6.]]]) - np.testing.assert_array_equal(sys3.den, [[[-20.]]]) + np.testing.assert_allclose(sys3.num, [[[6.]]]) + np.testing.assert_allclose(sys3.den, [[[-20.]]]) def test_divide_siso(self): """Divide two SISO systems.""" @@ -360,10 +360,10 @@ def test_divide_siso(self): sys3 = sys1 / sys2 sys4 = sys2 / sys1 - np.testing.assert_array_equal(sys3.num, [[[1., 3., 4., -3., -5.]]]) - np.testing.assert_array_equal(sys3.den, [[[-1., -3., 16., 7., -3.]]]) - np.testing.assert_array_equal(sys4.num, sys3.den) - np.testing.assert_array_equal(sys4.den, sys3.num) + np.testing.assert_allclose(sys3.num, [[[1., 3., 4., -3., -5.]]]) + np.testing.assert_allclose(sys3.den, [[[-1., -3., 16., 7., -3.]]]) + np.testing.assert_allclose(sys4.num, sys3.den) + np.testing.assert_allclose(sys4.den, sys3.num) def test_div(self): # Make sure that sampling times work correctly @@ -522,7 +522,7 @@ def test_freqresp_mimo(self): np.testing.assert_array_almost_equal(mag, true_mag) np.testing.assert_array_almost_equal(phase, true_phase) - np.testing.assert_array_equal(omega, true_omega) + np.testing.assert_allclose(omega, true_omega) # Tests for TransferFunction.pole and TransferFunction.zero. def test_common_den(self): @@ -626,10 +626,10 @@ def test_feedback_siso(self): sys3 = sys1.feedback(sys2) sys4 = sys1.feedback(sys2, 1) - np.testing.assert_array_equal(sys3.num, [[[-1., 7., -16., 16., 0.]]]) - np.testing.assert_array_equal(sys3.den, [[[1., 0., -2., 2., 32., 0.]]]) - np.testing.assert_array_equal(sys4.num, [[[-1., 7., -16., 16., 0.]]]) - np.testing.assert_array_equal(sys4.den, [[[1., 0., 2., -8., 8., 0.]]]) + np.testing.assert_allclose(sys3.num, [[[-1., 7., -16., 16., 0.]]]) + np.testing.assert_allclose(sys3.den, [[[1., 0., -2., 2., 32., 0.]]]) + np.testing.assert_allclose(sys4.num, [[[-1., 7., -16., 16., 0.]]]) + np.testing.assert_allclose(sys4.den, [[[1., 0., 2., -8., 8., 0.]]]) @slycotonly def test_convert_to_transfer_function(self): @@ -813,7 +813,7 @@ def test_dcgain_cont(self): den = [[[1, 3], [2, 3], [3, 3]], [[1, 5], [2, 7], [3, 11]]] sys4 = TransferFunction(num, den) expected = [[5, 7, 11], [2, 2, 2]] - np.testing.assert_array_equal(sys4.dcgain(), expected) + np.testing.assert_allclose(sys4.dcgain(), expected) def test_dcgain_discr(self): """Test DC gain for discrete-time transfer functions"""