Почти во всех случаях ваш лучший выбор - это не свертка и не БПФ, а просто применение фильтра БИХ напрямую (например, с помощью функции sosfilt ()). Это будет значительно более эффективным с точки зрения использования процессора и памяти.
Будет ли это иметь числовое значение, зависит от конкретного фильтра. Единственный случай, когда может появиться какое-то различие, это если полюса расположены очень, очень близко к окружности юнитов. Даже есть несколько хитростей, которые могут помочь. НЕ ИСПОЛЬЗУЙТЕ представление передаточной функции и 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 () работает плохо при частоте среза около 15 Гц при 44,1 кГц. Для функции sosfilt () отсечка может быть намного ниже 1/100 Гц при 44,1 кГц без каких-либо проблем.
Если у вас есть проблемы со стабильностью, БПФ тоже мало чем поможет. Поскольку ваш фильтр является БИХ-фильтром, импульсный отклик бесконечен и должен быть сначала усечен. На этих очень низких частотах импульсный отклик становится настолько длинным, что БПФ также становится непрактичным.
Например, если вы хотите срезать 1/100 Гц при 44,1 кГц и хотите, чтобы динамический диапазон при импульсной характеристике составлял 100 дБ, вам нужно примерно 25 миллионов выборок !!! Это почти 10 минут при 44,1 кГц и во много, много раз дольше, чем ваш исходный сигнал