def gabor(signal, n_coeff=None, q_oversample=None, window=None): """Compute the Gabor representation of a signal. :param signal: Singal to be analyzed. :param n_coeff: number of Gabor coefficients in time. :param q_oversample: Degree of oversampling :param window: Synthesis window :type signal: array-like :type n_coeff: integer :type q_oversample: int :type window: array-like :return: Tuple of Gabor coefficients, biorthogonal window associated with the synthesis window. :rtype: tuple """ if n_coeff is None: n_coeff = divider(signal.shape[0]) if q_oversample is None: q_oversample = divider(n_coeff) if window is None: window = np.exp(np.log(0.005) * np.linspace(-1, 1, nearest_odd(n_coeff)) ** 2) window = window / np.linalg.norm(window) m = int(q_oversample * signal.shape[0] / float(n_coeff)) mb = int(signal.shape[0] / float(n_coeff)) nb = int(signal.shape[0] / float(m)) # Zak transform? nh = window.shape[0] if nh % 2 == 0: raise ValueError("The window function should have an odd length.") alpha = np.round((2 * signal.shape[0] / float(n_coeff) - 1 - nh) / (2 * q_oversample)) hn1 = np.zeros((signal.shape[0],)) start = np.round(((signal.shape[0] - (nh - 1))) / 2) - alpha end = np.round((signal.shape[0] + nh - 1) / 2) - alpha hn1[np.arange(start - 1, end).astype(int)] = window msig = hn1.reshape(int(nb), int(m), order='F') dzth = np.fft.fft(msig.T, axis=0) / np.sqrt(m) mzh = np.zeros((m, mb)) x = np.arange(1, m + 1, dtype=float) for l in range(q_oversample): mod = modulo(x - l * m / q_oversample, m).astype(int) mzh += np.abs(dzth[mod - 1, :]) ** 2 mzh[mzh < np.spacing(1)] = 1 # Za transform of biorthogonal dual frame window gam dztgam = dzth / mzh gam = np.real(izak(dztgam)) / signal.shape[0] # Computation of Gabor coefficient of dual frame window. dgrn1 = np.zeros((signal.shape[0], n_coeff), dtype=complex) k = np.arange(1, signal.shape[0] + 1) for n in range(n_coeff): index = modulo(k - n * m / q_oversample, signal.shape[0]).astype(int) - 1 dgrn1[:, n] = np.fft.fft(signal * np.fft.fftshift(gam[index]), axis=0) dgr = dgrn1[np.arange(signal.shape[0], step=nb).astype(int), :] tfr = np.abs(dgr) ** 2 return tfr, dgr, gam
def test_divider(self): """Test the divider function.""" self.assertSequenceEqual(utils.divider(4), (2, 2)) self.assertSequenceEqual(utils.divider(17), (1, 17)) self.assertSequenceEqual(utils.divider(60), (6, 10)) x = np.arange(1, 101) lowers = np.zeros(x.shape) uppers = np.zeros(x.shape) for i, num in enumerate(x): a, b = utils.divider(num) lowers[i] = a uppers[i] = b perfect_squares = np.arange(1, 11)**2 np.testing.assert_allclose(perfect_squares, x[lowers == uppers])
def test_divider(self): """Test the divider function.""" self.assertItemsEqual(utils.divider(4), (2, 2)) self.assertItemsEqual(utils.divider(17), (1, 17)) self.assertItemsEqual(utils.divider(60), (6, 10)) x = np.arange(1, 101) lowers = np.zeros(x.shape) uppers = np.zeros(x.shape) for i, num in enumerate(x): a, b = utils.divider(num) lowers[i] = a uppers[i] = b perfect_squares = np.arange(1, 11) ** 2 np.testing.assert_allclose(perfect_squares, x[lowers == uppers])