1

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

Paradox
  • 738
  • 12
  • 30
BloodyMary
  • 173
  • 13
  • See the scale of the frequency amplitudes in the second graph. They are practically zero (of the order of [`eps`](https://es.mathworks.com/help/matlab/ref/eps.html)). The result seems to be correct, up to [floating-point inaccuracies](https://stackoverflow.com/a/686454/2586922) – Luis Mendo Jul 28 '17 at 09:02
  • 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 Jul 28 '17 at 09:20
  • 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 Jul 28 '17 at 09:26
  • 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 Jul 28 '17 at 10:03
  • Do you agree with closing this question as a duplicate of [this](https://stackoverflow.com/q/686439/2586922)? So it won't appear as unanswered – Luis Mendo Jul 28 '17 at 10:11
  • 1
    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 Jul 28 '17 at 10:23
  • You are right, it's not exactly the same. Besides, there's a proper answer now – Luis Mendo Jul 28 '17 at 10:25

1 Answers1

1

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.

Paradox
  • 738
  • 12
  • 30
  • Thank you very much! Luis already explained it to me, but thank you for your long answer with MATLAB codes. I already use them to set a limit to filter those numerical errors - it works just fine! :) – BloodyMary Jul 28 '17 at 10:49
  • Happy to help! :) – Paradox Jul 28 '17 at 12:37