Why the amplitude of fft computing is a little bit different from a known value?

I was trying test this:
n=5000;
ts=5;
t=[0:ts/n:ts];
x1=sin(2*pi*20*t);
x2=2*sin(2*pi*60*t);
x3=20*sin(2*pi*200*t);
x4=15*sin(2*pi*350*t);
x=x1+x2+x3+x4;
N=length(x);
k=[0:N-1];
T=N/Fs;
freq=k/T;
cutoff=ceil(N/2);
X=fftn(x)/(N/2);
X=abs(X);
stem(freq(1:cutoff),X(1:cutoff))
The magnitudes got different results to 1 (x1); 2 (x2); 20 (x3) and 15 (x4). And more...if "n" has more or less points for computing the fft, the frequencies (20, 60, 200, 350) also change. Why? Can someone help me? Thanks a lot.

 Accepted Answer

You have to realize that the frequency spacing between DFT elements depends on the length of the DFT and the sampling frequency. If your frequencies do not fall directly on a DFT bin (the spacing is Fs/N where Fs is the sampling frequency and N the length of the DFT) then the energy in a particular component will be mapped to a slightly different frequency.
Here is your example the way you think it should look:
n=5000; ts=5; t=[0:ts/n:ts-ts/n];
x1=sin(2*pi*20*t); x2=2*sin(2*pi*60*t); x3=20*sin(2*pi*200*t);
x4=15*sin(2*pi*350*t); x=x1+x2+x3+x4;
xdft = fft(x);
xdft = xdft(1:length(x)/2+1);
xdft(2:end-1) = 2*xdft(2:end-1);
xdft = xdft./length(x);
df = 1000/length(x);
freq = 0:df:500;
plot(freq,abs(xdft));
xlabel('Hz'); ylabel('Magnitude');
grid on;
You may want to review this:

3 Comments

Hi, Wayne.
First , I would like to thank you about your explanation. Second, I have some doubts yet. For instance, if I change n to 512 points instead 5000, the amplitude and phase will be the same? And what change in your program?
df=1000/length(x) is the same as df = (n/ts)/lentgh(x) ?
freq = 0:df:500 is the same as freq=0:df:(n/ts)/2 ?
and I don't understand the comand:
xdft(2:end-1) = 2*xdft(2:end-1);(?)
How does it work?
Thank you for your patience.
Andre, the frequency spacing in the DFT is Fs/N where Fs is the sampling frequency and N is the number of DFT points.
If you change N = 512, then the frequency spacing is 1000/512. As a result the frequencies in your signal may not correspond to a DFT bin.
For example, your frequency spacing would be 1000/512=1.9531 and 350 is not divisible by 1.9531. Accordingly, the energy in that signal may not get perfectly mapped to one DFT bin and the amplitude estimation may be off. Did you read the example in the link I provided? That is explained.
To get the amplitude correct on a one-sided DFT magnitude plot, yo have to multiply all the frequencies that occur twice in the DFT by 2.
Yes,
df = (n/ts)/length(x);
because (n/ts) is equal to the sampling frequency.
Thank you for accepting my answer if I have helped you.
Wayne, I am sorry ask you again, but I have doubts yet. I am a little bit confused with "n" and "N". I am thinking that is the same thing. In your answer above, you keep frequency F as 1000Hz. But F = n/ts, right? So if I choose n=512, I think that length(x)=512=length(t) too, because t depends on 'n'. So DFT bin keeps constant as (n/ts)/length(x)= (512/5)/512, different from 1000/512. What am I doing wrong?
Sorry for my delay. I had some problems.
Thank you.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!