I would like to try to compute y=filter(b,a,x,zi)
and dy[i]/dx[j]
using FFTs rather than in the time domain for possible speedup in a GPU implementation.
I am not sure it's possible, particularly when zi
is non-zero. I looked through how scipy.signal.lfilter
in scipy and filter
in octave are implemented. They are both done directly in the time domain, with scipy using direct form 2 and octave direct form 1 (from looking through code in DLD-FUNCTIONS/filter.cc
). I haven't seen anywhere an FFT implementation analogous to fftfilt
for FIR filters in MATLAB (i.e. a = [1.]).
やってみy = ifft(fft(b) / fft(a) * fft(x))
ましたが、これは概念的に間違っているようです。また、初期トランジェントの処理方法がわかりませんzi
。既存の実装への参照、ポインタをいただければ幸いです。
サンプルコード、
import numpy as np
import scipy.signal as sg
import matplotlib.pyplot as plt
# create an IRR lowpass filter
N = 5
b, a = sg.butter(N, .4)
MN = max(len(a), len(b))
# create a random signal to be filtered
T = 100
P = T + MN - 1
x = np.random.randn(T)
zi = np.zeros(MN-1)
# time domain filter
ylf, zo = sg.lfilter(b, a, x, zi=zi)
# frequency domain filter
af = sg.fft(a, P)
bf = sg.fft(b, P)
xf = sg.fft(x, P)
yfft = np.real(sg.ifft(bf/af * xf))[:T]
# error
print np.linalg.norm(yfft - ylf)
# plot, note error is larger at beginning and with larger N
plt.figure(1)
plt.clf()
plt.plot(ylf)
plt.plot(yfft)