0

I'm looking for the most abundant frequency in a periodic signal. I'm trying to understand what do I get if I perform a Fourier transformation on a periodic signal and filter for frequencies which have negative fft values.

In other words, what do the axis of plots 2 and 3 (see below) express? I'm plotting frequency (cycles/second) over the fft-transformed signal - what do negative values on the y axis mean, and would it make sense that I'd be interested in only those?

import numpy as np
import scipy

# generate data
time = scipy.linspace(0,120,4000)
acc = lambda t: 10*scipy.sin(2*pi*2.0*t) + 5*scipy.sin(2*pi*8.0*t) + 2*scipy.random.random(len(t))
signal = acc(time)

# get frequencies from decomposed fft
W =  np.fft.fftfreq(signal.size, d=time[1]-time[0])
f_signal = np.fft.fft(signal)

# filter signal
# I'm getting only the "negative" part!
cut_f_signal = f_signal.copy()
# filter noisy frequencies
cut_f_signal[(W < 8.0)] = 0
cut_f_signal[(W > 8.2)] = 0

# inverse fourier to get filtered frequency
cut_signal = np.fft.ifft(cut_f_signal)

# plot
plt.subplot(221)
plt.plot(time,signal)
plt.subplot(222)
plt.plot(W, f_signal)
plt.subplot(223)
plt.plot(W, cut_f_signal)
plt.subplot(224)
plt.plot(time, cut_signal)
plt.show()

Fourier transform and signal filtering

afrendeiro
  • 2,423
  • 2
  • 23
  • 22
  • BTW, a rectangular filter (zeroing out bins) in the frequency domain is an incredibly noisy non-flat filter with potential for tons of ripple and ringing. – hotpaw2 Jan 22 '15 at 01:28

2 Answers2

5

The FFT of a real-valued input signal will produce a conjugate symmetric result. (That's just the way the math works best.) So, for FFT result magnitudes only of real data, the negative frequencies are just mirrored duplicates of the positive frequencies, and can thus be ignored when analyzing the result.

However if you want to do the inverse and compute the IFFT, you will need to feed the IFFT a conjugate symmetric negative half (or upper half, above Fs/2) of frequency data, or else your IFFT result will end up producing a complex result (e.g. with non-zero imaginary (sqrt(-1)) components, rarely what one want when dealing with base-band real data).

If you want to filter the FFT data and end up with real results from an IFFT, you will need to filter the positive and negative frequencies symmetrically identically to maintain the needed symmetry.

The FFT also produces a complex result, where the value and sign the components (real and imaginary) of each result bin represents the phase as well as the magnitude of the component basis vector (complex sinusoid, or real cosine plus real sine components). Any negative value just represents a phase rotation from if the same result was positive.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • Thanks for the input, however, my question is not about the negative frequency values (which are the mirror of the positive ones) - in my example on the x axis, but about the negative ones in the y axis which come from the FFT - what do they mean? – afrendeiro Jan 22 '15 at 10:01
  • Answer updated regarding signed complex FFT results. – hotpaw2 Jan 22 '15 at 18:03
  • Thanks also for the hint on filtering noise symmetricaly – afrendeiro Jan 23 '15 at 09:38
0

As @hotpaw2 already wrote in his comment above, the result of a FFT performed on a real signal in time domain generates complex values in frequency domain.

The input value f_signal of your plot command is a vector of complex values.

plt.subplot(222)
plt.plot(W, f_signal)

This results in meaningless output. You should plot the absolute values of f_signal. If you are interested in the phase you should plot the angle, too. In Matlab this would look like this:

% Plot the absolute values of f_signal
plot(W, abs(f_signal));
% Plot the phase of f_signal
plot(W, (unwrap(angle(f_signal)));
Heinz M.
  • 668
  • 3
  • 8