Source code for tftb.processing.freq_domain

import numpy as np
from scipy import angle


[docs]def locfreq(signal): """ Compute the frequency localization characteristics. :param sig: input signal :type sig: numpy.ndarray :return: average normalized frequency center, frequency spreading :rtype: tuple :Example: >>> from tftb.generators import amgauss >>> z = amgauss(160, 80, 50) >>> fm, B = locfreq(z) >>> print("%.3g" % fm) -9.18e-14 >>> print("%.4g" % B) 0.02 """ if signal.ndim > 1: if 1 not in signal.shape: raise TypeError else: signal = signal.ravel() no2r = np.round(signal.shape[0] / 2.0) no2f = np.floor(signal.shape[0] / 2.0) sig = np.fft.fft(signal) sig = np.abs(sig) ** 2 sig = sig / sig.mean() freqs = np.hstack((np.arange(no2f), np.arange(-no2r, 0))) / signal.shape[0] fm = np.mean(freqs * sig) bw = 2 * np.sqrt(np.pi * np.mean(((freqs - fm) ** 2) * sig)) return fm, bw
[docs]def inst_freq(x, t=None, L=1): """ Compute the instantaneous frequency of an analytic signal at specific time instants using the trapezoidal integration rule. :param x: The input analytic signal :param t: The time instants at which to calculate the instantaneous frequencies. :param L: Non default values are currently not supported. If L is 1, the normalized instantaneous frequency is computed. If L > 1, the maximum likelihood estimate of the instantaneous frequency of the deterministic part of the signal. :type x: numpy.ndarray :type t: numpy.ndarray :type L: int :return: instantaneous frequencies of the input signal. :rtype: numpy.ndarray :Example: >>> from tftb.generators import fmsin >>> x = fmsin(70, 0.05, 0.35, 25)[0] >>> instf, timestamps = inst_freq(x) >>> plot(timestamps, instf) #doctest: +SKIP .. plot:: docstring_plots/processing/freq_domain/inst_freq.py """ if x.ndim != 1: if 1 not in x.shape: raise TypeError("Input should be a one dimensional array.") else: x = x.ravel() if t is not None: if t.ndim != 1: if 1 not in t.shape: raise TypeError("Time instants should be a one dimensional " "array.") else: t = t.ravel() else: t = np.arange(2, len(x)) fnorm = 0.5 * (angle(-x[t] * np.conj(x[t - 2])) + np.pi) / (2 * np.pi) return fnorm, t
[docs]def group_delay(x, fnorm=None): """ Compute the group delay of a signal at normalized frequencies. :param x: time domain signal :param fnorm: normalized frequency at which to calculate the group delay. :type x: numpy.ndarray :type fnorm: float :return: group delay :rtype: numpy.ndarray :Example: >>> import numpy as np >>> from tftb.generators import amgauss, fmlin >>> x = amgauss(128, 64.0, 30) * fmlin(128, 0.1, 0.4)[0] >>> fnorm = np.arange(0.1, 0.38, step=0.04) >>> gd = group_delay(x, fnorm) >>> plot(gd, fnorm) #doctest: +SKIP .. plot:: docstring_plots/processing/freq_domain/group_delay.py """ if x.ndim != 1: if 1 not in x.shape: raise TypeError else: x = x.ravel() if fnorm is None: numerator = np.fft.fft(x * np.arange(1, x.shape[0] + 1)) denominator = np.fft.fft(x) window = np.real(numerator / denominator) >= 1 ratio = np.real(numerator / denominator) * window.astype(int) ratio = ratio * (np.real(numerator / denominator) <= (len(x) + 3)).astype(int) gd = np.fft.fftshift(ratio) else: exponent = np.exp(-1j * 2.0 * np.pi * fnorm.reshape(len(fnorm), 1) * np.arange(len(x))) numerator = np.dot(exponent, (x * np.arange(1, x.shape[0] + 1))) denominator = np.dot(exponent, x) window = np.real(numerator / denominator) >= 1 ratio = np.real(numerator / denominator) * window.astype(int) gd = ratio * (np.real(numerator / denominator) <= (len(x) + 3)).astype(int) return gd