Hilbert Transform and Instantaneous Frequency
The Hilbert transform estimates the instantaneous frequency of a signal for monocomponent signals only. A monocomponent signal is described in the time-frequency plane by a single "ridge." The set of monocomponent signals includes single sinusoids and signals like chirps.
Generate a chirp sampled at 1 kHz for two seconds. Specify the chirp so its frequency is initially 100 Hz and increases to 200 Hz after one second.
fs = 1000; t = 0:1/fs:2-1/fs; y = chirp(t,100,1,200);
Estimate the spectrogram of the chirp using the short-time Fourier transform implemented in the pspectrum
function. The signal is well described by a single peak frequency at each point in time.
pspectrum(y,fs,'spectrogram')
Compute the analytic signal and differentiate its phase to measure the instantaneous frequency. The scaled derivative yields a meaningful estimate.
z = hilbert(y); instfrq = fs/(2*pi)*diff(unwrap(angle(z))); clf plot(t(2:end),instfrq) ylim([0 fs/2])
The instfreq
function computes and displays the instantaneous frequency in one step.
instfreq(y,fs,'Method','hilbert')
The method fails when the signal is not monocomponent.
Generate a sum of two sinusoids of frequencies 60 Hz and 90 Hz, sampled at 1023 Hz for two seconds. Compute and plot the spectrogram. Each time point shows the presence of the two components.
fs = 1023;
t = 0:1/fs:2-1/fs;
x = sin(2*pi*60*t)+sin(2*pi*90*t);
pspectrum(x,fs,'spectrogram')
yticks([60 90])
Compute the analytic signal and differentiate its phase. Zoom in on the region enclosing the frequencies of the sinusoids. The analytic signal predicts an instantaneous frequency that is the average of the sinusoid frequencies.
z = hilbert(x); instfrq = fs/(2*pi)*diff(unwrap(angle(z))); plot(t(2:end),instfrq) ylim([60 90]) xlabel('Time (s)') ylabel('Frequency (Hz)')
The instfreq
function also estimates the average.
instfreq(x,fs,'Method','hilbert')
To estimate both frequencies as functions of time, use spectrogram
to find the power spectral density and tfridge
to track the two ridges. In tfridge
, specify the penalty for changing frequency as 0.1.
[s,f,tt] = pspectrum(x,fs,'spectrogram'); numcomp = 2; [fridge,~,lr] = tfridge(s,f,0.1,'NumRidges',numcomp); pspectrum(x,fs,'spectrogram') hold on plot3(tt,fridge,abs(s(lr)),'LineWidth',4) hold off yticks([60 90])