# Noisy Frequency Estimation using Hilbert Transform

I'm looking for a way to estimate instantenous frequency with low time-variation. The following MATLAB function (save as test_fest.m) does this using the Hilbert transform on a single 10 Hz sine tone. Sample rate f_s is 1000 Hz.

function test_fest()
%TEST_FEST()  Test Frequency Estimation using Various Techniques.

fS = 1000;
f = [10]';                                  % Sine Wave Frequency
nFFT = fS;
x = sin(linspace(zeros(length(f),1), f*2*pi, fS));
X = hilbert(x,nFFT);

fE = diff(unwrap(angle(X))) * fS / (2*pi); % Frequency Estimate
eE = mean((fE/f-1).^2); % MSQ Error

plot(fE,'.');
title(sprintf('Hilbert Transform Instantaneous Frequency Estimation of Sine Wave f=%.2f Hz, f_S=%g Hz, Mean-Square Error:%.2g', f, fS, eE))


Output is shown here:

I, however, get a greater error, 2.3e-5, than I expected. Is there something wrong with my approach?

Digital Hilbert transform is tricky to do since an ideal Hilbert transformer requires an FIR filter with an impulse response from -infinity to +infinity. Obviously that can't be done, so numerical problems are unavoidable. They tend to be worst at low frequencies so my guess is you'd see a smaller error at, say, 100 Hz. Andrew Duncan's paper "The Analytic Impulse" is thorough analysis of what the digital Hilbert transform can and can't do. See http://www.andrewduncan.ws/air/index.html

Some alternative methods of measuring frequency have been discussed here: Is there an algorithm for finding a frequency without DFT or FFT?