119
$\begingroup$

It's very easy to filter a signal by performing an FFT on it, zeroing out some of the bins, and then performing an IFFT. For instance:

t = linspace(0, 1, 256, endpoint=False)
x = sin(2 * pi * 3 * t) + cos(2 * pi * 100 * t)
X = fft(x)
X[64:192] = 0
y = ifft(X)

The high frequency component is completely removed by this "brickwall" FFT filter.

But I've heard this is not a good method to use.

  • Why is it generally a bad idea?
  • Are there circumstances in which it's an ok or good choice?

[as suggested by pichenettes]

$\endgroup$
0

4 Answers 4

142
$\begingroup$

Zeroing bins in the frequency domain is the same as multiplying by a rectangular window in the frequency domain. Multiplying by a window in the frequency domain is the same as circular convolution by the transform of that window in the time domain. The transform of a rectangular window is the Sinc function ($\sin(\omega t)/\omega t$). Note that the Sinc function has lots of large ripples and ripples that extend the full width of time domain aperture. If a time-domain filter that can output all those ripples (ringing) is a "bad idea", then so is zeroing bins.

These ripples will be largest for any spectral content that is "between bins" or non-integer-periodic in the FFT aperture width. So if your original FFT input data is a window on any data that is somewhat non-periodic in that window (e.g. most non-synchronously sampled "real world" signals), then those particular artifacts will be produced by zero-ing bins.

Another way to look at it is that each FFT result bin represents a certain frequency of sine wave in the time domain. Thus zeroing a bin will produce the same result as subtracting that sine wave, or, equivalently, adding a sine wave of an exact FFT bin center frequency but with the opposite phase. Note that if the frequency of some content in the time domain is not purely integer periodic in the FFT width, then trying to cancel a non-integer periodic signal by adding the inverse of an exactly integer periodic sine wave will produce, not silence, but something that looks more like a "beat" note (AM modulated sine wave of a different frequency). Again, probably not what is wanted.

Conversely, if your original time domain signal is just a few pure unmodulated sinusoids that are all exactly integer periodic in the FFT aperture width, then zero-ing FFT bins will remove the designated ones without artifacts.

$\endgroup$
8
  • 8
    $\begingroup$ This answer has good stuff, but I would prefer more of a focus on the Gibbs effect. $\endgroup$
    – Jim Clay
    Commented Dec 10, 2012 at 2:04
  • 5
    $\begingroup$ An attempt to get an answer to the Gibbs effect was already asked here: dsp.stackexchange.com/questions/1144/… $\endgroup$
    – hotpaw2
    Commented Dec 10, 2012 at 2:45
  • 1
    $\begingroup$ @hotpaw2 This is a good explanation. However, I need a reference to this and am finding some difficulty in identifying one. It is the reason we do time domain filtering rather than work in the frequency domain. (Also, time domain can be real time.) However, nobody seems to start by stating this! $\endgroup$
    – Hugh
    Commented Feb 17, 2018 at 8:55
  • $\begingroup$ How can this be related with the window method for filter design? $\endgroup$ Commented May 17, 2019 at 11:47
  • 1
    $\begingroup$ Thanks @hotpaw2 for explanation. I am Software developer working in Speech processing and i haven't had a formal education in DSP. Neither do I understand the question completely nor I can begin to understand to your excellent answer.. but the question sounded interesting for me ! I just have one query: If i had to understand this answer and question completely who has no background in SignalProcessing/DSP. Where do i begin from ? Are there any course or standard books that can help understand ? Ones with elegant explanation with not too much math. Thanks. $\endgroup$
    – stonelazy
    Commented Jul 10, 2022 at 2:50
14
$\begingroup$

This question has also confused me for a long time. @hotpaw2's explanation is good. You may be interested in the simple experiment using matlab.

https://poweidsplearningpath.blogspot.com/2019/04/dftidft.html


updated information.

To verify this fact is simple, we just need to cautiously observe the spectrum of impulse response of an ideal(?) band pass filter which just zeros out FFT bins. Why do I need to add the adverb "cautiously"? If we just use the same size of the FFT to observe the response of the impulse, we will be deceived as shown in Fig 1. Nonetheless, if we add the order of DFT when observing the output of the filter, that is, zero padding the impulse response, we can find the so called Gibbs phenomenon, ripples in frequency domain, as depicted in Fig 2.

The results in fact comes from the windowing effect. If you want to entirely understand the problem, please refer to chapter 7.6 and chapter 10.1-10.2 of the bible of DSP (1). To sum up, three key points are noted here.

  1. Size of window and order of DFT(FFT) are totally independent. Don't mix them together.
  2. Properties of window (type/size) dominate the shape of DTFT. (ex. wider main lobe lead to wider transient band in frequency response.)
  3. DFT is just the sampling of DTFT in frequency domain. Moreover, the higher the order of DFT, the denser the spectrum of DFT is.

