To Get Correct FFT Result the length(x) must be An Integral Multiple of 100?

조회 수: 6 (최근 30일)
Hi, all
I'm trying to get the amplitude- frequency relationship and phase- frenquency relationship using fft. My signal is given by:
t=0:0.005:14; % Time [s] Where mod(length(t),100)~=0
% t=t=0:0.005:14; t(end)=[]; % Where mod(length(t),100)==0
Vs=10*cos(2*pi*20*t-pi/5)+13*cos(2*pi*60*t+pi/6);
Spectrum=fft(Vs)/length(Vs);
Spectrum(2:end-1)=Spectrum(2:end-1)*2;
To get the amplitude and the phase of the signal of specified frequency, I used:
Amplitude=abs(Spectrum);
Phase=angle(Spectrum);
The question is, if the length(Vs) is an integral multiple of 100 (100,2700, etc.), the programe returns a correct amplitude and phase like:
Both Amplitude and Phase value at the DC, 20Hz, 40Hz is the setting value. However, once the length(Vs) is not of an integral multiple of 100, the same program returns a totally wrong result like:
I don't know the reason, and I want a method by which I can get right Spectrum no matter what the length(Vs) is.(On the premise of guaranteeing sampling theorem).
Thanks

채택된 답변

Paul
Paul 2021년 7월 7일
편집: Paul 2021년 7월 8일
The desired plot will be obtained when N, the number of elements of t, is an integer multiple of the ratios Fs/Fn, where Fs is the sample frequency and Fn are the frequencies in Vs (in Hz). In this case we have
Fs = 200;
Fn = [20 60];
Given these vaues, selecting N = k*100 will satisy the criterion:
syms k N
N = k*sym(100);
N*sym(Fn)./sym(Fs) % integer valued for all integer k
ans = 
Here is the "good" case in the question:
N = 2800;
N.*Fn./Fs % integer
ans = 1×2
280 840
tfinal = func(N,Fs,Fn)
tfinal = 13.9950
Here is another case, where N satisfies the criteria, but is not a muliple of 100
N = 2820;
N.*Fn./Fs % integer
ans = 1×2
282 846
tfinal = func(N,Fs,Fn)
tfinal = 14.0950
As you already showed, choosing N = 2801, which does not satisfy the criterion, results in an undesired plot
N = 2801;
N.*Fn./Fs % not both integers
ans = 1×2
280.1000 840.3000
tfinal = func(N,Fs,Fn)
tfinal = 14
Note this result is not wrong. It is correct based on the input parameters.
function tfinal = func(N,Fs,Fn)
t = (0:(N-1))/Fs;
Vs = 10*cos(2*pi*Fn(1)*t-pi/5)+13*cos(2*pi*Fn(2)*t+pi/6);
Spectrum = fft(Vs)/length(Vs);
Spectrum(2:end-1) = Spectrum(2:end-1)*2;
Amplitude = abs(Spectrum);
Phase = angle(Spectrum);
figure;
stem((0:N-1)/N*Fs,Amplitude)
xlim([0 Fs/2])
xlabel('Hz')
tfinal = t(end);
end
  댓글 수: 2
Ziyu Hua
Ziyu Hua 2021년 7월 8일
Thanks Paul, you kind answer is exactly correct and very helpful.
So if I want to get the correct phase and amplitude of a signal of a given frequency, I need to balance the value of N,Fn, Fs carefully.
But in some case, I just has a signal and I don't know the frequency component of signal, which means I don't know the Fn of my signal. Is there a method that I could get correct amplitude and phase of a signal of unknow frequency?
Paul
Paul 2021년 7월 8일
I don't think so. As you said, you don't know exactly what you're looking for (otherwise, you wouldn't have to look for it). All you have is the dat you're given. If even perfectly measuring a pure tone, it's not likely the data will be perfectly matched between N, Fn, and Fs to perfectly figure out the fequency. With N and Fs large enough, you can get pretty close. I think you're touching on basic questions of how signal processing engineers (I'm not one of them) do their art of analyzing data. As is always the case, the more you know about the problem domain, the better off you'll be in selecting an approach to analyze the data and what conclusions to draw from that analysis.
Have a look at some of the examples in the documentation in the Signal Processing Toolbox, such as
doc pspectrum
particularly the sections on "Window Leakage and Resolution" and "More About."

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

LO
LO 2021년 7월 7일
편집: LO 2021년 7월 7일
the fft function will give you values as precise as the sampling rate of the signal. If it is a noisy signal, error can be caused by that too. Your result does not seem "totally wrong", simply "slightly off". The FFT analyzes your data with a sliding window, so you get several points analyzed at a time. Perhaps when the values are "round" then the resuls are rounded as well.
you can try to increse the signal resolution (using a fit fnction - like "polyfit") or you can try smoothen it (using "smooth" or "smoothdata"), to remove some noise. Noise could be filtered out if it is at constant frequency using bandstop filters (see documentation of "filt").
  댓글 수: 2
Ziyu Hua
Ziyu Hua 2021년 7월 7일
Thanks LO.
This problem is not caused by the noise, because the Vs in the above code is totally defined by the cos function as I mentioned in the code and has no initial noise. Vs is addition of ideal specific frequency elements in terms of cos. This is more likely an error caused by the method I use fft function, but I don't know why.
The document of fft function in the mathwork.com use signal of length in an integral multiple of 100 as well. And the situation where this premise does not hold is not mentioned in official document.
LO
LO 2021년 7월 7일
편집: LO 2021년 7월 7일
I use the FFT function as well and I have no problem with frequencies that are not multiples of 100.
have you tried specifying a fixed length for the FFT analysis ?
Y = fft(X,n);
or use alternatively the pwelch function, get the power as argument, and then find your power spectrum with the equation 10*log10*p
fs = 1000; % sampling rate
nfft= N; % size of FFT window
window= rectwin(nfft); % return a rectangular window
[p,f]= pwelch(x,window,0,nfft,fs); % W/Hz power spectral density within window
PS = 10*log10(p); % your power spectrum

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Fourier Analysis and Filtering에 대해 자세히 알아보기

태그

제품


릴리스

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by