Source code for tftb.generators.frequency_modulated

import numpy as np
from numpy import pi
import warnings


[docs]def fmconst(n_points, fnorm=0.25, t0=None): """ Generate a signal with constant frequency modulation. :param n_points: number of points :param fnorm: normalized frequency :param t0: time center :type n_points: int :type fnorm: float :type t0: float :return: frequency modulation signal with frequency fnorm :rtype: numpy.ndarray :Examples: >>> from tftb.generators import amgauss >>> z = amgauss(128, 50, 30) * fmconst(128, 0.05, 50)[0] >>> plot(real(z)) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmconst.py """ if t0 is None: t0 = round(n_points / 2.0) if n_points <= 0: raise TypeError elif abs(fnorm) > 0.5: raise TypeError else: tmt0 = np.arange(n_points) - t0 y = np.exp(1j * 2.0 * np.pi * fnorm * tmt0) y = y / np.real(y[int(t0)]) iflaw = fnorm * np.ones((n_points,)) return y, iflaw
[docs]def fmhyp(n_points, p1, p2): """Signal with hyperbolic frequency modulation. :param n_points: number of points. :param p1, p2: coefficients of the hyperbolic function. :type n_points: int :type p1: float :type p2: float :return: vector containing the modulated signal samples. :rtype: numpy.ndarray :Examples: >>> signal, iflaw = fmhyp(128, (1, 0.5), (32, 0.1)) >>> subplot(211), plot(real(signal)) #doctest: +SKIP >>> subplot(212), plot(iflaw) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmhyp.py """ c = (p2[1] - p1[1]) / (1.0 / p2[0] - 1 / p1[0]) f0 = p1[1] - c / p1[0] t = np.arange(1, n_points + 1) phi = 2 * np.pi * (f0 * t + c * np.log(np.abs(t))) iflaw = (f0 + c / np.abs(t)) a, b = iflaw < 0, iflaw > 0.5 aliasing = np.logical_or(a, b) if np.any(aliasing): msg = "Signal may be undersampled or may have negative frequencies." warnings.warn(msg, UserWarning) x = np.exp(1j * phi) return x, iflaw
[docs]def fmlin(n_points, fnormi=0.0, fnormf=0.5, t0=None): """ Generate a signal with linear frequency modulation. :param n_points: number of points :param fnormi: initial normalized frequency :param fnormf: final normalized frequency :param t0: time center :type n_points: int :type fnormi: float :type fnormf: float :type t0: float :return: The modulated signal, and the instantaneous amplitude law. :rtype: tuple(array-like) :Examples: >>> from tftb.generators import amgauss >>> z = amgauss(128, 50, 40) * fmlin(128, 0.05, 0.3, 50)[0] >>> plot(real(z)) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmlin.py """ if t0 is None: t0 = round(n_points / 2.0) if n_points <= 0: raise TypeError elif (abs(fnormi) > 0.5) or (abs(fnormf) > 0.5): raise TypeError else: y = np.arange(1, n_points + 1) y = fnormi * (y - t0) + ((fnormf - fnormi) / (2.0 * (n_points - 1))) * \ ((y - 1) ** 2 - (t0 - 1) ** 2) y = np.exp(1j * 2.0 * np.pi * y) y = y / y[int(t0) - 1] iflaw = np.linspace(fnormi, fnormf, n_points) return y, iflaw
[docs]def fmodany(iflaw, t0=1): """Arbitrary frequency modulation. :param iflaw: Vector of instantaneous frequency law samples. :param t0: time center :type iflaw: numpy.ndarray :type t0: float :return: output signal :rtype: :Examples: >>> from tftb.generators import fmlin >>> import numpy as np >>> y1, ifl1 = fmlin(100) # A linear instantaneous frequency law. >>> y2, ifl2 = fmsin(100) # A sinusoidal instantaneous frequency law. >>> iflaw = np.append(ifl1, ifl2) # combination of the two >>> sig = fmodany(iflaw) >>> subplot(211), plot(real(sig)) #doctest: +SKIP >>> subplot(212), plot(iflaw) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmodany.py """ if len(iflaw.shape) > 1: if iflaw.shape[1] != 1: raise TypeError("iflaw should be a column vector.") elif np.amax(np.abs(iflaw)) > 0.5: raise TypeError("Elements of iflaw should be within -0.5 and 0.5") if (t0 > iflaw.shape[0]) or (t0 == 0): raise TypeError("T0 should be between 1 and len(iflaw)") y = np.exp(1j * 2.0 * pi * np.cumsum(iflaw)) y = y * np.conjugate(y[t0]) return y
[docs]def fmpar(n_points, coefficients): """Parabolic frequency modulated signal. :param n_points: number of points :param coefficients: coefficients of the parabolic function. :type n_points: int :type coefficients: tuple :return: Signal with parabolic frequency modulation law. :rtype: tuple :Examples: >>> x, iflaw = fmpar(128, (0.4, -0.0112, 8.6806e-05)) >>> subplot(211), plot(real(x)) #doctest: +SKIP >>> subplot(212), plot(iflaw) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmpar.py """ a0, a1, a2 = coefficients t = np.arange(n_points) phi = 2 * np.pi * (a0 * t + (a1 / 2 * t) ** 2 + (a2 / 3 * t) ** 3) iflaw = a0 + a1 * t + a2 * (t ** 2) a, b = iflaw < 0, iflaw > 0.5 aliasing = np.logical_or(a, b) if np.any(aliasing): msg = "Signal may be undersampled or may have negative frequencies." warnings.warn(msg, UserWarning) x = np.exp(1j * phi) return x, iflaw
[docs]def fmpower(n_points, k, coefficients): """Generate signal with power law frequency modulation. :param n_points: number of points. :param k: degree of power law. :param p1, p2: coefficients of the power law. :type n_points: int :type k: int :type p1: float :type p2: float :return: vector of modulated signal samples. :rtype: numpy.ndarray :Examples: >>> x, iflaw = fmpower(128, 0.5, (1, 0.5, 100, 0.1)) >>> subplot(211), plot(real(x)) #doctest: +SKIP >>> subplot(212), plot(iflaw) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmpower.py """ if len(coefficients) == 2: f0, c = coefficients elif len(coefficients) > 2: p1 = coefficients[:2] p2 = coefficients[2:] c = (p2[1] - p1[1]) / (1.0 / (p2[0] ** k) - 1.0 / (p1[0] ** k)) f0 = p1[1] - c / (p1[0] ** k) t = np.arange(n_points) phi = 2 * np.pi * (f0 * t + c / (1 - k) * np.abs(t) ** (1 - k)) iflaw = (f0 + c * np.abs(t) ** (-k)) a, b = iflaw < 0, iflaw > 0.5 aliasing = np.logical_or(a, b) if np.any(aliasing): msg = "Signal may be undersampled or may have negative frequencies." warnings.warn(msg, UserWarning) x = np.exp(1j * phi) return x, iflaw
[docs]def fmsin(n_points, fnormin=0.05, fnormax=0.45, period=None, t0=None, fnorm0=None, pm1=1): """Sinusodial frequency modulation. :param n_points: number of points :param fnormin: smallest normalized frequency :param fnormax: highest normalized frequency :param period: period of sinusoidal fm :param t0: time reference :param fnorm0: normalized frequency at time t0 :param pm1: frequency direction at t0 :type n_points: int :type fnormin: float :type fnormax: float :type period: int :type t0: float :type fnorm0: float :type pm1: int :return: output signal :rtype: numpy.ndarray :Examples: >>> z = fmsin(140, period=100, t0=20, fnorm0=0.3, pm1=-1) >>> plot(real(z)) #doctest: +SKIP .. plot:: docstring_plots/generators/frequency_modulated/fmsin.py """ if period is None: period = n_points if t0 is None: t0 = n_points / 2.0 if fnorm0 is None: fnorm0 = 0.5 * (fnormin + fnormax) fnormid = 0.5 * (fnormax + fnormin) delta = 0.5 * (fnormax - fnormin) phi = -pm1 * np.arccos((fnorm0 - fnormid) / delta) t = np.arange(n_points) - t0 phase = 2 * pi * fnormid * t + delta * period * (np.sin(2 * pi * t / period + phi)) -\ np.sin(phi) y = np.exp(1j * phase) iflaw = fnormid + delta * np.cos(2 * pi * t / period + phi) return y, iflaw
if __name__ == '__main__': fmconst(128) fmhyp(128, (1, 0.5), (32, 0.1)) fmlin(128) fmodany(np.random.rand(128) - 0.5) fmpar(128, (0.4, -0.0112, 8.6806e-05)) fmpower(128, 0.5, (1, 0.5, 100, 0.1)) fmsin(128)