def test_1d_filter(): """Test our private overlap-add filtering function""" rng = np.random.RandomState(0) # make some random signals and filters for n_signal in (1, 2, 5, 10, 20, 40, 100, 200, 400, 1000, 2000): x = rng.randn(n_signal) for n_filter in (2, 5, 10, 20, 40, 100, 200, 400, 1000, 2000): # Don't test n_filter == 1 because scipy can't handle it. if n_filter > n_signal: continue # only equal or lesser lengths supported for filter_type in ('identity', 'random'): if filter_type == 'random': h = rng.randn(n_filter) else: # filter_type == 'identity' h = np.concatenate([[1.], np.zeros(n_filter - 1)]) # ensure we pad the signal the same way for both filters n_pad = max(min(n_filter, n_signal - 1), 0) x_pad = _smart_pad(x, n_pad) for zero_phase in (True, False): # compute our expected result the slow way if zero_phase: x_expected = np.convolve(x_pad, h)[::-1] x_expected = np.convolve(x_expected, h)[::-1] x_expected = x_expected[len(h) - 1:-(len(h) - 1)] else: x_expected = np.convolve(x_pad, h) x_expected = x_expected[:-(len(h) - 1)] # remove padding if n_pad > 0: x_expected = x_expected[n_pad:-n_pad] # make sure we actually set things up reasonably if filter_type == 'identity': assert_allclose(x_expected, x) # compute our version for n_fft in (None, 32, 128, 129, 1023, 1024, 1025, 2048): # need to use .copy() b/c signal gets modified inplace x_copy = x[np.newaxis, :].copy() if (n_fft is not None and n_fft < 2 * n_filter - 1 and zero_phase): assert_raises(ValueError, _overlap_add_filter, x_copy, h, n_fft, zero_phase) elif (n_fft is not None and n_fft < n_filter and not zero_phase): assert_raises(ValueError, _overlap_add_filter, x_copy, h, n_fft, zero_phase) else: # bad len warning with warnings.catch_warnings(record=True): x_filtered = _overlap_add_filter( x_copy, h, n_fft, zero_phase)[0] assert_allclose(x_expected, x_filtered)
def test_1d_filter(): """Test our private overlap-add filtering function.""" # make some random signals and filters rng = np.random.RandomState(0) for n_signal in (1, 2, 3, 5, 10, 20, 40): x = rng.randn(n_signal) for n_filter in (1, 2, 3, 5, 10, 11, 20, 21, 40, 41, 100, 101): for filter_type in ('identity', 'random'): if filter_type == 'random': h = rng.randn(n_filter) else: # filter_type == 'identity' h = np.concatenate([[1.], np.zeros(n_filter - 1)]) # ensure we pad the signal the same way for both filters n_pad = n_filter - 1 x_pad = _smart_pad(x, (n_pad, n_pad)) for phase in ('zero', 'linear', 'zero-double'): # compute our expected result the slow way if phase == 'zero': # only allow zero-phase for odd-length filters if n_filter % 2 == 0: pytest.raises(RuntimeError, _overlap_add_filter, x[np.newaxis], h, phase=phase) continue shift = (len(h) - 1) // 2 x_expected = np.convolve(x_pad, h) x_expected = x_expected[shift:len(x_expected) - shift] elif phase == 'zero-double': shift = len(h) - 1 x_expected = np.convolve(x_pad, h) x_expected = np.convolve(x_expected[::-1], h)[::-1] x_expected = x_expected[shift:len(x_expected) - shift] shift = 0 else: shift = 0 x_expected = np.convolve(x_pad, h) x_expected = x_expected[:len(x_expected) - len(h) + 1] # remove padding if n_pad > 0: x_expected = x_expected[n_pad:len(x_expected) - n_pad] assert len(x_expected) == len(x) # make sure we actually set things up reasonably if filter_type == 'identity': out = x_pad.copy() out = out[shift + n_pad:] out = out[:len(x)] out = np.concatenate( (out, np.zeros(max(len(x) - len(out), 0)))) assert len(out) == len(x) assert_allclose(out, x_expected) assert len(x_expected) == len(x) # compute our version for n_fft in (None, 32, 128, 129, 1023, 1024, 1025, 2048): # need to use .copy() b/c signal gets modified inplace x_copy = x[np.newaxis, :].copy() min_fft = 2 * n_filter - 1 if phase == 'zero-double': min_fft = 2 * min_fft - 1 if n_fft is not None and n_fft < min_fft: pytest.raises(ValueError, _overlap_add_filter, x_copy, h, n_fft, phase=phase) else: x_filtered = _overlap_add_filter(x_copy, h, n_fft, phase=phase)[0] assert_allclose(x_filtered, x_expected, atol=1e-13)
def test_1d_filter(): """Test our private overlap-add filtering function.""" # make some random signals and filters for n_signal in (1, 2, 3, 5, 10, 20, 40): x = rng.randn(n_signal) for n_filter in (1, 2, 3, 5, 10, 11, 20, 21, 40, 41, 100, 101): for filter_type in ('identity', 'random'): if filter_type == 'random': h = rng.randn(n_filter) else: # filter_type == 'identity' h = np.concatenate([[1.], np.zeros(n_filter - 1)]) # ensure we pad the signal the same way for both filters n_pad = n_filter - 1 x_pad = _smart_pad(x, np.array([n_pad, n_pad])) for phase in ('zero', 'linear', 'zero-double'): # compute our expected result the slow way if phase == 'zero': # only allow zero-phase for odd-length filters if n_filter % 2 == 0: assert_raises(RuntimeError, _overlap_add_filter, x[np.newaxis], h, phase=phase) continue shift = (len(h) - 1) // 2 x_expected = np.convolve(x_pad, h) x_expected = x_expected[shift:len(x_expected) - shift] elif phase == 'zero-double': shift = len(h) - 1 x_expected = np.convolve(x_pad, h) x_expected = np.convolve(x_expected[::-1], h)[::-1] x_expected = x_expected[shift:len(x_expected) - shift] shift = 0 else: shift = 0 x_expected = np.convolve(x_pad, h) x_expected = x_expected[:len(x_expected) - len(h) + 1] # remove padding if n_pad > 0: x_expected = x_expected[n_pad:len(x_expected) - n_pad] assert_equal(len(x_expected), len(x)) # make sure we actually set things up reasonably if filter_type == 'identity': out = x_pad.copy() out = out[shift + n_pad:] out = out[:len(x)] out = np.concatenate((out, np.zeros(max(len(x) - len(out), 0)))) assert_equal(len(out), len(x)) assert_allclose(out, x_expected) assert_equal(len(x_expected), len(x)) # compute our version for n_fft in (None, 32, 128, 129, 1023, 1024, 1025, 2048): # need to use .copy() b/c signal gets modified inplace x_copy = x[np.newaxis, :].copy() min_fft = 2 * n_filter - 1 if phase == 'zero-double': min_fft = 2 * min_fft - 1 if n_fft is not None and n_fft < min_fft: assert_raises(ValueError, _overlap_add_filter, x_copy, h, n_fft, phase=phase) else: x_filtered = _overlap_add_filter( x_copy, h, n_fft, phase=phase)[0] assert_allclose(x_filtered, x_expected, atol=1e-13)