I got a wrong result cuFFT: fft --> ifft,

Hi,

I’m trying to use cuFFT API.
So, I made a simple example for fft and ifft using cuFFT and I compared the result with MATLAB.
However, the result was totally different from MATLAB. I think MATLAB result is right.

I attach the source code and results.
If anyone has an idea, please let me know! thank you.

#define SIGNAL_SIZE_TEST 4
int main()
{
int _size = sizeof(cufftComplex) * SIGNAL_SIZE_TEST;
cufftComplex *x_t;

//Allocate host memory for the x(t)
x_t = (cufftComplex *)malloc(sizeof(cufftComplex) * SIGNAL_SIZE_TEST);

//Allocate host memory for the result(t)
cufftComplex *result = (cufftComplex *)malloc(_size);

x_t[0].x = 5;
x_t[1].x = 7;
x_t[2].x = 9;
x_t[3].x = 15;

x_t[0].y = 0;
x_t[1].y = 0;
x_t[2].y = 0;
x_t[3].y = 0;

//Allocate device memory for signal
cufftComplex *x_w;
checkCudaErrors(cudaMalloc((void **)&x_w, _size));

//Copy host memory to device
checkCudaErrors(cudaMemcpy(x_w, x_t, _size, cudaMemcpyHostToDevice));

//cufft plan
cufftHandle plan;
checkCudaErrors(cufftPlan1d(&plan, SIGNAL_SIZE_TEST, CUFFT_C2C, 1));

//FFT
printf("Transforming signal cufftexecC2C\n");
checkCudaErrors(cufftExecC2C(plan, x_w, x_w, CUFFT_FORWARD));

//Print-out the result of FFT
checkCudaErrors(cudaMemcpy(result, x_w, _size, cudaMemcpyDeviceToHost));
for(unsigned int i = 0; i<SIGNAL_SIZE_TEST; i++)
{
	printf("Real: %f,  imagi: %f \n", result[i].x, result[i].y);
}

//IFFT
checkCudaErrors(cufftExecC2C(plan, x_w, x_w, CUFFT_INVERSE));
//Copy device memory to host
printf("Copy device memory to host\n");
checkCudaErrors(cudaMemcpy(result, x_w, _size, cudaMemcpyDeviceToHost));

//Print-out the result of iFFT
for(unsigned int i = 0; i<SIGNAL_SIZE_TEST; i++)
{
	printf("Real: %f,  imagi: %f \n", result[i].x, result[i].y);
}

}

///////////////////////////////
result

  1. cuda result :

input: [5+0i, 7+0i, 9+0i, 15+0i]
fft result : 36+0i, -4+8i, -8+0i, -4-8i
ifft result: 20+0i, 28+0i, 36+0i, 60+0i

  1. matlab result:
    input: [5+0i, 7+0i, 9+0i, 15+0i]
    fft result: 9+0i, -1-2i, -2+0i, -1+2i
    ifft result: [5+0i, 7+0i, 9+0i, 15+0i]

When doing FFT->IFFT conversions, the result must be divided by the length of the transform (4 in this case). This is documented in several places in the CUFFT documentation, such as here:

http://docs.nvidia.com/cuda/cufft/index.html#cufft-transform-directions

“cuFFT performs un-normalized FFTs; that is, performing a forward FFT on an input data set followed by an inverse FFT on the resulting set yields data that is equal to the input, scaled by the number of elements. Scaling either transform by the reciprocal of the size of the data set is left for the user to perform as seen fit.”

thanks for your reply!
It’s really helpful for me.

However, I have one more question.

I added normalization factor 4 on the FFT result of Real and Imaginary.
36+0i, -4+8i, -8+0i, -4-8i --> if this result divided by 4, --> 9, -1+2i, -2, -1-2i
but, matlab result is : 9+0i, -1-2i, -2+0i, -1+2i
the signs for imaginary part is different.
Do I have to divide imaginary part by negatve factor?

if you manually do the FFT using the 4-pt DFT matrix, you can easily verify that the cuFFT result is correct. However, it’s hard to imagine matlab will get it wrong. So please check your matlab code :-)

I don’t have convenient access to matlab. When I run the following code in Octave (3.8.2):

X = [5+0i 7+0i 9+0i 15+0i]
Y = fft(X)

I get:

Y = 

    36 + 0i    -4 + 8i    -8 + 0i    -4 - 8i

Which duplicates the output from CUFFT exactly. It seems unlikely to me that Octave is “wrong”. So at the moment I can’t explain the differences. Perhaps we are shaping our arrays differently. Perhaps you should give the exact code you use in matlab and the exact output.