FFT spectral leak?
34 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
Marcel Kreuzberg
2022 年 11 月 9 日
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
採用された回答
Mathieu NOE
2022 年 11 月 9 日
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 件のコメント
Mathieu NOE
2022 年 11 月 10 日
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...
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Fourier Analysis and Filtering についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!