1
votes

I have two main questions, but starting from the beginning: I wanted to know how FFT (fast Fourier transform) works on real examples. I created two sinusoidal waves (for example Wave1 = 5 Hz and Wave2 = 15 Hz amplitude), then I added those two and made FFT from third "Wave3". It looks OK - I saw my "peaks" around 5 and 15 Hz.

Blue = 5 Hz, Red = 15 Hz, Yellow = Blue + Red. FFT from "Yellow" Wave, looks good:

Blue = 5 Hz, Red = 15 Hz, Yellow = Blue + Red. FFT from "Yellow" Wave, looks good

OK, and then I have changed the data. Now I have two waves with identical amplitudes but opposite phases. If I add them, their amplitude is 0 - and that seems correct to me.

Two waves with opposite phases. Yellow - Wave1+Wave2 + Strange FFT of the yellow wave:

Two waves with opposite phases. Yellow - Wave1+Wave2 + Strange FFT of yellow wave

And now is the part that I don't understand at all. Here are my questions:

1) Even if I see on the picture that this third Yellow wave has an amplitude equal to 0, it's not like that in data tables. After adding two main waves (and they have opposite data!) I get the strange result.

Example: 5 first points in the data

Wave 1:

  • 0,0627905195293128
  • 0,125333233564304
  • 0,187381314585724
  • 0,248689887164855
  • 0,309016994374947

Wave 2:

  • -0,0627905195293134
  • -0,125333233564304
  • -0,187381314585724
  • -0,248689887164855
  • -0,309016994374947

Wave 3 (Sum) :

  • -5,68989300120393e-16
  • -1,11022302462516e-16
  • -1,11022302462516e-16
  • 3,05311331771918e-16
  • -1,11022302462516e-16

Why the sum of these waves is not equal 0, as it is shown in the picture? Why FFT looks so strange? Is there even a possibility that FFT will show us the real amplitudes of two identical waves with opposite phases? I thought it will not, but what's the truth?

Here is my MATLAB code:

THREE WAVES:

D = 1; % 1 second
S = 1000; % sampling rate
P = 0.5; % phase
T = 1/S; % sampling period
t = [T:T:D]; % time
myphi=2*pi*P;
myphi2=2*pi*1;

syn3 = sin(2*10*t*pi+myphi); % first wave
syn2 = sin(2*10*t*pi+myphi2); % second wave
sinmax=syn2+syn3; % yellow wave

figure; plot(t,syn3,t,syn2,t,sinmax,'LineWidth',2); grid on;
xlabel('Time (seconds)');
ylabel('Amplitude');

FFT CODE:

L = length(sinmax);
myFFT = fft(sinmax,S);
myFFT=myFFT/L; %scale the output to 1
freq = S/2*linspace(0,1,S/2);
figure; stem(freq,abs(myFFT(1:length(freq))));
xlabel('Frequency (Hz)');
ylabel('Amplitude');

Thank you very much in advance...

Mary

1
See the scale of the frequency amplitudes in the second graph. They are practically zero (of the order of eps). The result seems to be correct, up to floating-point inaccuracies - Luis Mendo
Hi! Thank you for your reply! OK, so as I understand the data are good (ie. there is no bug in my code), and because of my scale I cannot really see that the "yellow" line is not flat, as it seems to be. That's ok and thank you. I do not understand yet, why adding "0,125.." with "-0,125.." is not "0" but something like "-1,11". And why the FFT looks so strange, as if this yellow wave was composed of all these frequencies from 0 to 500 Hz? There is something I do not understand in physics. I thought there was going to be a destructive interference. Isn't it? - BloodyMary
The FFT amplitudes you see in the second graph are about 10^16 times smaller than in the first. They should be 0, but they are not exactly 0 because of small numerical errors. As a simpler example, try sin(pi/4)-sqrt(2)/2 and you'll see it doesn't give exactly 0. So it's not something strange with physics; it's just numerical issues. If you plot the two FFT's on the same axes, the second one will actually look like zero in comparison with the first - Luis Mendo
Oh! Now I understand, so it's all about numerical errors on those small numbers and about scales. Thank you very much for your answer! - BloodyMary
Yes, your answer is good. You can close this topic, although I think it's not quite the same as the topic you mentioned. It's more about understanding not only how Matlab works, but also about FFT and waves: more noobs like me may find your answer interesting. Thank you once again :). - BloodyMary

1 Answers

1
votes

First things first, your calculations are correct.

Because the two graphs are auto-resized, it is easy to make a mistake interpreting them but the amplitudes are way smaller on the 2nd one than the 1st (10e-16 vs. 10e1, respectively).

On the 2nd graph, the one which leaves you puzzled, you are just victim of numerical errors : these numbers can be interpreted as 0.

From there, you have two simple solutions :

  1. you are fine with the results you have, and you can just tweak the figures to display results on the same scale to avoid any misleading interpretation
  2. you would like to have "proper zero values" instead of "small ones"

1) Set a limit for the Y-axis

You can just add something like this line (it is just an example - change it to meet your needs) when plotting your figures :

ymax = max(abs(my_fft));
ymin = - ymax;
ylim([ymin ymax])

2) Set a limit for filtering numerical errors

Like in a lot of numerical methods algorithms, you might want to consider as 0 values which are in between 0 and small interval, often called epsilon :

 abs_fft = abs(my_fft);
 epsilon = 10e-12 % your threshold
 abs_fft(abs_fft < epsilon) = 0;

You might want to check out eps which is a built-in Matlab variable, meant for this kind of cases.