The script below filters frequencies by cutting of all frequencies larger than 6.
However instead of using the seemingly correct function rfftfreq
, fftfreq
is being used.
To my understandnig rfftfreq
should be used together with rfft
. Why does this code work although it uses fftfreq
with rfft
?
import numpy as np
from scipy.fftpack import rfft, irfft, fftfreq
time = np.linspace(0,10,2000)
signal = np.cos(5*np.pi*time) + np.cos(7*np.pi*time)
W = fftfreq(signal.size, d=time[1]-time[0])
f_signal = rfft(signal)
# If our original signal time was in seconds, this is now in Hz
cut_f_signal = f_signal.copy()
cut_f_signal[(W<6)] = 0
cut_signal = irfft(cut_f_signal)
Background: rfft
gives an array sorting the fourier modes with real and imaginery in separate entries. Such as [R(0), R(1), I(1), ... R(N/2),I(N/2)]
for R(n)
and I(n)
being the real and imaginery part of the fourier mode respectively. (assuming an even entry array)
Therefore, rfftfreq
yields an array of frequencies corresponding to this array such as (assuming an even entry array and sampling spacing of 1):
[0, 1/n, 1/n, 2/n, 2/n ... n/(2n), n/(2n)]
However this code works with fftfreq
where the output of the function is
[0, 1/n, ... n/(2n), -n/(2n), ..., -1/n]
Clearly, fftfreq
should lead to wrong results when used together with rfft
because the frequencies and FFT bins do not match.