FFT real/imaginary/abs parts interpretation
Asked Answered
R

4

26

I'm currently learning about discret Fourier transform and I'm playing with numpy to understand it better.

I tried to plot a "sin x sin x sin" signal and obtained a clean FFT with 4 non-zero points. I naively told myself : "well, if I plot a "sin + sin + sin + sin" signal with these amplitudes and frequencies, I should obtain the same "sin x sin x sin" signal, right?

Well... not exactly

(First is "x" signal, second is "+" signal)

enter image description here

Both share the same amplitudes/frequencies, but are not the same signals, even if I can see they have some similarities.

Ok, since I only plotted absolute values of FFT, I guess I lost some informations.

Then I plotted real part, imaginary part and absolute values for both signals :

enter image description here

Now, I'm confused. What do I do with all this? I read about DFT from a mathematical point of view. I understand that complex values come from the unit circle. I even had to learn about Hilbert space to understand how it works (and it was painful!...and I only scratched the surface). I only wish to understand if these real/imaginary plots have any concrete meaning outside mathematical world:

  • abs(fft) : frequencies + amplitudes
  • real(fft) : ?
  • imaginary(fft) : ?

code :

import numpy as np
import matplotlib.pyplot as plt
N = 512 # Sample count
fs = 128 # Sampling rate
st = 1.0 / fs # Sample time
t = np.arange(N) * st # Time vector

signal1 = \
1   *np.cos(2*np.pi * t) *\
2   *np.cos(2*np.pi * 4*t) *\
0.5 *np.cos(2*np.pi * 0.5*t)

signal2 = \
0.25*np.sin(2*np.pi * 2.5*t) +\
0.25*np.sin(2*np.pi * 3.5*t) +\
0.25*np.sin(2*np.pi * 4.5*t) +\
0.25*np.sin(2*np.pi * 5.5*t)



_, axes = plt.subplots(4, 2)

# Plot signal
axes[0][0].set_title("Signal 1 (multiply)")
axes[0][0].grid()
axes[0][0].plot(t, signal1, 'b-')

axes[0][1].set_title("Signal 2 (add)")
axes[0][1].grid()
axes[0][1].plot(t, signal2, 'r-')

# FFT + bins + normalization
bins = np.fft.fftfreq(N, st)    
fft  = [i / (N/2) for i in np.fft.fft(signal1)]
fft2 = [i / (N/2) for i in np.fft.fft(signal2)]

# Plot real
axes[1][0].set_title("FFT 1 (real)")
axes[1][0].grid()
axes[1][0].plot(bins[:N/2], np.real(fft[:N/2]), 'b-')

axes[1][1].set_title("FFT 2 (real)")
axes[1][1].grid()
axes[1][1].plot(bins[:N/2], np.real(fft2[:N/2]), 'r-')

# Plot imaginary
axes[2][0].set_title("FFT 1 (imaginary)")
axes[2][0].grid()
axes[2][0].plot(bins[:N/2], np.imag(fft[:N/2]), 'b-')

axes[2][1].set_title("FFT 2 (imaginary)")
axes[2][1].grid()
axes[2][1].plot(bins[:N/2], np.imag(fft2[:N/2]), 'r-')

# Plot abs
axes[3][0].set_title("FFT 1 (abs)")
axes[3][0].grid()
axes[3][0].plot(bins[:N/2], np.abs(fft[:N/2]), 'b-')

axes[3][1].set_title("FFT 2 (abs)")
axes[3][1].grid()
axes[3][1].plot(bins[:N/2], np.abs(fft2[:N/2]), 'r-')

plt.show()
Retroflexion answered 2/9, 2014 at 13:26 Comment(0)
T
48

For each frequency bin, the magnitude sqrt(re^2 + im^2) tells you the amplitude of the component at the corresponding frequency. The phase atan2(im, re) tells you the relative phase of that component. The real and imaginary parts, on their own, are not particularly useful, unless you are interested in symmetry properties around the data window's center (even vs. odd).

