6

私は非常に単純なインプレース DFT を書いています。ここに示す式を使用しています: http://en.wikipedia.org/wiki/Discrete_Fourier_transform#Definitionとオイラーの式を組み合わせて、これだけのために複素数クラスを使用する必要がないようにします。これまでのところ、私はこれを持っています:

private void fft(double[] data)
        {
            double[] real = new double[256];
            double[] imag = new double[256];
            double pi_div_128 = -1 * Math.PI / 128;
            for (int k = 0; k < 256; k++)
            {
                for (int n = 0; n < 256; n++)
                {
                    real[k] += data[k] * Math.Cos(pi_div_128 * k * n);
                    imag[k] += data[k] * Math.Sin(pi_div_128 * k * n);
                }
                data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]);
            }
        }

しかし、Math.Cos と Math.Sin の項は最終的には正と負の両方になるため、これらの項に data[k] を掛けて加算すると、それらは相殺され、非常に小さな値が得られます。それがどのように起こっているかはわかりますが、私のコードが数学を誤って表現している可能性があることを理解できません。どんな助けでも大歓迎です。参考までに、私は自分で書く必要があります。既製のFFTを入手できることに気づきました。

4

2 に答える 2

9

このセクションに誤りがあると思います

for (int n = 0; n < 256; n++)
{
    real[k] += data[k] * Math.Cos(pi_div_128 * k * n);
    imag[k] += data[k] * Math.Sin(pi_div_128 * k * n);
}

data[k] を data[n] に置き換える必要があります

編集:

また、次の行でデータを破壊しています。

data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]);

複素数のモジュライを別の場所または後で保存する必要があります。モジュラスだけが必要であり、それを data[] に格納したい場合は、変換を計算した後に別のループをコーディングする必要があります。すべての real[k] と imag [k] を計算するには、data[] 全体が必要です。

于 2010-04-28T02:15:24.187 に答える
8
private double[] dft(double[] data)
{
    int n = data.Length;
    int m = n;// I use m = n / 2d;
    double[] real = new double[n];
    double[] imag = new double[n];
    double[] result = new double[m];
    double pi_div = 2.0 * Math.PI / n;
    for (int w = 0; w < m; w++)
    {
        double a = w * pi_div;
        for (int t = 0; t < n; t++)
        {
            real[w] += data[t] * Math.Cos(a * t);
            imag[w] += data[t] * Math.Sin(a * t);
        }
        result[w] = Math.Sqrt(real[w] * real[w] + imag[w] * imag[w]) / n;
    }
    return result;
}
于 2012-08-15T20:23:22.133 に答える