В этом примере показано, как спроектировать эффективные КИХ-фильтры с очень узкими полосами перехода, использующими многоступенчатые методы. Методы могут быть расширены к проекту многоскоростных фильтров. См. Многоступенчатый Проект Decimators/Interpolators для примера этого.
Один из недостатков использования КИХ-фильтров - то, что порядок фильтра имеет тенденцию становиться обратно пропорциональным пропускной способности перехода фильтра. Рассмотрите следующие технические требования проекта (где пульсации даны в линейных модулях):
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 достигает эффективного проекта для указанных выше технических условий в том смысле, что он сокращает общее количество требуемых множителей. Для этого проблема проектирования повреждается в два этапа, фильтр, который сверхдискретизирован, чтобы достигнуть строгих технических требований, не используя много множителей и фильтр, который удаляет изображения, созданные при повышающей дискретизации предыдущего фильтра.
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