ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

遷移帯域が狭い FIR フィルターの効率的な設計

この例では、多段手法を使用する、遷移帯域が非常に狭い場合でも効率的な FIR フィルターの設計方法を示します。この手法は、マルチレート フィルターの設計にも応用できます。これに関する例は、「間引き/内挿の多段設計」を参照してください。

遷移帯域が狭いローパス フィルターの設計

FIR フィルターを使用する欠点の 1 つに、フィルターの遷移帯域に反比例してフィルター次数が増加する傾向にあることが挙げられます。以下の設計仕様 (リップルが線形単位で指定されている場合) を考えます。

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;

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

この仕様を満たす通常の線形位相等リップル設計は、以下のように設計できます。

FIR = design(LP,'equiripple','SystemObject',true);
cost(FIR)
 
ans =
 
Number of Multipliers            : 695
Number of Adders                 : 694
Number of States                 : 694
Multiplications per Input Sample : 695
Additions per Input Sample       : 694

必要なフィルター長は 694 タップになります。

内挿 FIR (IFIR) の設計

IFIR 設計アルゴリズムを使用すると、必要な乗数の合計数が減少するため、上述の仕様を効率的に設計することができます。これを行うには、多数の乗数を使用せずに厳格な仕様を満たすためにアップサンプルしたフィルターと、前のフィルターのアップサンプル時に作成されたイメージを削除するフィルターの 2 ステージに設計を分割します。

IFIR = design(LP,'ifir','SystemObject',true);

明らかに状況は悪くなっています。ここでは、694 乗数のシングル フィルターの代わりに、合計 804 乗数の 2 つのフィルターがあり、乗数が明らかに以前よりも増えています。しかし、第 2 ステージの詳細を見ると、約 5 分の 1 の乗数のみが非ゼロであることがわかります。これにより乗数の実際の合計数が 694 から 208 に削減されます。

cost(IFIR)
 
ans =
 
Number of Multipliers            : 208
Number of Adders                 : 206
Number of States                 : 802
Multiplications per Input Sample : 208
Additions per Input Sample       : 206

2 つの設計の応答を比較します。

hfvt = fvtool(FIR,IFIR,'color','White');
legend(hfvt,'Equiripple design', 'IFIR design','Location','Best')

アップサンプリング係数の手動制御

前の例では、乗数の合計数が最小化されるように使用するアップサンプリング係数を自動的に決定しました。この仕様では、最適なアップサンプリング係数は 5 でした。一方、以下の設計オプションを考えてください。

opts = designopts(LP,'ifir')
opts = 

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

この場合は、アップサンプリング係数を制御できることがわかります。たとえば、5 ではなく 4 でアップサンプリングを行う場合は、以下のようになります。

opts.UpsamplingFactor = 4;
opts.SystemObject = true;
IFIR_4 = design(LP,'ifir',opts);
cost(IFIR_4)
 
ans =
 
Number of Multipliers            : 217
Number of Adders                 : 215
Number of States                 : 767
Multiplications per Input Sample : 217
Additions per Input Sample       : 215

これにより合計 217 の非ゼロ乗数の設計が得られます。

同時最適化の使用

IFIR に使用する 2 つのフィルターを同時に設計することができます。この場合は、設計時間がかかるものの乗数の数を大幅に削減することができます (アルゴリズムの性質から、一部のケースでは設計が収束しない可能性があります)。

opts.UpsamplingFactor = 'auto'; % Automatically determine the best factor
opts.JointOptimization = true;
Hd_ifir_jo = design(LP,'ifir',opts);
cost(Hd_ifir_jo)
 
ans =
 
Number of Multipliers            : 172
Number of Adders                 : 170
Number of States                 : 726
Multiplications per Input Sample : 172
Additions per Input Sample       : 170

この設計の最適なアップサンプリング係数は 6 でした。非ゼロ乗数の数はわずか 152 となります。

マルチレート/多段手法を使用した設計の効率化

これまでに検討した設計では、シングルレート手法を使用しました。これは、MPIS (入力サンプルあたりに必要な乗算) の数が非ゼロ乗数の数と等しくなることを意味します。たとえば、最後に示した設計には 152 MPIS が必要になります。最初の単一ステージ等リップル設計には、694 MPIS が必要でした。

