0

filter2 が原因で丸めエラーが発生しています。最小限のコード例を次に示します。

format long

x=[ 0 0 0 0 0
 64 65 72 74 72
 104 111 109 106 112];

h=[ 0 0 0 0 0
 0 0.500000000000000 0 0.500000000000000 0
 0 0 0 0 0]

y=filter2(h,x, 'valid')
y_= x(2,2)/2 + x(2,4)/2
y__= sum(sum(x .* h))    
round(y)
round(y_)
round(y__)

結果は

y = 69.499999999999986
y_ = 69.500000000000000
y_ = 69.500000000000000
ans = 69
ans = 70
ans = 70

これは、fft ドメイン (または同様のもの) でフィルタリングを行った結果であると推測しています。残念ながら、FPGA インプリメンテーションに対して生成しているテスト ベクターを検証するときに問題が発生します。

このエラーを修正/回避する方法はありますか?

PS私はmatlab 2007bを使用しています。

編集: 2007a から 2007b へ Edit2: y__ の例を追加

4

2 に答える 2

1

浮動小数点演算で実行された演算が近似結果を生成するのは、予想される動作です。浮動小数点演算では固定数のビットを使用して数値を表し、各浮動小数点演算の結果は最も近い表現可能な数値に丸められます (別の丸めモードが設定されていない場合)。

特に、FFT の実行には多くの値のサインとコサインが必要であり、サインとコサインは正確には表現できません。これらの値と FFT データの値に対する演算では、正確には表現できない多くの中間結果が生成されます。したがって、FFT の結果は概算であると予想されます。

浮動小数点 FFT のエラーに関する調査では、エラーの動作は一般的に良好であることが示されています。ただし、結果が 69.5 の「正しい」側に到達して、希望する丸めが行われるとは期待できません。基本的に、FFT の結果を丸めることで正確な結果が得られると期待するのは誤りです。

一般に、精度の高い浮動小数点形式を使用すると、誤差の大きさを減らすことができます。したがって、より高い精度を使用すると、FFT の結果が理想的な結果に近づく可能性があります。ただし、丸めを機能させるには何が必要かを検討してください。69.5 またはそれよりわずかに大きい数値は 70 に丸められます。69.5 よりわずかに小さい数値は 69 に丸められますが、これは望ましくありません。したがって、必要に応じて丸めるには、69.5 未満の数値を生成するエラーは、そのエラーがどれほど小さいかに関係なく許容されます。ただし、すべての浮動小数点形式には何らかのエラーがあります。したがって、希望する方法で丸められる結果を生成することが保証されている精度はありません。(誤差は、丸めモードを設定して、必要に応じて上向きまたは下向きに丸めることである程度制御できます。ただし、FFT は複雑な操作であり、最終製品で目的の丸めを取得するには、すべての中間操作で丸めを制御する必要があり、実用的ではありません.)

そのため、浮動小数点 FFT では希望する結果が得られません。利用可能ないくつかのオプションは次のとおりです。

  • あなたの期待を変えてください。フィルターが正確な演算と同じ結果を生成するとは思わないでください。
  • FFT ではなく、直接演算を使用してフィルターを実行します。(私は Matlab を使用しておらず、Matlab でこれを行う良い方法についてアドバイスすることはできません。) 浮動小数点演算でこれを行うと、すべての中間値が浮動小数点形式で表現できる場合にのみ、正確な結果が得られることに注意してください。これは通常、フィルターとデータに「単純な」値を持つ小さなフィルターにのみ当てはまります。(この目的のために、バイナリ浮動小数点形式を想定すると、「単純な」値とは、浮動小数点形式の小数部分の数ビットだけで表現できる値、つまり、2 の数乗整数の和である値です。 2 -1 +2 -3である .625 など、互いに近いもの)。
  • 正確な算術を使用します。Maple や Mathematica などの一部の数学ソフトウェアは、正確な算術演算をサポートしています。私の知る限り、Matlab にはありません。FFT を正確に実行するには、より優れた数学的能力 (正弦と余弦を正確に操作する) が必要なため、これには通常、FFT ではなく直接演算でフィルターを実行する必要があります。

これはテスト用であると述べているため、次のいずれかをお勧めします。

  • 結果の小さなエラーを許可します。小さなエラーは浮動小数点演算の典型であり、通常、テストしているフィルターのエラーを示すものではありません。テストで探しているバグは、通常、大規模で多数のエラーを生成します。
  • 十分な場合は直接演算を使用し、必要な場合は正確な演算を使用します。これにより、より多くのプロセッサ時間が消費されます。ただし、テストは一般に高性能である必要はないため、より多くのプロセッサ時間を使用してもかまいません。
于 2012-11-20T02:00:50.270 に答える
0

これに対処する標準的な方法は、浮動小数点比較を避けることです。

2 つのものが等しいかどうかをチェックするのではなく、絶対差がイプシロンよりも小さいかどうかをチェックします。

したがって、2 つの数値が一致するかどうかを確認したい場合は、次のようにします。

abs(y-y_)
于 2012-11-19T14:02:09.467 に答える