fft importance of time sampled

3 visualizaciones (últimos 30 días)
Juan
Juan el 23 de Abr. de 2016
Editada: Juan el 23 de Abr. de 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',[])

Respuesta aceptada

Star Strider
Star Strider el 23 de Abr. de 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 comentarios
Juan
Juan el 23 de Abr. de 2016
Editada: Juan el 23 de Abr. de 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 el 23 de Abr. de 2016
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Spectral Measurements en Help Center y File Exchange.

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by