Я хотел бы попытаться вычислить y=filter(b,a,x,zi)
и dy[i]/dx[j]
, используя FFT, а не во временной области для возможного ускорения в реализации GPU.
Я не уверен, что это возможно, особенно когда zi
не равен нулю.Я посмотрел, как реализованы scipy.signal.lfilter
в scipy и filter
в октаве.Они оба делаются непосредственно во временной области, при этом scipy использует прямую форму 2 и октавную прямую форму 1 (из просмотра кода в DLD-FUNCTIONS/filter.cc
).Я нигде не видел реализации FFT, аналогичной fftfilt
для FIR-фильтров в MATLAB (то есть 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)