def anabpsk(n_points, n_comp=None, f0=0.25): """Binary phase shift keying (BPSK) signal. :param n_points: number of points. :param n_comp: number of points in each component. :param f0: normalized frequency. :type n_points: int :type n_comp: int :type f0: float :return: BPSK signal :rtype: numpy.ndarray :Examples: >>> x, am = anabpsk(300, 30, 0.1) >>> subplot(211), plot(real(x)) >>> subplot(212), plot(am) .. plot:: docstring_plots/generators/analytic_signals/anabpsk.py """ if n_comp is None: n_comp = np.round(n_points / 5) if (f0 < 0) or (f0 > 0.5): raise TypeError("f0 must be between 0 and 0.5") m = int(np.ceil(n_points / n_comp)) jumps = 2.0 * np.round(np.random.rand(m)) - 1 am = np.kron(jumps, np.ones((n_comp,)))[:n_points] y = am * fmconst(n_points, f0, 1)[0] return y, am
def anaask(n_points, n_comp=None, f0=0.25): """Generate an amplitude shift (ASK) keying signal. :param n_points: number of points. :param n_comp: number of points of each component. :param f0: normalized frequency. :type n_points: int :type n_comp: int :type f0: float :return: Tuple containing the modulated signal and the amplitude modulation. :rtype: tuple(numpy.ndarray) :Examples: >>> x, am = anaask(512, 64, 0.05) >>> subplot(211), plot(real(x)) >>> subplot(212), plot(am) .. plot:: docstring_plots/generators/analytic_signals/anaask.py """ if n_comp is None: n_comp = np.round(n_points / 2) if (f0 < 0) or (f0 > 0.5): raise TypeError("f0 must be between 0 and 0.5") m = int(np.ceil(n_points / n_comp)) jumps = np.random.rand(m) am = np.kron(jumps, np.ones((n_comp,)))[:n_points] fm, iflaw = fmconst(n_points, f0, 1) y = am * fm return y, am
def anaask(n_points, n_comp=None, f0=0.25): """Generate an amplitude shift (ASK) keying signal. :param n_points: number of points. :param n_comp: number of points of each component. :param f0: normalized frequency. :type n_points: int :type n_comp: int :type f0: float :return: Tuple containing the modulated signal and the amplitude modulation. :rtype: tuple(numpy.ndarray) :Examples: >>> x, am = anaask(512, 64, 0.05) >>> subplot(211), plot(real(x)) #doctest: +SKIP >>> subplot(212), plot(am) #doctest: +SKIP .. plot:: docstring_plots/generators/analytic_signals/anaask.py """ if n_comp is None: n_comp = round(n_points / 2.0) if (f0 < 0) or (f0 > 0.5): raise TypeError("f0 must be between 0 and 0.5") m = int(np.ceil(n_points / n_comp)) jumps = np.random.rand(m) am = np.repeat(jumps, n_comp)[:n_points] fm, _ = fmconst(n_points, f0, 1) y = am * fm return y, am
def anabpsk(n_points, n_comp=None, f0=0.25): """Binary phase shift keying (BPSK) signal. :param n_points: number of points. :param n_comp: number of points in each component. :param f0: normalized frequency. :type n_points: int :type n_comp: int :type f0: float :return: BPSK signal :rtype: numpy.ndarray :Examples: >>> x, am = anabpsk(300, 30, 0.1) >>> subplot(211), plot(real(x)) #doctest: +SKIP >>> subplot(212), plot(am) #doctest: +SKIP .. plot:: docstring_plots/generators/analytic_signals/anabpsk.py """ if n_comp is None: n_comp = round(n_points / 5.0) if (f0 < 0) or (f0 > 0.5): raise TypeError("f0 must be between 0 and 0.5") m = int(np.ceil(n_points / n_comp)) jumps = 2.0 * np.round(np.random.rand(m)) - 1 am = np.repeat(jumps, n_comp)[:n_points] y = am * fmconst(n_points, f0, 1)[0] return y, am
====================================================== This example uses Friedman's method to calculate the instantaneous frequency density of a hybrid signal. The method consists of computing the histograms of frequency displacements of the spectrogram of the signal. """ import numpy as np import matplotlib.pyplot as plt from tftb.generators import fmlin, fmsin, fmconst from tftb.processing.reassigned import pseudo_wigner_ville from tftb.processing.postprocessing import friedman_density sig1, if1 = fmsin(60, 0.16, 0.35, 50, 1, 0.35, 1) sig2, if2 = fmlin(60, 0.3, 0.1) sig3, if3 = fmconst(60, 0.4) sig = np.hstack((sig1, np.zeros((8,)), sig2 + sig3)) t = np.arange(1, 128, step=2) tfr, rtfr, hat = pseudo_wigner_ville(sig, timestamps=t) tifd = friedman_density(tfr, hat, t) f = np.linspace(0, 0.5, tifd.shape[0]) plt.contour(t, f, tifd, 4) plt.grid(True) plt.title("Friedman's instantaenous frequency density") plt.xlabel('Time') plt.ylabel('Frequency') plt.show()
# -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ ========================================================================== Pseudo-Wigner-Ville Distribution of a Gaussian Atom and a Complex Sinusoid ========================================================================== This example demonstrates the pseudo Wigner Ville distribution of a signal composed from a Gaussian atom and a complex sinusoid with constant frequency modulation. Note that the frequency resolution is relatively worse than that of the Wigner-Ville representation, and the interferences have not been resolved properly. """ from tftb.generators import fmconst, amgauss from tftb.processing import PseudoWignerVilleDistribution import numpy as np sig = fmconst(128, 0.15)[0] + amgauss(128) * fmconst(128, 0.4)[0] tfr = PseudoWignerVilleDistribution(sig) tfr.run() tfr.plot(show_tf=True, kind="contour", freq_x=(abs(np.fft.fftshift(np.fft.fft(sig))) ** 2)[::-1][:64], freq_y=np.arange(sig.shape[0] / 2))
#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ """ from tftb.generators import amgauss, fmconst import numpy as np import matplotlib.pyplot as plt z = amgauss(128, 50.0, 30.0) * fmconst(128, 0.05, 50)[0] plt.plot(np.real(z)) plt.xlim(0, 128) plt.grid() plt.title('Constant Frequency Modulation') plt.show()
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 if __name__ == '__main__': from tftb.generators import fmconst sig = np.r_[fmconst(128, 0.2)[0], fmconst(128, 0.4)[0]] tfr = ShortTimeFourierTransform(sig) tfr.run() tfr.plot()
# # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ ==================================================================================================================== Monocomponent Nonstationary Signal with Constant Frequency Modulation and One-Sided Exponential Amplitude Modulation ==================================================================================================================== Generate a monocomponent nonstationary signal with constant frequency modulation and one-sided exponential amplitude modulation. """ from tftb.generators import fmconst, amexpos import matplotlib.pyplot as plt from numpy import real fm, _ = fmconst(256, 0.2) am = amexpos(256, 100, kind='unilateral') signal = am * fm plt.plot(real(signal)) plt.xlabel('Time') plt.ylabel('Real part') plt.title('Constant Frequency, One-sided Exponential Amplitude') plt.xlim(0, 256) plt.grid() plt.show()
This example demonstrates the visualization of the Morlet scalogram of a signal containing two complex sinusoids. In a scalogram, the frequency resolution varies on the scale of the signal. Here, the frequency resolution decreases at higher frequencies (lower scale). Figure 3.20 from the tutorial. """ from tftb.processing import Scalogram from tftb.generators import fmconst import numpy as np from mpl_toolkits.axes_grid1 import make_axes_locatable import matplotlib.pyplot as plt sig2 = fmconst(128, .15)[0] + fmconst(128, .35)[0] tfr, t, freqs, _ = Scalogram(sig2, time_instants=np.arange(1, 129), waveparams=6, fmin=0.05, fmax=0.45, n_voices=128).run() tfr = np.abs(tfr) ** 2 threshold = np.amax(tfr) * 0.05 tfr[tfr <= threshold] = 0.0 t, f = np.meshgrid(t, freqs) fig, axContour = plt.subplots(figsize=(10, 8)) axContour.contour(t, f, tfr) axContour.grid(True) axContour.set_title("Morlet scalogram") axContour.set_ylabel('Frequency') axContour.yaxis.set_label_position('right') axContour.set_xlabel('Time')
for l in range(q_oversample): # NOQA: E741 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 if __name__ == '__main__': from tftb.generators import fmconst import matplotlib.pyplot as plt sig = np.r_[fmconst(128, 0.2)[0], fmconst(128, 0.4)[0]] ts = np.linspace(0, 1, 256) tfr = ShortTimeFourierTransform(sig, timestamps=ts) tfr.run() tfr.plot(show_tf=True, cmap=plt.cm.viridis)
# # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ ==================================================================================================================== Monocomponent Nonstationary Signal with Constant Frequency Modulation and One-Sided Exponential Amplitude Modulation ==================================================================================================================== Generate a monocomponent nonstationary signal with constant frequency modulation and one-sided exponential amplitude modulation. Figure 2.7 from the tutorial. """ from tftb.generators import fmconst, amexpos import matplotlib.pyplot as plt from numpy import real fm, _ = fmconst(256, 0.2) am = amexpos(256, 100, kind='unilateral') signal = am * fm plt.plot(real(signal)) plt.xlabel('Time') plt.ylabel('Real part') plt.title('Constant Frequency, One-sided Exponential Amplitude') plt.xlim(0, 256) plt.grid() plt.show()
#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ ========================================================================== Pseudo-Wigner-Ville Distribution of a Gaussian Atom and a Complex Sinusoid ========================================================================== This example demonstrates the pseudo Wigner Ville distribution of a signal composed from a Gaussian atom and a complex sinusoid with constant frequency modulation. Note that the frequency resolution is relatively worse than that of the Wigner-Ville representation, and the interferences have not been resolved properly. Figure 4.9 from the tutorial. """ from tftb.generators import fmconst, amgauss from tftb.processing import PseudoWignerVilleDistribution sig = fmconst(128, 0.15)[0] + amgauss(128) * fmconst(128, 0.4)[0] tfr = PseudoWignerVilleDistribution(sig) tfr.run() tfr.plot(show_tf=True, kind="contour")
* One-sided exponential amplitude modulation (See :ref:`amexpos`) * Constant frequency modulation (See :ref:`fmconst`) * -5 dB complex gaussian noise (See :ref:`noisecg` and :ref:`sigmerge`) And how to plot its energy spectrum. Figure 1.10 of the tutorial. """ import numpy as np import matplotlib.pyplot as plt from tftb.generators import amexpos, fmconst, sigmerge, noisecg # Generate a noisy transient signal. transsig = amexpos(64, kind='unilateral') * fmconst(64)[0] signal = np.hstack((np.zeros((100,)), transsig, np.zeros((92,)))) signal = sigmerge(signal, noisecg(256), -5) fig, ax = plt.subplots(2, 1) ax1, ax2 = ax ax1.plot(np.real(signal)) ax1.grid() ax1.set_title('Noisy Transient Signal') ax1.set_xlabel('Time') ax1.set_xlim((0, 256)) ax1.set_ylim((np.real(signal).max(), np.real(signal.min()))) # Energy spectrum of the signal dsp = np.fft.fftshift(np.abs(np.fft.fft(signal)) ** 2) ax2.plot(np.arange(-128, 128, dtype=float) / 256, dsp) ax2.set_title('Energy spectrum of noisy transient signal')
Comparison of the Wigner Ville distribution with its smoothed and reassinged counterparts. Figure 4.35 from the tutorial. """ import numpy as np import matplotlib.pyplot as plt from tftb.generators import fmsin, fmlin, fmconst from tftb.processing import (ideal_tfr, WignerVilleDistribution, smoothed_pseudo_wigner_ville, reassigned_smoothed_pseudo_wigner_ville) sig1, if1 = fmsin(60, 0.16, 0.35, 50, 1, 0.35, 1) sig2, if2 = fmlin(60, 0.3, 0.1) sig3, if3 = fmconst(60, 0.4) sig = np.hstack((sig1, np.zeros((8, )), sig2 + sig3)) iflaw = np.zeros((2, 128)) iflaw[0, :] = np.hstack((if1, np.nan * np.ones((8, )), if2)) iflaw[1, :] = np.hstack((np.nan * np.ones((68, )), if3)) tfr, t, f = ideal_tfr(iflaw) plt.figure(figsize=(10, 8)) plt.subplot(221) plt.contour(t, f, tfr, 1) plt.gca().set_xticklabels([]) plt.grid(True) plt.title("Ideal instantaneous frequencies") plt.ylabel('Normalized Frequencies')
T = np.arange(1, N + 1, step=4) t = np.arange(1, N + 1) p = N / 2 fmin1 = 1.0 / 64 fmax1 = 1.5 * 1.0 / 8 x1 = fmsin(N, fmin1, fmax1, p, N / 2, fmax1)[0] fmin2 = 1.0 / 32 fmax2 = 1.5 * 1.0 / 4 x2 = fmsin(N, fmin2, fmax2, p, N / 2, fmax2)[0] f0 = 1.5 * 1.0 / 16 x3 = amgauss(N, N / 2, N / 8) * fmconst(N, f0)[0] a1 = 1 a2 = 1 a3 = 1 x = np.real(a1 * x1 + a2 * x2 + a3 * x3) x = x / np.max(np.abs(x)) decomposer = EMD(x) imf = decomposer.decompose() n_freq_bins = 256 short_window_length = 127 beta = 3 * np.pi window = kaiser(short_window_length, beta=beta)
characteristics: * One-sided exponential amplitude modulation (See :ref:`amexpos`) * Constant frequency modulation (See :ref:`fmconst`) * -5 dB complex gaussian noise (See :ref:`noisecg` and :ref:`sigmerge`) And how to plot its energy spectrum. """ import numpy as np import matplotlib.pyplot as plt from tftb.generators import amexpos, fmconst, sigmerge, noisecg # Generate a noisy transient signal. transsig = amexpos(64, kind="unilateral") * fmconst(64)[0] signal = np.hstack((np.zeros((100,)), transsig, np.zeros((92,)))) signal = sigmerge(signal, noisecg(256), -5) fig, ax = plt.subplots(2, 1) ax1, ax2 = ax ax1.plot(np.real(signal)) ax1.grid() ax1.set_title("Noisy Transient Signal") ax1.set_xlabel("Time") ax1.set_xlim((0, 256)) ax1.set_ylim((np.real(signal).max(), np.real(signal.min()))) # Energy spectrum of the signal dsp = np.fft.fftshift(np.abs(np.fft.fft(signal)) ** 2) ax2.plot(np.arange(-128, 128, dtype=float) / 256, dsp) ax2.set_title("Energy spectrum of noisy transient signal")
# # Copyright © 2015 jaidev <jaidev@newton> # # Distributed under terms of the MIT license. """ ======================================= Spectrogram of a Noisy Transient Signal ======================================= This example demonstrates the simple use of a Spectrogram to localize a signal in time and frequency. The transient signal appears at the normalized frequency 0.25 and between time points 125 and 160. Figure 1.11 from the tutorial. """ import numpy as np from scipy.signal import hamming from tftb.generators import amexpos, fmconst, sigmerge, noisecg from tftb.processing.cohen import Spectrogram # Generate a noisy transient signal. transsig = amexpos(64, kind='unilateral') * fmconst(64)[0] signal = np.hstack((np.zeros((100, )), transsig, np.zeros((92, )))) signal = sigmerge(signal, noisecg(256), -5) fwindow = hamming(65) spec = Spectrogram(signal, n_fbins=128, fwindow=fwindow) spec.run() spec.plot(kind="contour", threshold=0.1, show_tf=False)
=========================================== This example demonstrates the visualization of the Morlet scalogram of a signal containing two complex sinusoids. In a scalogram, the frequency resolution varies on the scale of the signal. Here, the frequency resolution decreases at higher frequencies (lower scale). """ from tftb.processing import scalogram from tftb.generators import fmconst import numpy as np from mpl_toolkits.axes_grid1 import make_axes_locatable import matplotlib.pyplot as plt sig2 = fmconst(128, 0.15)[0] + fmconst(128, 0.35)[0] tfr, t, f, _ = scalogram(sig2, time_instants=np.arange(1, 129), waveparams=6, fmin=0.05, fmax=0.45, n_voices=128) tfr = np.abs(tfr) ** 2 threshold = np.amax(tfr) * 0.05 tfr[tfr <= threshold] = 0.0 t, f = np.meshgrid(t, f) fig, axContour = plt.subplots(figsize=(10, 8)) axContour.contour(t, f, tfr) axContour.grid(True) axContour.set_title("Morlet scalogram") axContour.set_ylabel("Frequency") axContour.yaxis.set_label_position("right") axContour.set_xlabel("Time") divider = make_axes_locatable(axContour)