ほとんどすべての場合、最良の選択は畳み込みでもFFTでもなく、IIRフィルターを直接適用するだけです(たとえばsosfilt()関数を使用)。これは、CPUとメモリの消費の点で非常に効率的です。
数値が異なるかどうかは、特定のフィルターによって異なります。いくつかの違いが忍び寄る唯一のケースは、極が単位円に非常に近い場合です。役立つトリックもいくつかあります。伝達関数表現とfilter()を使用しないで、sosfilt()で極と零点を使用してください。違いの例を次に示します。
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()は、約15Hz @ 44.1kHzのカットオフで悪くなります。sosfilt()の場合、カットオフは44.1kHzの1/100 Hzを大幅に下回ることができ、問題はありません。
安定性に問題がある場合、FFTはあまり役に立ちません。フィルターはIIRフィルターであるため、インパルス応答は無限であり、最初に切り捨てる必要があります。これらの非常に低い周波数では、インパルス応答が非常に長くなるため、FFTも実用的ではなくなります。
たとえば、44.1 kHzで1/100 Hzのカットオフが必要で、100 dBのインパルス応答のダイナミックレンジが必要な場合、およそ2500万サンプルが必要です!!! これは44.1 kHzでほぼ10分で、元の信号よりも何倍も長くなります