12
\$\begingroup\$

I have tried different Fourier transform codes out there on single sine waves, and all of them produce a distributed spectrum with a resonance at the signal frequency when they should theoretically display a single bar.

The sampling frequency has little effect (10kHz here), however the number of cycles does:

One cycle:

enter image description here

100 cycles:

enter image description here

100000 cycles:

enter image description here

It looks like the fourier transform converges only for an infinite number of cycles, why is that? Shouldn't a time window of exactly one cycle bring the same results as that of N cycles?

Application: This is both out of curiosity and also because I want to get how much the step response of a first order system will be exciting the resonance of a mechanical assembly. Therefore I need an accurate Fourier transform of the response... Which I don't trust anymore. What could I do to improve the accuracy then, based on the "sine wave" case?

enter image description here

P.S: These particular screenshots are based on the code here.

\$\endgroup\$
  • 6
    \$\begingroup\$ In addition to the accepted answer, note that there's no reason to believe that the discrete-time Fourier transform (which you're calculating using the DFT) would be an impulse for an input signal that is one period of a sinusoid. The continuous-time Fourier transform of a sinusoid is an impulse, yes, but that sinusoid is infinite in duration. When you limit the signal in time, that's equivalent to multiplying by a rectangular window function. The frequency-domain result is the convolution of the impulse and the Fourier transform of the window, which is essentially what you're observing. \$\endgroup\$ – Jason R Apr 20 '15 at 12:19
  • \$\begingroup\$ Thanks for the remark. So how do you explain that if I change the NFFT number to the length of the vector, the result is a single bar? \$\endgroup\$ – Mister Mystère Apr 20 '15 at 23:15
  • 1
    \$\begingroup\$ Good question. This occurs because of an inherent assumption in the DFT. The finite-length signal given at the input of the DFT is assumed to periodically extend in both directions with infinite duration. Therefore, when you have an integer number of cycles inside the "aperture" of the DFT, you end up with the transform of an infinite-duration sinusoid: a single impulse. This corresponds to the case of exactly zero spectral leakage, and rarely occurs in practice. \$\endgroup\$ – Jason R Apr 21 '15 at 3:11
29
\$\begingroup\$

This is a windowing artifact.

The linked code pads out a 10,000 sample signal with zeroes so that the length is a power of two.

%% Author :- Embedded Laboratory

%%This Project shows how to apply FFT on a signal and its physical 
% significance.

fSampling = 10000;          %Sampling Frequency
tSampling = 1/fSampling;    %Sampling Time
L = 10000;                  %Length of Signal
t = (0:L-1)*tSampling;      %Time Vector
F = 100;                    %Frequency of Signal

%% Signal Without Noise
xsig = sin(2*pi*F*t);
...

%%Frequency Transform of above Signal
subplot(2,1,2)
NFFT = 2^nextpow2(L);
Xsig = fft(xsig,NFFT)/L;
...

Note that in the above code, the FFT is taken with the FFT size NFFT which is the next power of 2 bigger than the signal length (in this case, 16,384.) From the Mathworks fft() documentation:

Y = fft(X,n) returns the n-point DFT. fft(X) is equivalent to fft(X, n) where n is the size of X in the first nonsingleton dimension. If the length of X is less than n, X is padded with trailing zeros to length n. If the length of X is greater than n, the sequence X is truncated. When X is a matrix, the length of the columns are adjusted in the same manner.

This means that you are not actually taking a FFT of a 'pure sine wave' - you are taking the FFT of a sine wave with a flat signal after it.

This is equivalent to taking the FFT of a sine wave multiplied with a square window function. The FFT spectrum is then the convolution of the sine wave frequency spectrum (an impulse function) with the square wave frequency spectrum (sinc(f).)

If you change L = 16,384 so that there is no zero-padding of the signal, you will observe a perfect FFT.

Further search keywords: "Spectral Leakage", "Window Function", "Hamming Window".


Edit: I cleaned up some material I wrote on this topic back in university, which goes into substantially more detail. I've posted that on my blog.

\$\endgroup\$
  • \$\begingroup\$ It was right in front of my face this entire time. Well done sir, I just changed the NFFT number to the length of the vector and that did it. \$\endgroup\$ – Mister Mystère Apr 20 '15 at 11:53
  • 1
    \$\begingroup\$ @MisterMystère: See edit for link to the relevant material I wrote in university. A much more thorough explanation, including pictures. \$\endgroup\$ – Li-aung Yip Apr 20 '15 at 12:03
  • \$\begingroup\$ (Though I forgot to re-type the math formulas - fixed now.) \$\endgroup\$ – Li-aung Yip Apr 20 '15 at 12:08
  • \$\begingroup\$ Just a reminder that there is little advantage to padding to nextpow2 using matlab FFT algoriths, which I believe is fftw (fastest fourier transform in the west) \$\endgroup\$ – Scott Seidman Apr 21 '15 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.