Эффективное узкое КИХ-создание фильтра полосы перехода

В этом примере показано, как спроектировать эффективные КИХ-фильтры с очень узкими полосами перехода, использующими многоступенчатые методы. Методы могут быть расширены к проекту многоскоростных фильтров. См. Многоступенчатый Проект Decimators/Interpolators для примера этого.

Проект фильтра Lowpass с узкой пропускной способностью перехода

Один из недостатков использования КИХ-фильтров - то, что порядок фильтра имеет тенденцию становиться обратно пропорциональным пропускной способности перехода фильтра. Рассмотрите следующие технические требования проекта (где пульсации даны в линейных модулях):

Fpass = 2866.5;   % Passband edge
Fstop = 3087;   % Stopband edge
Apass = 0.0174;  % Passband ripple, 0.0174 dB peak to peak
Astop = 66.0206; % Stopband ripple, 66.0206 dB of minimum attenuation
Fs    = 44.1e3;

lowpassSpec = fdesign.lowpass(Fpass,Fstop,Apass,Astop,Fs);

Регулярная линейная фаза equiripple проект, который соответствует спецификациям, может быть спроектирована с:

eqripFilter = design(lowpassSpec,'equiripple','SystemObject',true);
cost(eqripFilter)
ans = 

  struct with fields:

                  NumCoefficients: 695
                        NumStates: 694
    MultiplicationsPerInputSample: 695
          AdditionsPerInputSample: 694

Требуемая длина фильтра оказывается 694 касаниями.

Интерполированный КИХ (IFIR) проект

Алгоритм проекта IFIR достигает эффективного проекта для указанных выше технических условий в том смысле, что он сокращает общее количество требуемых множителей. Для этого проблема проектирования повреждается в два этапа, фильтр, который сверхдискретизирован, чтобы достигнуть строгих технических требований, не используя много множителей и фильтр, который удаляет изображения, созданные при повышающей дискретизации предыдущего фильтра.

interpFilter = design(lowpassSpec,'ifir','SystemObject',true);

По-видимому, мы сделали вещи хуже. Вместо одного фильтра с 694 множителями у нас теперь есть два фильтра с в общей сложности 804 множителями. Однако тщательное изучение вторых театрализованных представлений, что только приблизительно один множитель в 5 является ненулевым. Фактическое общее количество множителей было сокращено от 694 до 208.

cost(interpFilter)
ans = 

  struct with fields:

                  NumCoefficients: 208
                        NumStates: 802
    MultiplicationsPerInputSample: 208
          AdditionsPerInputSample: 206

Давайте сравним ответы двух проектов:

fvt = fvtool(eqripFilter,interpFilter,'Color','White');
legend(fvt,'Equiripple design', 'IFIR design','Location','Best')

Вручную управляя фактором повышающей дискретизации

В предыдущем примере мы автоматически определили фактор повышающей дискретизации, используемый таким образом, что общее количество множителей было минимизировано. Оказалось, что для данных технических требований, оптимальный фактор повышающей дискретизации равнялся 5. Однако, если мы исследуем проектные решения:

opts = designopts(lowpassSpec,'ifir') %#ok
opts = 

  struct with fields:

      FilterStructure: 'dffir'
     UpsamplingFactor: 'auto'
    JointOptimization: 0
         SystemObject: 0

мы видим, что можем управлять фактором повышающей дискретизации. Например, если мы хотели сверхдискретизировать 4, а не 5:

opts.UpsamplingFactor = 4;
opts.SystemObject = true;
upfilter = design(lowpassSpec,'ifir',opts);
cost(upfilter)
ans = 

  struct with fields:

                  NumCoefficients: 217
                        NumStates: 767
    MultiplicationsPerInputSample: 217
          AdditionsPerInputSample: 215

Мы получили бы проект, который имеет в общей сложности 217 ненулевых множителей.

Используя объединенную оптимизацию

Возможно спроектировать два фильтра, используемые в IFIR совместно. Путем выполнения так, мы можем сохранить значительное количество множителей за счет более длительного времени проектирования (из-за природы алгоритма, проект не может также сходиться в целом в некоторых случаях):

opts.UpsamplingFactor = 'auto'; % Automatically determine the best factor
opts.JointOptimization = true;
ifirFilter = design(lowpassSpec,'ifir',opts);
cost(ifirFilter)
ans = 

  struct with fields:

                  NumCoefficients: 172
                        NumStates: 726
    MultiplicationsPerInputSample: 172
          AdditionsPerInputSample: 170

Для этого проекта лучший найденный фактор повышающей дискретизации равнялся 6. Количество ненулевых множителей - теперь только 152

Используя Многоскоростные/Многоступенчатые Методы, чтобы Достигнуть Эффективных Проектов

