def test_05(self): # Test that bode() finds a reasonable frequency range. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) n = 10 # Expected range is from 0.01 to 10. expected_w = np.logspace(-2, 1, n) w, mag, phase = bode(system, n=n) assert_almost_equal(w, expected_w)
def test_04(self): # Test bode() phase calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_phase = np.arctan2(y.imag, y.real) * 180.0 / np.pi assert_almost_equal(phase, expected_phase)
def test_03(self): # Test bode() magnitude calculation. # 1st order low-pass filter: H(s) = 1 / (s + 1) system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) jw = w * 1j y = np.polyval(system.num, jw) / np.polyval(system.den, jw) expected_mag = 20.0 * np.log10(abs(y)) assert_almost_equal(mag, expected_mag)
def test_02(self): # Test bode() phase calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # angle(H(s=0.1)) ~= -5.7 deg # angle(H(s=1)) ~= -45 deg # angle(H(s=10)) ~= -84.3 deg system = lti([1], [1, 1]) w = [0.1, 1, 10] w, mag, phase = bode(system, w=w) expected_phase = [-5.7, -45, -84.3] assert_almost_equal(phase, expected_phase, decimal=1)
def test_01(self): # Test bode() magnitude calculation (manual sanity check). # 1st order low-pass filter: H(s) = 1 / (s + 1), # cutoff: 1 rad/s, slope: -20 dB/decade # H(s=0.1) ~= 0 dB # H(s=1) ~= -3 dB # H(s=10) ~= -20 dB # H(s=100) ~= -40 dB system = lti([1], [1, 1]) w = [0.1, 1, 10, 100] w, mag, phase = bode(system, w=w) expected_mag = [0, -3, -20, -40] assert_almost_equal(mag, expected_mag, decimal=1)
def test_from_state_space(self): # Ensure that bode works with a system that was created from the # state space representation matrices A, B, C, D. In this case, # system.num will be a 2-D array with shape (1, n+1), where (n,n) # is the shape of A. # A Butterworth lowpass filter is used, so we know the exact # frequency response. a = np.array([1.0, 2.0, 2.0, 1.0]) A = companion(a).T B = np.array([[0.0], [0.0], [1.0]]) C = np.array([[1.0, 0.0, 0.0]]) D = np.array([[0.0]]) with suppress_warnings() as sup: sup.filter(BadCoefficients) system = lti(A, B, C, D) w, mag, phase = bode(system, n=100) expected_magnitude = 20 * np.log10(np.sqrt(1.0 / (1.0 + w**6))) assert_almost_equal(mag, expected_magnitude)
def test_07(self): # bode() should not fail on a system with pure imaginary poles. # The test passes if bode doesn't raise an exception. system = lti([1], [1, 0, 100]) w, mag, phase = bode(system, n=2)
def test_06(self): # Test that bode() doesn't fail on a system with a pole at 0. # integrator, pole at zero: H(s) = 1 / s system = lti([1], [1, 0]) w, mag, phase = bode(system, n=2) assert_equal(w[0], 0.01) # a fail would give not-a-number