In quasi tutti i casi la scelta migliore non è né convoluzione né FFT, ma semplicemente applicando direttamente il filtro IIR (usando ad esempio la funzione sosfilt ()). Ciò sarà notevolmente più efficiente in termini di consumo di CPU e memoria.
La differenza numerica dipende dal filtro specifico. L'unico caso in cui una certa differenza può insinuarsi è se i poli sono molto, molto vicini al cerchio dell'unità. Anche lì alcuni trucchi che possono aiutare. NON UTILIZZARE la rappresentazione e il filtro della funzione di trasferimento () ma utilizzare poli e zero con sosfilt (). Ecco un esempio per la differenza.
n = 2^16; % filter length
fs = 44100; % sample rate
x = zeros(n,1); x(1) = 1;
f0 = 15; % cutoff frequency in Hz
% design with poles and zeroes
[z,p,k] = butter(5,f0*2/fs);
clf
plot(sosfilt(zp2sos(z,p,k),x));
% design with transfer function
[b,a] = butter(5,f0*2/fs);
hold on
plot(filter(b,a,x),'k');
filter () si guasta con un cutoff di circa 15Hz @ 44.1kHz. Per sosfilt () il cutoff può essere ben al di sotto di 1/100 di Hz a 44,1 kHz senza problemi.
Se hai problemi di stabilità, anche la FFT non aiuta molto. Poiché il filtro è un filtro IIR, la risposta all'impulso è infinita e dovrebbe essere prima troncata. A queste frequenze molto basse la risposta all'impulso diventa così lunga che anche la FFT diventa poco pratica.
Ad esempio, se si desidera un taglio di 1/100 Hz a 44,1 kHz e si desidera un intervallo dinamico nella risposta all'impulso di 100 dB, sono necessari circa 25 milioni di campioni !!! Sono quasi 10 minuti a 44,1 kHz e molte, molte volte più lunghe del segnale originale