Je voudrais essayer de calculer y=filter(b,a,x,zi)
et dy[i]/dx[j]
en utilisant des FFT plutôt que dans le domaine temporel pour une accélération possible dans une implémentation GPU.Filtre de calcul (b, a, x, zi) en utilisant FFT
Je ne suis pas sûr que ce soit possible, en particulier lorsque zi
est différent de zéro. J'ai regardé à travers comment scipy.signal.lfilter
dans Scipy et filter
dans l'octave sont mis en œuvre. Ils sont tous deux faits directement dans le domaine temporel, avec scipy utilisant la forme directe 2 et la forme directe d'octave 1 (en regardant le code en DLD-FUNCTIONS/filter.cc
). Je n'ai vu nulle part une implémentation FFT analogue à fftfilt
pour les filtres FIR dans MATLAB (c'est-à-dire a = [1.]).
J'ai essayé de faire y = ifft(fft(b)/fft(a) * fft(x))
mais cela semble être une erreur conceptuelle. En outre, je ne suis pas sûr de savoir comment gérer le transitoire initial zi
. Toute référence, pointeur vers une implémentation existante, serait appréciée.
Exemple de code,
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)
Merci. Il semble que ce code calcule les spectres de puissance des signaux sonores. Je n'ai pas pu trouver où le filtrage IRR via FFT a lieu. – Paul