2011-09-28 16 views
26

私は現在、いくつかのフーリエ変換アルゴリズムを書こうとしています。数学的な定義で説明したように、私は、単純なDFTアルゴリズムで開始しました:離散フーリエ変換

public class DFT { 
    public static Complex[] Transform(Complex[] input) { 
     int N = input.Length; 

     Complex[] output = new Complex[N]; 

     double arg = -2.0 * Math.PI/(double)N; 
     for (int n = 0; n < N; n++) { 
      output[n] = new Complex(); 
      for (int k = 0; k < N; k++) 
       output[n] += input[k] * Complex.Polar(1, arg * (double)n * (double)k); 
     } 
     return output; 
    } 
} 

は、だから私は、次のコードでこのアルゴリズムをテストした:変換が正常に動作します

private int samplingFrequency = 120; 
    private int numberValues = 240; 

    private void doCalc(object sender, EventArgs e) { 
     Complex[] input = new Complex[numberValues]; 
     Complex[] output = new Complex[numberValues]; 

     double t = 0; 
     double y = 0; 
     for (int i = 0; i < numberValues; i++) { 
      t = (double)i/(double)samplingFrequency; 
      y = Math.Sin(2 * Math.PI * t); 
      input[i] = new Complex(y, 0); 
     } 

     output = DFT.Transform(input); 

     printFunc(input); 
     printAbs(output); 
    } 

が、numberValuesが複数ある場合にのみ、 samplingFrequencyの数(この場合、120,240,360、...)。 240個の値についての私の結果厥:

http://s1.directupload.net/images/110928/n3m8hqg6.jpg

変換がうまく働きました。私は私の計算された値の数を変更した場合

http://s7.directupload.net/images/110928/qizoiqbt.jpg

は、なぜ私が間違った結果を取得しています:私は、この結果を得る280個の値を計算しようとしていた場合

? 私の問題が私のコードにあるのか、DFTの数学的定義を誤解しているのか分かりません。いずれにせよ、誰も私の問題を助けてくれるの?ありがとう。

+0

Transform関数の入力が複雑な配列である理由を教えてください。確かに標準的な音波(時間領域)から変換している場合、それは単一のダブル配列ですか? –

+2

さて、私はそれを得ます - 虚数部は0に設定されているので、単なる二重の場合と本質的に同じです。あなたのコードでは、 'Complex.Polar'は 'Complex.FromPolarCoordinates'にする必要があります。 –

+2

プロットには何を使用しますか? – GorillaApe

答えて

28

あなたが経験していることはSpectral Leakageと呼ばれています。

これは、フーリエ変換の基礎となる数学が-infinityから+∞までの連続関数を仮定しているために発生します。あなたが提供するサンプルの範囲は無限回繰り返されます。ウインドウ内の波形のサイクル数が完全ではない場合、両端が一直線に並ばないため、不連続性が得られ、周波数が片側になるにつれて自らが現れます。

これを処理する通常の方法は、Windowingと呼ばれます。しかし、これは、振幅がわずかにオフになるため、欠点があります。これは、処理するサンプルのウィンドウ全体に、ウィンドウの両端で0に向かう関数を乗算するプロセスです。このプロセスによって信号の総電力が低下するため、端が整列しますが、振幅の歪みがあります。

要約すると、コードにエラーはなく、結果は期待通りです。アーチファクトはウィンドウ関数を使用して減少させることができますが、これは振幅の精度に影響します。プロジェクトの要件に最も適したソリューションを調査して判断する必要があります。

4

非周期的な正弦波に対して誤った結果を得ているわけではありません。そして、彼らは単なる「人工物」ではありません。あなたの結果は実際には、より完全なDFT結果であり、あなたは定期的な正弦波では見えません。それらの他の非ゼロ値は、例えば、単一の非周期的なアパーチャ正弦波の周波数を補間するために使用することができる有用な情報を含む。

DFTは正方形のウィンドウを正弦波と畳み込むものと考えることができます。これは無限の範囲を持つSinc関数を生成する(何かに非常に近い)が、ちょうどDFTビン上に中心を置いた正弦波の中央DFTビン以外のすべてのDFTビン周波数でゼロになる。これは、周波数がFFTアパーチャ内で正確に周期的である場合にのみ起こり、他の周波数に対しては起こらない。 Sinc関数には、最初のプロットの中に隠されているたくさんの "こぶ"があります。

関連する問題