FFT spectral leak?

36 views (last 30 days)
Yi-xiao Liu
Yi-xiao Liu on 9 Nov 2022
Commented: Yi-xiao Liu on 10 Nov 2022
I find that in the power spectrum returned by fft the amplitude of peaks are much smaller than expected, even for artifical signals. This is in contrast to the examples given in documation
openExample('matlab/FFTOfNoisySignalExample')
I wonder what can be done to improve? Increasing sampling rate seem to have very little effect.
t=linspace(0,10,1e4);
x=1*cos(7e1*t)+2*cos(3e2*t);
%should make peaks at 70 and 300 with amplitude of 1 and 2
[omega,P1]=fft1D(t,x);
plot(omega,P1)
function [omega,P1]=fft1D(t,x)
L=numel(t);
Fs=L/(max(t)-min(t));
xfft = fft(x);
P2 = abs(xfft/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
omega = Fs*(0:(L/2))/L*2*pi;
end
  1 Comment
Marcel Kreuzberg
Marcel Kreuzberg on 9 Nov 2022
in the example 'matlab/FFTOfNoisySignalExample' the intervall parameters are defined first.
if you play in your example with the line t=linspace(0,10,1e4) you will get different peak values as the fft is not the exact analytic result

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 9 Nov 2022
hello
the amplitude accuracy depends if your signal frequency matches or not the fft frequency vector bins . If not your estimated amplitudes will be slghtly off, depending of the frequency mismatch between fft bins and actual signal frequency and also what king of window you are using (or none).
you can play with example below to see the effects (mismatch, window)
to make it simple I choose fs = samples = 500 so df = 1 Hz.
if your signals have integer frequencies, amplitudes are exact , if not... see by yourself and try with hanning window for improved amplitude computation.
samples = 500;
dt = 2e-3; % fs = 500 Hz
t=(0:samples-1)*dt;
x=1*cos(2*pi*40*t)+2*cos(2*pi*70*t); % case 1 : signal frequencies are exact match with fft bins (fft freq points are separated by df = fs/nfft and nfft = samples)
% x=1*cos(2*pi*40.2*t)+2*cos(2*pi*70.3*t); % case 2 : signal frequencies are not exact match with fft bins
% FFT plot
[f1,fft_spectrum1] = do_fft(t,x);
figure(1)
plot(f1,fft_spectrum1,'-*')
title('Scheme 1')
ylabel('|X(f)|')
xlabel('Frequency[hz]')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [freq_vector,fft_spectrum] = do_fft(time,data)
time = time(:);
data = data(:);
dt = mean(diff(time));
Fs = 1/dt;
nfft = length(data); % maximise freq resolution => nfft equals signal length
%% use windowing or not at your conveniance
% no window
fft_spectrum = abs(fft(data))*2/nfft;
% % hanning window
% window = hanning(nfft);
% window = window(:);
% fft_spectrum = abs(fft(data.*window))*4/nfft;
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_spectrum = fft_spectrum(select,:);
freq_vector = (select - 1)*Fs/nfft;
end
  3 Comments
Mathieu NOE
Mathieu NOE on 10 Nov 2022
sure - hanning is a bit the everyday solution by default (for guys like me working on noise and vibration data) but cleary the window type must be carefully selected depending of signal type and your expectations
internet is ful of publications about what window for which job and performance...
Yi-xiao Liu
Yi-xiao Liu on 10 Nov 2022
Yes, many of them compare different window in terms of spectral accuracy and amplitude accuracy.
I wonder, however, why don't people use uniform window (no window) to identify frequencies first then flat top to determine the amplitude of these frequencies to get the best of both worlds?

Sign in to comment.

More Answers (0)

Categories

Find more on Fourier Analysis and Filtering in Help Center and File Exchange

Tags

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!