So, with the help of denser spectrum in Fig.2, we can see through the mask of ideal(fake) Band pass filter.

enter image description here Deceitfully Freq. Response.

enter image description here Gibbs phenomenon in Freq. Response.

(1) Alan V. Oppenheim and Ronald W. Schafer. 2009. Discrete-Time Signal Processing (3rd ed.). Prentice Hall Press, Upper Saddle River, NJ, USA.

fps = 15;

LPF = 1;
HPF = 2;

n = -511:512;
n0 = 0;
imp = (n==n0);

NyquistF = 1/2*fps;

%% Ideal BPF
tmp_N = 512;
tmp_n = 0:1:tmp_N-1;
freq = ( n .* fps) ./ tmp_N;
F = fft(imp, tmp_N);  
F_bpf = IdealBandpassFilter(F, fps, LPF, HPF);
imp_rep =[real(ifft(F_bpf))'];

% Zero padding.
imp_rep2 =[zeros(1,2048) real(ifft(F_bpf))' zeros(1,2048)];

N = 2^nextpow2(length(imp_rep));
F = fft(imp_rep,N);
freq_step = fps/N;
freq = -fps/2:freq_step:fps/2-freq_step;
freq = freq(N/2+1:end)';

figure;
plot(freq,abs(F(1:N/2)));
xlabel('freq(Hz)');
ylabel('mag');
title('Mis leading Freq Response');


N = 2^nextpow2(length(imp_rep2));
F = fft(imp_rep2,N);
freq_step = fps/N;
freq = -fps/2:freq_step:fps/2-freq_step;
freq = freq(N/2+1:end)';

figure;
plot(freq,abs(F(1:N/2)));
xlabel('freq(Hz)');
ylabel('mag');
title('Zero Padding (DFT) with more points');

%% Function
function filered_signal = IdealBandpassFilter(input_signal, fs, w1, w2)

    N = length(input_signal);
    n = 0:1:N-1;
    freq = ( n .* fs) ./ N;

    filered_signal = zeros(N, 1);

    for i = 1:N
        if freq(i) > w1 & freq(i) < w2
            filered_signal(i) = input_signal(i);
        end

    end
end
$\endgroup$
1
  • $\begingroup$ I think there may be a little bug in your code. "F = fft(imp, tmp_N);" should be "F = fft(imp, 2*tmp_N);". As a result, the filter designed by zeroing bins is not as bad as the figure you show. $\endgroup$
    – ecook
    Commented Apr 12, 2022 at 2:00
1
$\begingroup$

FFT gives poor time resolution i.e it doesn't give information at what time that particular frequency exist. It gives information on existing frequency components for given signal duration.

By zeroing bins in FFT gives poor resolution after IFFT in time domain.

$\endgroup$
3
  • $\begingroup$ however there are computational difficulties for very long signal to take fft and then ifft. To avoid zitters/ringing filtering of a signal has to be transit smoothly from pass band to stop band. $\endgroup$ Commented Apr 5, 2018 at 5:58
  • 4
    $\begingroup$ "FFT gives poor time resolution" FFT gives no time resolution, it's a spectral domain transform and so, like said afterwards, gives only information about frequency components of a signal. $\endgroup$
    – EdParadox
    Commented Aug 5, 2019 at 15:11
  • 3
    $\begingroup$ The resolution provided by an FFT is the length of it's window. Anything outside the FFT's window is not resolved as being inside the FFT's window. $\endgroup$
    – hotpaw2
    Commented Aug 31, 2019 at 5:50
1
$\begingroup$

Zeroing is a good idea if

  1. What's being zeroed is already zero
  2. What's being zeroed is very close to zero

1 is actually optimal and is what's proven by the sampling theorem. It's not a "no-op" in that it could be a step in decimation - then doing nothing corresponds to subsampling. 2 works because the DFT is stable in sense of norms, roughly meaning small change in one domain $\Leftrightarrow$ small change in other. These are important to note because any kind of filtering is, in almost all cases, a deformation, and there's many ways to filter wrong.

The next-best alternative is what's flat in frequency domain over frequencies of interest, so freqs aren't scaled relative to each other - but the filter's time-domain behavior also matters, so Layman's safest is to go with known filters, e.g. Hann-windowed sinc. Since it's convolution, choice of padding also becomes important.

Why it's bad in general: refer to hotpaw's answer.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.