間引きと内挿を組み合わせたマルチレート/多段手法を使用することにより、MPIS 数の少ない効率的な設計を得ることができます。間引きでは、MPIS 数 (平均) は、乗数の数を間引き係数で除算することにより求めることができます。

MULTI_FIR = design(LP,'multistage','SystemObject',true);
cost(MULTI_FIR)
 
ans =
 
Number of Multipliers            : 396    
Number of Adders                 : 387    
Number of States                 : 352    
Multiplications per Input Sample : 73     
Additions per Input Sample       : 70.8333

最初のステージの乗数は 21 で、間引き係数は 3 であるため、MPIS 数は 7 です。第 2 ステージは長さ 45、累積間引き係数は 6 です (つまり、このステージの間引き係数を最初のステージの間引き係数で乗算したものです。これはこのステージの入力サンプルが最初のステージの入力サンプルの 1/3 のレートで入るためです)。したがって、MPIS の平均数 (マルチレート/多段の全体フィルターの入力の参照) は 45/6=7.5 になります。最後に、第 3 ステージの間引き係数が 1 であることを考えると、このステージの MPIS の平均数は 130/6=21.667 になります。3 つの間引きの平均 MPIS の合計は 36.5 です。

内挿の場合のフィルターも、間引きと同じです。さらに、計算コストも同じです。したがって、マルチレート/多段設計全体の合計 MPIS 数は 73 になります。

次に、等リップル設計と以下の設計の応答を比較します。

hfvt = fvtool(FIR,MULTI_FIR,'color','White','NormalizeMagnitudeto1','on');
legend(hfvt,'Equiripple design', 'Multirate/multistage design', ...
    'Location','NorthEast')

多段設計の阻止帯域の減衰が、他の設計の約 2 倍であることに注意してください。これは、必要な仕様を満たす上で障害となるエイリアシングを避けるために、間引きで必要とされる 66dB だけ帯域外コンポーネントを減衰させる必要があるためです。同様に、内挿でもこの設計の仕様を満たすために、イメージを 66dB 減衰させる必要があります。

ステージ数の手動制御

ここで得られたマルチレート/多段設計は 6 ステージから構成されていました。ステージ数は既定で自動的に決定されます。ただし、得られるステージ数を手動で制御することも可能です。以下に例を示します。

Hd_multi_4 = design(LP,'multistage','NStages',4,'SystemObject',true);
cost(Hd_multi_4)
 
ans =
 
Number of Multipliers            : 516 
Number of Adders                 : 507 
Number of States                 : 402 
Multiplications per Input Sample : 86  
Additions per Input Sample       : 84.5

この場合の平均 MPIS 数は 86 です。

群遅延

各設計の群遅延を計算することができます。マルチレート/多段設計を使用した場合に、遅延が最も大きくなることに注意してください (これが計算コストの低い設計の欠点です)。IFIR 設計も、単一ステージ等リップル設計より遅延が大きくなりますが、マルチレート/多段設計ほどではありません。

hfvt = fvtool(FIR,IFIR,MULTI_FIR,...
    'Analysis','grpdelay','color','White');
legend(hfvt, 'Equiripple design','IFIR design',...
    'Multirate/multistage design');

信号のフィルター処理

次に例を使って、IFIR とマルチレート/多段設計では、計算量を大幅に抑えながら単一ステージ等リップル設計と同じ性能が得られることを示します。カスケードに対してフィルター処理を実行するためには、generateFilteringCode(IFIR) および generateFilteringCode(MULTI_FIR) を呼び出す必要があります。ここでは、HelperIFIRFilter と HelperMultiFIRFilter を作成するためにこれは既に行われています。

SA = dsp.SpectrumAnalyzer('SpectralAverages',50,'SampleRate',Fs,...
    'PlotAsTwoSidedSpectrum',false,'YLimits', [-90 10]);
tic,
while toc < 20
    % Run for 20 seconds
    x = randn(6000,1);

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

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

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

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

この情報は役に立ちましたか?