# How to avoid leakage in the following FFT

I have written a code for FFT for a signal which time domain plot and FFT is shown bellow.

I am not sure about what FFT length to do in order to avoid leakage of energy?

I know the number periods has to be integer, but i cant see how to implement this principle in here practically.

Also I get an amplitude which is very far from 5 5 10 as written in the time domain signal.

Where did i go wrong?

    clc
clear all
Fs=200e3;
Ts=1/Fs;
dt=0:Ts:5e-3-Ts;

f1=1e3;
f2=20e3;
f3=30e3;

y=5*sin(2*pi*f1*dt)+5*sin(2*pi*f2*dt)+5*sin(2*pi*f1*dt)+10*sin(2*pi*f3*dt);
%plot(dt,y)
nfft=length(y);
nfft2=2.^nextpow2(nfft);
fy=fft(y,nfft2);
f_half=fy(1:(nfft2/2));
xfft=Fs.*(0:nfft2/2-1)/nfft2;
plot(xfft,abs(f_half));


fixed final:

clc
clear all
Fs=200e3;
Ts=1/Fs;
dt=0:Ts:5e-3-Ts;

f1=1e3;
f2=20e3;
f3=30e3;

y=5*sin(2*pi*f1*dt)+5*sin(2*pi*f2*dt)+10*sin(2*pi*f3*dt);
%plot(dt,y)
nfft=length(y);
nfft2=1000;
fy=fft(y,nfft2);
f_half=2*fy(1:(nfft2/2));
xfft=Fs.*(0:(nfft2/2)-1)/nfft2;
plot(xfft,abs(f_half)/(nfft));


Updated FFT conv FIR

clc
clear all
Fs=200e3;
Ts=1/Fs;
dt=0:Ts:5e-3-Ts;

f1=1e3;
f2=20e3;
f3=30e3;

y=5*sin(2*pi*f1*dt)+5*sin(2*pi*f2*dt)+10*sin(2*pi*f3*dt);
%plot(dt,y)
nfft=length(y);
nfft2=1000;
fy=fft(y,nfft2);
f_half=2*fy(1:(nfft2/2));
xfft=Fs.*(0:(nfft2/2)-1)/nfft2;
%plot(xfft,abs(f_half)/(nfft));

cut_off=25e3/(Fs/2);
order=64;
h=fir1(order,cut_off);
con=conv(y,h)
%plot(con)
fz=fft(con,nfft2);
f_half_z=2*fz(1:(nfft2/2));
plot(xfft,abs(f_half_z)/(nfft));


Updated with filter response plot:

clc
clear all
Fs=200e3;
Ts=1/Fs;
dt=0:Ts:5e-3-Ts;

f1=1e3;
f2=20e3;
f3=30e3;

y=5*sin(2*pi*f1*dt)+5*sin(2*pi*f2*dt)+10*sin(2*pi*f3*dt);
%plot(dt,y)
nfft=length(y);
nfft2=1000;
fy=fft(y,nfft2);
f_half=2*fy(1:(nfft2/2));
xfft=Fs.*(0:(nfft2/2)-1)/nfft2;
%plot(xfft,abs(f_half)/(nfft));

cut_off=25e3/(Fs/2);
order=32;
h=fir1(order,cut_off);
fh=fft(h,nfft2);
plot(abs(fh(1:nfft/2)));
con=conv(y,h)
%plot(con)
fz=fft(con,nfft2);
f_half_z=2*fz(1:(nfft2/2));
%plot(xfft,abs(f_half_z)/(nfft));
$$$$

