2

ここ数週間、私は任意のバイトのセットを受け取り、それらをシグナルとして扱うDFTを実装しようとしています。次に、それらを周波数領域に変換します。その後、それはそれらを元に戻します。元々は、元の信号を再構築するために一部のコンポーネントを使用しようとしただけでした。これが失敗したとき、私はすべてのコンポーネントを使用しようとしましたが、それでも失敗しました。

私はこれを行う方法のガイドとしてウィキペディアの方程式に従ってきました、そして私のコードはこのコードを与えられた(私の心の中で)与えられた方程式と一致するようです:

DFT:

for (int k = 0; k < frequency_domain_magnitude.length; k++) {
    for (int n = 0; n < data.length; n++) {
        double val = (-2.0 * Math.PI * n * k / data.length);
        freq_imag[k] += data[n] * -Math.sin(val);
        freq_real[k] += data[n] * Math.cos(val);
    }
    frequency_domain_magnitude[k] = Math.sqrt(freq_imag[k] * freq_imag[k] + freq_real[k] * freq_real[k]);
}

IDFT:

for (int n = 0; n < data.length; n++) {
    doubleValue[n] = 0;
    for (int k = 0; k < freqUsed.length; k++) {
        double val = (2.0 * Math.PI * n * k / data.length);
        doubleValue[n] = freq_real[k] * Math.cos(val) - freq_imag[k] * Math.sin(val);
    }
    time_real[n] = (byte) (Math.floor(doubleValue[n]));
}

誰かが私が問題が何であるかを特定するのを手伝ってもらえますか?

同じプロジェクトについての前の質問をしましたが、それはひどい言い回しであり、編集はより多くの混乱を引き起こしたかもしれません。また、その質問は答えられたかもしれませんが、私はまだ理解する必要があります。それはここで見つけることができます

4

2 に答える 2

3

少なくとも3つのことが間違っています:

まず、IDFTのすべての周波数を合計しているわけではありません。これは非常に大きな問題であり、基本的に、周波数領域データ全体ではなく、1つの個別の周波数のIDFTのみを取得することと同じです。次に、IDFTでサインが反転しています。

スニペット2の5行目を次のように変更します

    doubleValue[n] += freq_real[k] * Math.cos(val) + freq_imag[k] * Math.sin(val);

そして、doubleValueをゼロに初期化することを確認してください。

第三に、正規化ステップを追加する必要があります。

スニペット2の7行目を次のように変更します

time_real[n] = (byte) (Math.floor(doubleValue[n] / data.length))

第4に、簡単にするために、整数データ型に切り捨てる前に、浮動小数点の入力と出力を使用してこの浮動小数点アルゴリズムをテストし、整数データ(浮動小数点)のラウンドトリップを実行して正確な正解が得られるとは想定しないでください。エラーは非常に現実的です。

また、他の誰かのDFTおよびIDFTの実装を取得し、他のエラーをキャッチするために、いくつかの非常に単純な入力での動作を実装と比較することも役立つ場合があります。DFTは線形代数であるため、完全に正しいとは言えず、質的には問題ないように見える答えが表示される場合があります。

于 2011-08-22T07:19:25.787 に答える
1

数値的な意味では、丸めや量子化のエラーはほとんどの場合、ラウンドトリップ中にわずかな違いや情報の損失を引き起こすため、できません。

ただし、DFTとIDFTを正しく完全に実装すると、この数値エラー内で時間領域データを再作成できます。FFT / IFFTペアは、DFT/IDFTペアよりも小さな数値誤差を生成する可能性があります。

用語(複雑な虚数の用語や頻度ビンなど)を破棄すると、結果は元の用語から遠くなります。たとえば、frequency_domain_magnitude.lengthまたはfreqUsed.lengthがデータの長さよりも短い場合、用語は破棄されます(わずかに異なるアルゴリズムやスケール係数を使用する場合を除く)。

@ellisbbenが述べているように、IDFTには少なくとも1つまたは2つの致命的なタイプミスがあります。

于 2011-08-22T21:50:19.417 に答える