def test_step_pole_cancellation(self, tsystem): # confirm that pole-zero cancellation doesn't perturb results # https://github.com/python-control/python-control/issues/440 step_info_no_cancellation = step_info(tsystem[0].sys) step_info_cancellation = step_info(tsystem[1].sys) self.assert_step_info_match(tsystem[0].sys, step_info_no_cancellation, step_info_cancellation)
def test_step_pole_cancellation(self, pole_cancellation, no_pole_cancellation): # confirm that pole-zero cancellation doesn't perturb results # https://github.com/python-control/python-control/issues/440 step_info_no_cancellation = step_info(no_pole_cancellation) step_info_cancellation = step_info(pole_cancellation) for key in step_info_no_cancellation: np.testing.assert_allclose(step_info_no_cancellation[key], step_info_cancellation[key], rtol=1e-4)
def test_step_pole_cancellation(self, pole_cancellation, no_pole_cancellation): # confirm that pole-zero cancellation doesn't perturb results # https://github.com/python-control/python-control/issues/440 step_info_no_cancellation = step_info(no_pole_cancellation) step_info_cancellation = step_info(pole_cancellation) for key in step_info_no_cancellation: if key == 'Overshoot': # skip this test because these systems have no overshoot # => very sensitive to parameters continue np.testing.assert_allclose(step_info_no_cancellation[key], step_info_cancellation[key], rtol=1e-4)
def test_step_info(self): # From matlab docs: sys = TransferFunction([1, 5, 5], [1, 1.65, 5, 6.5, 2]) Strue = { 'RiseTime': 3.8456, 'SettlingTime': 27.9762, 'SettlingMin': 2.0689, 'SettlingMax': 2.6873, 'Overshoot': 7.4915, 'Undershoot': 0, 'Peak': 2.6873, 'PeakTime': 8.0530, 'SteadyStateValue': 2.50 } S = step_info(sys) Sk = sorted(S.keys()) Sktrue = sorted(Strue.keys()) assert Sk == Sktrue # Very arbitrary tolerance because I don't know if the # response from the MATLAB is really that accurate. # maybe it is a good idea to change the Strue to match # but I didn't do it because I don't know if it is # accurate either... rtol = 2e-2 np.testing.assert_allclose([S[k] for k in Sk], [Strue[k] for k in Sktrue], rtol=rtol)
def test_step_info_invalid(self): """Call step_info with invalid parameters.""" with pytest.raises(ValueError, match="time series data convention"): step_info(["not numeric data"]) with pytest.raises(ValueError, match="time series data convention"): step_info(np.ones((10, 15))) # invalid shape with pytest.raises(ValueError, match="matching time vector"): step_info(np.ones(15), T=np.linspace(0, 1, 20)) # time too long with pytest.raises(ValueError, match="matching time vector"): step_info(np.ones((2, 2, 15))) # no time vector
def test_step_info(self, tsystem, systype, time_2d, yfinal): """Test step info for SISO systems.""" step_info_kwargs = tsystem.kwargs.get('step_info', {}) if systype == "time response": # simulate long enough for steady state value tfinal = 3 * tsystem.step_info['SettlingTime'] if np.isnan(tfinal): pytest.skip("test system does not settle") t, y = step_response(tsystem.sys, T=tfinal, T_num=5000) sysdata = y step_info_kwargs['T'] = t[np.newaxis, :] if time_2d else t else: sysdata = tsystem.sys if yfinal: step_info_kwargs['yfinal'] = tsystem.step_info['SteadyStateValue'] info = step_info(sysdata, **step_info_kwargs) self.assert_step_info_match(tsystem.sys, info, tsystem.step_info)
def test_step_info_mimo(self, tsystem, systype, yfinal): """Test step info for MIMO systems.""" step_info_kwargs = tsystem.kwargs.get('step_info', {}) if systype == "time response": tfinal = 3 * max([S['SettlingTime'] for Srow in tsystem.step_info for S in Srow]) t, y = step_response(tsystem.sys, T=tfinal, T_num=5000) sysdata = y step_info_kwargs['T'] = t else: sysdata = tsystem.sys if yfinal: step_info_kwargs['yfinal'] = [[S['SteadyStateValue'] for S in Srow] for Srow in tsystem.step_info] info_dict = step_info(sysdata, **step_info_kwargs) for i, row in enumerate(info_dict): for j, info in enumerate(row): self.assert_step_info_match(tsystem.sys, info, tsystem.step_info[i][j])