Tass answered 2/9, 2014 at 15:2 Comment(3)
Thank to both you and hotpaw2. I think I understand it much better now. I didn't even know the existence of atan2!Retroflexion
Questions?: 1) I assume the real part of the complex number squared is positive, right? 2) What is sign of the imaginary part of the complex number when it is squared? Is it negative because sqrt(-1)**2 is -1?Data
@ox.: no, think of complex numbers as re + j * im. So both re and im are real values, and both re^2 and im^2 will be positive.Tass
I
20

With respect to some reference point, say the center of a fixed time window, a sine wave and a cosine wave of the same frequency will look different (have different starting phases with respect to any fixed time reference point). They will also be mathematically orthogonal over any integer periodic width, so can represent independent basis vector components of a transform.

The real portion of an FFT result is how much each frequency component resembles a cosine wave, the imaginary component, how much each component resembles a sine wave. Various ratios of sine and cosine components together allow one to construct a sinusoid of any arbitrary or desired phase, thus allowing the FFT result to be complete.

Magnitude alone can't tell the difference between a sine and cosine wave. An IFFT(imag(FFT)) would screw up the reconstruction of any signal with a different phase than pure cosines. Same with IFFT(re(FFT)) and pure sine waves (with respect to the FFT aperture window).

Incorrigible answered 2/9, 2014 at 15:43 Comment(3)
That gives clear picture of the relation between basis components of the a transform. But would you please elaborate the last part? "An IFFT(imag(FFT)) would screw up the reconstruction of any signal with a different phase than pure cosines."Convalescence
You can't reconstruct any pure cosine wave with any finite set of sine waves (referenced to the same phase starting point).Incorrigible
Thanks for "rephrasing". I totally agree with you. Signal either IFFT(Im(FFT)) or IFFT(Re(FFT)) from a single basis component does not contribute to the other (its orthogonal).Convalescence
E
3

You can convert the signal 1, which consists of a product of three cos functions to a sum of four cos functions. This makes the difference to function 2 which is a sum of four sine functions.

A cos function is an even function cos(-x) == cos(x). The Fourier Transformation of an even function is pure real. That is the reason why the plot of the imaginary part of the fft of function 1 contains only values close to zero (1e-15).

A sine function is an odd function sin(-x) == -sin(x). The Fourier Transformation of an odd function is pure imaginary. That is the reason why the plot of the real part of the fft of function 2 contains only values close to zero (1e-15).

If you want to understand FFT and DFT in more detail read a textbook of signal analysis for electrical engineering.

Einsteinium answered 3/9, 2014 at 15:10 Comment(1)
You are right, I didn't not submit the good example (sin/cos). Well, I do read various textbooks, websites, watch videos, a DSP mooc, but they mostly consist of some intimidating (at least for me) mathematical concepts and formulas and require some extra investigation like this one. I begin to understand them but I still have a long way to go. Thank to the previous answers, I can now reconstruct manually any signal by adding cosine sub-signals (since original signal is real) with corresponding magnitudes and phases. The phase formula was the key I was missing. That why I accepted Paul R answerRetroflexion
A
0

Although ... you must be a good expert now :) For others: Please notice that with this set of Correct mathematical equation so correcting the sum as:

    signal1 = \
1   *np.cos(2*np.pi * t) *\
2   *np.cos(2*np.pi * 4*t) *\
0.5 *np.cos(2*np.pi * 0.5*t)

signal2 = \
0.25*np.cos(-2*np.pi * 2.5*t) +\
0.25*np.cos(2*np.pi * 3.5*t) +\
0.25*np.cos(-2*np.pi * 4.5*t) +\
0.25*np.cos(2*np.pi * 5.5*t)

Now gives following result

(Now results are)

So point is that real part should also be the same

Aftergrowth answered 23/4, 2020 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.