Для проектов, обсужденных до сих пор, использовались односкоростные методы. Это означает, что количество умножения, требуемого на входную выборку (MPIS), равно количеству ненулевых множителей. Например, последний проект, который мы показали, требует 152 MPIS. Одноступенчатые equiripple проектируют, мы начали с необходимых 694 MPIS.

При помощи многоскоростных/многоступенчатых методов, которые комбинируют децимацию и интерполяцию, мы можем также получить эффективные проекты с небольшим числом MPIS. Для decimators количество умножения, требуемого на входную выборку (в среднем), дано количеством множителей, разделенных на фактор децимации.

multistageFilter = design(lowpassSpec,'multistage','SystemObject',true);
cost(multistageFilter)
ans = 

  struct with fields:

                  NumCoefficients: 396
                        NumStates: 352
    MultiplicationsPerInputSample: 73
          AdditionsPerInputSample: 70.8333

Первая стадия имеет 21 множитель и фактор децимации 3. Поэтому количество MPIS равняется 7. Второй этап имеет длину 45 и совокупный фактор децимации 6 (который является фактором децимации этого этапа, умноженного на фактор децимации первой стадии; это вызвано тем, что входные выборки к этому этапу уже входят на уровне 1/3 уровень входных выборок к первой стадии). Среднее количество умножения на входную выборку (ссылка на вход полного многоскоростного/многоступенчатого фильтра) таким образом 45/6=7.5. Наконец, учитывая, что третья стадия имеет фактор децимации 1, среднее количество умножения на вход для этого этапа является 130/6=21.667. Общее количество среднего MPIS для трех decimators 36.5.

Для интерполяторов оказывается, что фильтры идентичны decimators. Кроме того, их вычислительная стоимость является тем же самым. Поэтому общее количество MPIS для целого многоскоростного/многоступенчатого проекта равняется 73.

Теперь мы сравниваем ответы проекта equiripple и этого:

fvt = fvtool(eqripFilter,multistageFilter,'Color','White', ...
    'NormalizeMagnitudeto1','on');
legend(fvt,'Equiripple design', 'Multirate/multistage design', ...
    'Location','NorthEast')

Заметьте, что затухание в полосе задерживания для многоступенчатого проекта является о двойном тем из других проектов. Это вызвано тем, что необходимо для decimators затухать из компонентов полосы на необходимые 66 дБ во избежание искажения, которое нарушило бы необходимые технические требования. Точно так же интерполяторы должны ослабить изображения на 66 дБ для того, чтобы выполнить техническим требованиям этой проблемы.

Вручную управляя количеством этапов

Многоскоростной/многоступенчатый проект, который был получен, состоял из 6 этапов. Количество этапов определяется автоматически по умолчанию. Однако также возможно вручную управлять количеством этапов тот результат. Например:

lp4stage=design(lowpassSpec,'multistage','NStages',4,'SystemObject',true);
cost(lp4stage)
ans = 

  struct with fields:

                  NumCoefficients: 516
                        NumStates: 402
    MultiplicationsPerInputSample: 86
          AdditionsPerInputSample: 84.5000

Среднее количество MPIS для этого случая равняется 86

Групповая задержка

Мы можем вычислить групповую задержку каждого проекта. Заметьте, что многоскоростной/многоступенчатый проект вводит большую часть задержки (это - цена, чтобы заплатить за менее в вычислительном отношении дорогой проект). Проект IFIR вводит больше задержки, чем одноступенчатый проект equiripple, но меньше, чем многоскоростной/многоступенчатый проект.

fvt = fvtool(eqripFilter,interpFilter,multistageFilter,...
    'Analysis','grpdelay','Color','White');
legend(fvt, 'Equiripple design','IFIR design',...
    'Multirate/multistage design');

Фильтрация сигнала

Мы теперь показываем на примере, что IFIR и многоступенчатый/многоскоростной проект выполняют сравнительно к одноступенчатому проекту equiripple при требовании намного меньшего количества расчета. Для того, чтобы выполнить фильтрацию для каскадов, необходимо вызвать generateFilteringCode (ifirFilter) и generateFilteringCode (multistageFilter). Это уже было сделано здесь для того, чтобы создать HelperIFIRFilter и HelperMultiFIRFilter.

scope = dsp.SpectrumAnalyzer('SpectralAverages',50,'SampleRate',Fs,...
    'PlotAsTwoSidedSpectrum',false,'YLimits', [-90 10],...
    'ShowLegend',true','ChannelNames',{'Equiripple design',...
    'IFIR design','Multirate/multistage design'});
tic,
while toc < 20
    % Run for 20 seconds
    x = randn(6000,1);

    % Filter using single stage FIR filter
    y1 = eqripFilter(x);

    % Filter using IFIR filter
    y2 = HelperIFIRFilter(x);

    % Filter multi-stage/multi-rate FIR filters
    y3 = HelperMultiFIRFilter(x);

    % Compare the output from both approaches
    scope([y1,y2,y3])
end