The Fourier transform is a mathematical formula that relates a signal sampled in time or space to the same signal sampled in frequency. In signal processing, the Fourier transform can reveal important characteristics of a signal, namely, its frequency components.
The Fourier transform is defined for a vector with uniformly sampled points by
is one of complex roots of unity where is the imaginary unit. For and , the indices and range from to .
fft function in MATLAB® uses a fast Fourier transform algorithm to compute the Fourier transform of data. Consider a sinusoidal signal
x that is a function of time
t with frequency components of 15 Hz and 20 Hz. Use a time vector sampled in increments of of a second over a period of 10 seconds.
t = 0:1/50:10-1/50; x = sin(2*pi*15*t) + sin(2*pi*20*t); plot(t,x)
Compute the Fourier transform of the signal, and create the vector
f that corresponds to the signal's sampling in frequency space.
y = fft(x); f = (0:length(y)-1)*50/length(y);
When you plot the magnitude of the signal as a function of frequency, the spikes in magnitude correspond to the signal's frequency components of 15 Hz and 20 Hz.
The transform also produces a mirror copy of the spikes, which correspond to the signal's negative frequencies. To better visualize this periodicity, you can use the
fftshift function, which performs a zero-centered, circular shift on the transform.
n = length(x); fshift = (-n/2:n/2-1)*(50/n); yshift = fftshift(y); plot(fshift,abs(yshift))
In scientific applications, signals are often corrupted with random noise, disguising their frequency components. The Fourier transform can process out random noise and reveal the frequencies. For example, create a new signal,
xnoise, by injecting Gaussian noise into the original signal,
xnoise = x + 2.5*gallery('normaldata',size(t),4);
Signal power as a function of frequency is a common metric used in signal processing. Power is the squared magnitude of a signal's Fourier transform, normalized by the number of frequency samples. Compute and plot the power spectrum of the noisy signal centered at the zero frequency. Despite noise, you can still make out the signal's frequencies due to the spikes in power.
ynoise = fft(xnoise); ynoiseshift = fftshift(ynoise); power = abs(ynoiseshift).^2/n; plot(fshift,power) title('Power')
Using the Fourier transform formula directly to compute each of the elements of requires on the order of floating-point operations. The fast Fourier transform algorithm requires only on the order of operations to compute. This computational efficiency is a big advantage when processing data that has millions of data points. Many specialized implementations of the fast Fourier transform algorithm are even more efficient when is a power of 2.
Consider audio data collected from underwater microphones off the coast of California. This data can be found in a library maintained by the Cornell University Bioacoustics Research Program. Load and format a subset of the data in
bluewhale.au, which contains a Pacific blue whale vocalization. You can use the command
sound(x,fs) to listen to the entire audio file.
whaleFile = 'bluewhale.au'; [x,fs] = audioread(whaleFile); whaleMoan = x(2.45e4:3.10e4); t = 10*(0:1/fs:(length(whaleMoan)-1)/fs); plot(t,whaleMoan) xlabel('Time (seconds)') ylabel('Amplitude') xlim([0 t(end)])
Specify a new signal length that is the next power of 2 greater than the original length. Then, use
fft to compute the Fourier transform using the new signal length.
fft automatically pads the data with zeros to increase the sample size. This padding can make the transform computation significantly faster, particularly for sample sizes with large prime factors.
m = length(whaleMoan); n = pow2(nextpow2(m)); y = fft(whaleMoan,n);
Plot the power spectrum of the signal. The plot indicates that the moan consists of a fundamental frequency around 17 Hz and a sequence of harmonics, where the second harmonic is emphasized.
f = (0:n-1)*(fs/n)/10; % frequency vector power = abs(y).^2/n; % power spectrum plot(f(1:floor(n/2)),power(1:floor(n/2))) xlabel('Frequency') ylabel('Power')