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_modulo(self): """Test the modulo function.""" x = np.arange(1, 11) np.testing.assert_allclose(utils.modulo(x, 1), np.ones(x.shape)) np.testing.assert_allclose(utils.modulo(x, 2), np.array([1, 2, 1, 2, 1, 2, 1, 2, 1, 2])) np.testing.assert_allclose(utils.modulo(x, 3), np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1])) np.testing.assert_allclose(utils.modulo(x, 4), np.array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2])) np.testing.assert_allclose(utils.modulo(x, 5), np.array([1, 2, 3, 4, 5, 1, 2, 3, 4, 5]))