• So, you know that the period of the signal needs to fit into the FFT length an integer amount of times. You know the period, right? So, where's the exact problem? – Marcus Müller Mar 17 at 16:29
• Hello Marcus,We have three signals in here ,suppose i take the highest fd=30000 cycles/sec. i am having problem with connecting the numbers in this terms. the sinus period is 5 micro second,we sample our signal each 5e^-6 till 0.005 sec,so in total we have 1000 samples of the signal. but we do fft on 1024 members ,so our frequency range(0-200Khz) is divided by 1024. I have tried to implement the formula for leakage of the code i posted shown in the link bellow. It doesnt give me whole integer number. How do i choose the parameters for my 3 sinuses? ibb.co/KqXNt1S Thanks. – rocko445 Mar 17 at 17:47
• you realize that period is inverse to frequency, so your period is the least common mulitple of all the periods of the periodic components. – Marcus Müller Mar 17 at 18:10
• In case Marcus's hints are too subtle, or my answer doesn't manage to transmit the message: you have a 1000 points time sequence, on which you perform a 1024 points FFT, and which gives you spectral leakage due to the mismatch in the ratios. What can be done to match the ratio? – a concerned citizen Mar 17 at 22:30
• There are two answers to the question in the comment above: either match the number of samples to the FFT, or vice-versa. You did he first, I was aiming for the second, since you said you have to perform an FFT of 1024 points. so you could have just chosen f1=1024, f2=20*f1, f3=30*f1. Either way it works. – a concerned citizen Mar 18 at 18:57

Since your frequencies f2 and f3 are a multiple of f1=1k, and since your time vector is until 5 ms, that means your signal fits for a whole 5 periods, harmonics and all, so it's just ripe for a FFT. The problem you're having is that you chose the FFT to be of a number of points (1024) different than the number of samples (1000), so now one bin will be Fs/nfft = 2e5/1024 = 195.31 Hz. If you check the first values of the frequency vector xfft(1:10), you'll see that the first frequency falls in between two bins:

            0
1.9531e+02
3.9062e+02
5.8594e+02
7.8125e+02
9.7656e+02 % f1 is between this
1.1719e+03 % ...and this
1.3672e+03
1.5625e+03
1.7578e+03


The other two have the same symptom. This means the amplitude (which is not normalized, that's why it's ~5k) can't be the real one. When the equivalent DFT will calculate the butterflies, the indices will not match f1 at the same spot. If you would have performed the FFT for 1000 points, the bins would have been 2e5/1e3 = 200 Hz in width. That would have made the frequency vector display these frst 10 values:

      0
200
400
600
800
1000 % spot on
1200
1400
1600
1800


Using a 1024 length FFT means now there are more than one butterfly with different values, and they all add up. Which means you have a mild case of spectral leakage, i.e. the frequency that should have been present in one bin, only, is spreading across its neighbours. Also see the Wikipedia article.

• Hello,So if my basic common frequency is 1000Hz then i need my FFT to be of the length of the basic frequency 1000. Fd=1000Hz Fs=200000Hz N=1000 ,So its 1000,000/200,000=5. I have normalised the result by 1000 as shown in the plot link and the text code bellow. i get 2.5, 2.5, 5 amp. Oiler formula says sinus will be displayed by two harmonics. Why sinus 30Khz where presented in 30Khz and 170Khz by FFT using oiler formula? Thanks. photo link of oiler formula: ibb.co/Mp4hJQV photo link of spectrum plot: ibb.co/ZNtspqC Text code: textuploader.com/18ivu – rocko445 Mar 18 at 16:06
• @rocko445 Euler's formula has nothing to do with harmonics here. The reason you see two images of the same sine is related to mirroring due to the sampling. – a concerned citizen Mar 18 at 16:25
• Hello,then why we get half the amplitude in both of them? but sinus is represented by two harmonics not one. Why in the FFT it is represented with one and half the amplitude?Thanks. – rocko445 Mar 18 at 16:39
• @rocko445 Your normalization is off by a factor of 2 then. Try 2/Nfft`. – a concerned citizen Mar 18 at 16:56
• @rocko445 Your question has been answered. What you want is not part of it, so make a new one. – a concerned citizen Mar 18 at 17:09