Normalization of FFT output
9 ビュー (過去 30 日間)
古いコメントを表示
In the FFT help for MATLAB R2018b there seems to be conflicting FFT normalization examples.
In the "Gaussian Pulse" example the time domain signal has lenght L and the FFT output has length n, n = nextpow2(L). The double-sided amplitude spectrum is normalized by n, i.e. the frequency domain number of points, P = abs(Y/n).
In the "Cosine Waves" examples, L and n are defined in the same way, but this time the double-sided amplitude spectrum is normalized by L, i.e the time domain number of points, P2 = abs(Y/L).
Why the difference? Which one is correct? Normalizing by the number of samples before or after zero-padding?
0 件のコメント
回答 (1 件)
David Goodmanson
2020 年 6 月 11 日
Hello Vittorio,
In the gaussian case, the waveform has died down to zero each end (technically it's not zero, but it is smaller than realmin = 2.2251e-308 and hence becomes 0 in double precision). So adding more zeros at each end makes no difference to the waveform. Zero filling is almost always pointless in my opinion. It does affect normalization since you are dividing by n instead of L, but you do end up with an acceptable result.
The cosine case is different. Here you are transforming a continuous wave, a sum of cosines at three frequencies, and the idea is to find the amplitude of each component. Initially, the signal fills the entire time window. To get the correct amplitudes in the frequency domain, you divide the fft result by L (details below).
But it's important to note that L is not only the length of the array, it's also the number of points where the CW signal is nonzero. Once you zerofill, which is a terribly bad idea in this case, the former CW wave is cut off and you add zeros that contribute nothing to the height of the peaks in the transform. So you still need to dIvide by the original L. DIviding by n gives a result for amplitudes that is too small by a factor of L/n, which is the duty cycle of the signal in the new expanded time window.
** dividing by L: Suppose the time array (of length L) has array index m and array spacing delt. Consider a signal of frequency f0 and amplitude A. Then signal = A*exp(2*pi*i*f0*m*delt).
For the set of frequencies 'fn' in the frequency domain, each amplitude 'an' is
an = sum{m=0,L-1} A*exp(2*pi*i*f0*m*delt).*exp(-2*pi*i*fn*m*delt)
When fn matches f0, there is a sum of L identical terms that equal A, which produces L*A. So you have to divide by L to get back to an = A.
When zerofilling is done, there are still only L points that contribute to this sum, and the result is still L*A.
[the foregoing ignored some inessential off-by-one indexing issues].
参考
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!