MATLAB: Comparison of FFT codes

fft

Hello Matlab community,
I am trying to wrap my head around sampling frequencies and the FFT code. I have used the following example: https://www.mathworks.com/help/matlab/ref/fft.html
The code I copied from the link above provides results which seem to have the correct amplitudes (0.7 and 1) but danse around the exact frequency (49.3-50.7 and 119.3-120.7 ish). The exact code I used is:
Fs = 1000; % Sampling frequency

T = 1/Fs; % Sampling period

L = 1500; % Length of signal

t = (0:L-1)*T; % Time vector
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
f = Fs*(0:(L/2))/L;
Y = fft(S);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
plot(f,P1)
title('Single-Sided Amplitude Spectrum of S(t)')
xlabel('f (Hz)')
ylabel('|P1(f)|')
Wherease the code I developed using what I think is logical (based on my limited programming knowledge) gives almost the exact frequencies (50 and 120, but tapper outward below 0.025 amplitude), but reduced amplitudes (0.6971 and 0.9765):
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sampling period
L = 1500; % Length of signal
for t=0:T:L
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
x(round(t/T)+1,1)=S;
time(round(t/T)+1,1)=t;
f(round(t/T)+1,1) = Fs*t/L;
end
f1 = f(1:Fs*L/2+1);
fftx = fft(x);
P2 = abs(fftx/(Fs*L));
P1 = 2*P2(1:Fs*L/2+1);
plot(f1,P1)
xlabel('Frequency [Hz]')
ylabel('Amplitude [V]')
title('FFT')
What gives?? In my mind these codes seem equivalent… Also, what does the following line in the example provided in the link above mean:
P1(2:end-1) = 2*P1(2:end-1);
It seems to give the same results whether that line of code is there or not…

Best Answer

Compare size(S) between the two cases and you'll see the difference--and do you see why there is that difference?
The difference in amplitude in a single bin is owing to whether the frequency grid exactly matches the input frequencies of the signal or not -- if it does, then the entire energy is in that one bin; if it isn't quite lined up on a bin (as your second isn't, again why?) then the total energy is "smeared" across bins and you have to integrate the peak to get the total energy.
I've previously submitted documentation enhancement request to TMW that there should be additional explanation of the normalization factor--the two-sided FFT returns half the signal power in the negative frequency and half in positive; P2 is the two-sided PSD estimate. P1 is then the one-sided (positive frequency) PSD so the total energy is 2X the two-sided. But there's only one DC and one Fmax bin so the 2:end-1 prevents doubling those compoonents. Since the noiseless signal is zero-mean, there is no DC and there is also no power at Fmax for a clean signal not undersampled so Fmax component is also just rounding noise in magnitude. Hence, for the given input it doesn't matter but for real world data can be significant. You'll see some effect if you go on to the example with noise.
So, whether the subscriptiing expression is used or not makes no real difference in the example, but you'll only get half the magnitude it you don't use the 2X factor at all (to state the obvious explicity?).
Had long discussion some months ago on the subject where posted a bunch of examples...you might search for Answers I wrote with subject including PSD or FFT--unfortunately I have to run right now and I don't have a link to past stuff at hand.