I would like to try to calculate y=filter(b,a,x,zi)and dy[i]/dx[j]using FFT, and not in the time domain for possible acceleration in the implementation of the GPU.
I am not sure if this is possible, especially when it ziis nonzero. I looked at how scipy.signal.lfilterscipy and filteroctave are implemented. They are executed directly in the time domain, and scipy uses direct form 2 and an octave of direct form 1 (from viewing the code in DLD-FUNCTIONS/filter.cc). I have never seen an FFT implementation similar fftfiltto FIR filters in MATLAB (ie A = [1.]).
I tried to do y = ifft(fft(b) / fft(a) * fft(x)), but it seems conceptually wrong. Also, I'm not sure how to handle the initial transition period zi. Any references pointing to an existing implementation will be appreciated.
Code example
import numpy as np
import scipy.signal as sg
import matplotlib.pyplot as plt
N = 5
b, a = sg.butter(N, .4)
MN = max(len(a), len(b))
T = 100
P = T + MN - 1
x = np.random.randn(T)
zi = np.zeros(MN-1)
ylf, zo = sg.lfilter(b, a, x, zi=zi)
af = sg.fft(a, P)
bf = sg.fft(b, P)
xf = sg.fft(x, P)
yfft = np.real(sg.ifft(bf/af * xf))[:T]
print np.linalg.norm(yfft - ylf)
plt.figure(1)
plt.clf()
plt.plot(ylf)
plt.plot(yfft)
source
share