fft importance of time sampled

3 Ansichten (letzte 30 Tage)
Juan
Juan am 23 Apr. 2016
Bearbeitet: Juan am 23 Apr. 2016
I guessed that the longer one samples, the most exact result with fft. And so it seems to do with frequency, but not at all with amplitude. The amplitude decreases the longer the time sampled. Did I do something wrong ? Is this reasonable? Thanks to any help
% T=[.01 .02 .1 .2 1];
% T=[1:10]
T=[1 5 10];
n=10; % maximal number of harmonic
freq = 5;
Fs = 150e4; % Sampling frequency (frecuencia de muestreo)
nfft = 1e7; % Length of FFT % number of fft bins
tic
for m=1:length(T)
t = 0:1/Fs:T(m); % Time vector of 1 second
x = cos(2*pi*t*freq); % sine wave of f Hz.
x = x-mean(x);% restamos de la fcn 'x' su DC offset
figure(1);
subplot(length(T),1,m);
plot(t,x,'.');
% Take fft, padding with zeros so that length(X) is equal to nfft
X = fft(x,nfft);
% FFT is symmetric, throw away second half
X = X(1:nfft/2);
% Scaling is done here using the number of samples: length(x)/2
X=X/(length(x)/2);
% Take the magnitude of fft of x
mx = abs(X);
% Frequency vector
f_fft = (0:nfft/2-1)*Fs/nfft;
f_Axis=f_fft(1:nfft/2);
% picos de amplitud
pks= findpeaks(mx(1:nfft/2));
n=min(n,length(pks));
pks_sort=sort(pks,'descend');% vector de picos
for k = 1:n
locs=find(mx(1:nfft/2)==pks_sort(k));
f(k)=f_Axis(locs);
end
% bar plot freq y magnitude
figure
uds='Amp';
pks_sort=pks_sort(:); % to make it column array for text of bar plot
f=f(:); % to make it column array for text of bar plot
subplot(1,2,1)
bar(pks_sort(1:n),'r');
ylabel({sprintf('Amplitude (%s)'...
,uds)},'fontweight','bold','fontsize',16);
text(1:n,pks_sort(1:n),num2str(pks_sort(1:n),'%.2f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
subplot(1,2,2)
bar(f(1:n),'b');
ylabel('Frequency (Hz)','fontweight','bold','fontsize',16);
text(1:n,f(1:n),num2str(f(1:n),'%.2f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
bar3d_pks_sort(m,:)=pks_sort(1:n);
bar3d_f(m,:)=f(:);
end
figure;
col(1,:)=[0 0 1]; col(2,:)=[0 .5 0];
plot(bar3d_pks_sort(:,1),'-+','Color',col(1,:),'Linewidth',2);
h1 = gca;
h2 = axes('Position',get(h1,'Position'));
plot(bar3d_f(:,1),'-o','Color',col(2,:),'Linewidth',2);
set(h1,'YColor',col(1,:))
set(h2,'YAxisLocation','right','Color','none','XTickLabel',[],'YColor',col(2,:))
set(h2,'YAxisLocation','right','Color','none','XTickLabel',[])

Akzeptierte Antwort

Star Strider
Star Strider am 23 Apr. 2016
You have to normalise the Fourier transform by the length of the time-domain vector.
So this line should be:
Fn = Fs/2; % Nyquist Frequency
% Take fft, padding with zeros so that length(X) is equal to nfft
X = fft(x,nfft)/nfft;
... and the following line is then:
% FFT is symmetric, throw away second half
Fv = linspace(0, 1, fix(X/2)+1)*Fn; % Frequency Vector (For Plots, &c.)
Iv = 1:length(Fv); % Index Vector
X = X(1:nfft(Iv))*2;
The current documentation is a bit confusing. Much more straightforward description is in the R2015a fft documentation.
I didn’t go through the rest of your code, but that should correct some of it.
  2 Kommentare
Juan
Juan am 23 Apr. 2016
Bearbeitet: Juan am 23 Apr. 2016
magnitude scale and thus nfft variable were the key
Thanks!
The only thing to change is:
nfft=fix(length(x)/2)*2;
There is some written about scale in fft fucntion, but as Star Strider says, its a bit confusing.
I read <http://es.mathworks.com/help/matlab/ref/fft.html?searchHighlight=fft matlab fft guide > . Sumerized it says:
Datf = fft(Data,N) specifies the transformation length. In the default case, the length of the transformation is determined by the signal length. A second argument N will force FFT transformations of length N, padding with zeros if the signals in Data are shorter and truncating otherwise. Thus the number of frequencies in the real signal case will be N/2 or (N+1)/2. If Data contains several experiments, N can be a row vector of corresponding length.
I misunderstood The number of frequencies in the real signal case will be N/2. I interpreted as fft check only for frequencies as high as N (e.g. till frequency N=150 Hz). And thats false, it checks N/2 difference frequencies, no till N/2 frequency.
If anyone fancys to try the code solved complete just copy-paste this:
% T=[.01 .02 .1 .2 1];
% T=[2:2:8];
T=[1 5 10];
n=10; % maximal number of harmonic
freq = 5;
Fs = 150e4; % Sampling frequency (frecuencia de muestreo)
tic
for m=1:length(T)
t = 0:1/Fs:T(m); % Time vector of 1 second
x = cos(2*pi*t*freq); % sine wave of f Hz.
x = x-mean(x);% rest DC offset
nfft=fix(length(x)/2)*2; % KEY OF THIS QUESTION !!!
figure(1);
subplot(length(T),1,m);
plot(t,x,'.');
% Take fft, padding with zeros so that length(X) is equal to nfft
X = fft(x,nfft);
% FFT is symmetric, throw away second half
X = X(1:nfft/2);
% Scaling is done here using the number of samples: length(x)/2
X=X/(length(x)/2);
% Take the magnitude of fft of x
mx = abs(X);
% Frequency vector
f_fft = (0:nfft/2-1)*Fs/nfft;
f_Axis=f_fft(1:nfft/2);
pks= findpeaks(mx(1:nfft/2));
n=min(n,length(pks));
pks_sort=sort(pks,'descend');
for k = 1:n
locs=find(mx(1:nfft/2)==pks_sort(k));
f(k)=f_Axis(locs);
end
% bar plot freq and magnitude
figure
uds='Amp';
pks_sort=pks_sort(:);
f=f(:);
subplot(1,2,1)
bar(pks_sort(1:n),'r');
ylabel({sprintf('Amplitude (%s)'...
,uds)},'fontweight','bold','fontsize',16);
text(1:n,pks_sort(1:n),num2str(pks_sort(1:n),'%.2f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
subplot(1,2,2)
bar(f(1:n),'b');
ylabel('Frequency (Hz)','fontweight','bold','fontsize',16);
text(1:n,f(1:n),num2str(f(1:n),'%.2f'),...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom')
bar3d_pks_sort(m,:)=pks_sort(1:n);
bar3d_f(m,:)=f(:);
end
figure;
bar3(bar3d_pks_sort);
figure;
bar3(bar3d_f);
figure;
col(1,:)=[0 0 1]; col(2,:)=[0 .5 0];
plot(bar3d_pks_sort(:,1),'-+','Color',col(1,:),'Linewidth',2);
text(1:m,bar3d_pks_sort(:,1),num2str(bar3d_pks_sort(:,1)),...
'HorizontalAlignment','right','Color','red','FontSize',14)
h1 = gca;
h2 = axes('Position',get(h1,'Position'));
plot(bar3d_f(:,1),'-o','Color',col(2,:),'Linewidth',2);
set(h1,'YColor',col(1,:))
set(h2,'YAxisLocation','right','Color','none','XTickLabel',[],'YColor',col(2,:))
set(h2,'YAxisLocation','right','Color','none','XTickLabel',[])
toc
Star Strider
Star Strider am 23 Apr. 2016
As always, my pleasure!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by