tags:

views:

185

answers:

1

I'm writing a very simple in-place DFT. I am using the formula shown here: http://en.wikipedia.org/wiki/Discrete_Fourier_transform#Definition along with Euler's formula to avoid having to use a complex number class just for this. So far I have this:

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]);
            }
        }

But the Math.Cos and Math.Sin terms eventually go both positive and negative, so as I'm adding those terms multiplied with data[k], they cancel out and I just get some obscenely small value. I see how it is happening, but I can't make sense of how my code is perhaps mis-representing the mathematics. Any help is appreciated. FYI, I do have to write my own, I realize I can get off-the shelf FFT's.

+3  A: 

I believe You have an error in this section

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);
}

You should replace data[k] with data[n]

EDIT:

You are also destroying Your data in the line:

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

You have to store the moduli of your complex numbers somewhere else or later. If the modulus is all you want, and You want to store it in data[] You have to code another loop after computing the transform., The whole data[] is necessary for computing every real[k] and imag [k].

Maciej Hehl
After fixing that, it does fix the really-small-value problem, but the result looks nothing like a fourier transform. It's just a DC offset and then values right between 0 and 4 for the rest of the transform.
Adam
@Adam: I found one more problem and edited my answer
Maciej Hehl
+1 Maciel is right. It's conceptually important to understand that the Fourier transform at one point (real[k] real[k], with k typically a 'frecuency') does not relates just to the original signal at one point (data[n] with n typpicaly a 'time') but with all the signal - and the same viceversa.
leonbloy