# Accuracy of time-domain filters and frequency domain filters

I am trying to calculate the Hilbert transform using 3 different method: scipy.signal.hilbert function, time domain filter, and frequency domain filter.

The test signal is $$1/(1+t^{2})$$, and its Hilbert transform is $$t/(1+t^{2})$$. In this result, the time domain filter is more accurate than scipy hilbert and frequency domain filter.

For the other test signal $$\cos(2\pi ft)$$, its Hilbert transform is $$\sin(2\pi ft)$$, where $$f=127$$Hz. When the signal is in $$[0,1)$$ second, The frequency domain filter is more accurate than time domain filter. When the signal is in $$[0,0.35)$$ second, The time domain filter is more accurate than frequency domain filter.

I am wondering what is the reason that the time domain filter or frequency domain filter are more accurate than the other one. Are there any requirements to use time domain filter or frequency domain filter?

Here's the code for the first test signal.

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal,fft

fs = 4096
time = np.arange(-10,10.,1./fs)
sig = 1/(1+time**2)

analytic_signal = signal.hilbert(sig)
amplitude_envelope = np.abs(analytic_signal)
instantaneous_phase = np.unwrap(np.angle(analytic_signal))
instantaneous_frequency = (np.diff(instantaneous_phase) / (2.0*np.pi) * fs)

order = 50001
co = [2*np.sin(np.pi*n/2)**2/np.pi/n for n in range(1, order+1)]
co1 = [2*np.sin(np.pi*n/2)**2/np.pi/n for n in range(-order, 0)]
co = co1+[0]+ co

out = signal.convolve(sig, co, mode='same', method='fft')

analytic_signal2 = sig + 1j*out
amplitude_envelope2 = np.abs(analytic_signal2)
instantaneous_phase2 = np.unwrap(np.angle(analytic_signal2))
instantaneous_frequency2 = (np.diff(instantaneous_phase2) / (2.0*np.pi) * fs)

sig_f = fft.fft(sig)
sig_f[0:int(len(sig_f)/2)] *= -1j
sig_f[int(len(sig_f)/2):len(sig_f)] *= 1j
new_sig = fft.ifft(sig_f)

analytic_signal3 = sig + 1j*new_sig
amplitude_envelope3 = np.abs(analytic_signal3)
instantaneous_phase3 = np.unwrap(np.angle(analytic_signal3))
instantaneous_frequency3 = (np.diff(instantaneous_phase3) / (2.0*np.pi) * fs)

plt.plot(time,np.imag(analytic_signal)-sig*time,linewidth=2,label='Scipy hilbert')
plt.plot(time,out-sig*time,label='Time domain')
plt.plot(time,new_sig-sig*time,label='Freq domain')
plt.title(r'$$1/(1+t^{2})$$')
plt.xlabel('Time [s]')
plt.ylabel('Error')
plt.legend()
plt.show()


• You need to edit your question. You do not define what you mean by "time domain filter" and "frequency domain filter". All filters, digital or analog, that are applied to real signals in the real world are applied in the time domain. We can tell ourselves differently, but at best we will be in error. Since there are an infinite number of "time domain filters" and you used just one -- specify it, in math, not just code. Since there are an infinite number of possible "frequency domain filters" and since the name is questionable -- specify it, in math. Commented Jul 11, 2021 at 20:38

The test signal is $$1/(1+t^2)$$
No, it's not. Not if you represent it in a computer as a list of numbers. $$1/(1+t^2)$$ is not bandlimited, that means you can't sample it without aliasing. Furthermore, by doing an FFT you also sample the spectrum which means you have an infinite periodic repetition in the time domain as well.