1

Here is my code in matlab:

x = [1 2 3 4];
result = fft(x);
a = real(result);
b = imag(result);

Result from matlab:

a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]

And my runnable code in objective-c:

int length = 4;
float* x =  (float *)malloc(sizeof(float) * length);
x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;

// Setup the length
vDSP_Length log2n = log2f(length);

// Calculate the weights array. This is a one-off operation.
FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);

// For an FFT, numSamples must be a power of 2, i.e. is always even
int nOver2 = length/2;

// Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));

// Generate a split complex vector from the sample data
vDSP_ctoz((COMPLEX*)x, 2, &A, 1, nOver2);

// Perform a forward FFT using fftSetup and A
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);

//Take the fft and scale appropriately
Float32 mFFTNormFactor = 0.5;
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, nOver2);

printf("After FFT: \n");
printf("%.2f | %.2f \n",A.realp[0], 0.0);
for (int i = 1; i< nOver2; i++) {
    printf("%.2f | %.2f \n",A.realp[i], A.imagp[i]);
}
printf("%.2f | %.2f \n",A.imagp[0], 0.0);

The output from objective c:

   After FFT: 
   10.0 |  0.0
   -2.0 |  2.0

The results are so close. I wonder where is the rest ? I know missed something but don't know what is it.

Updated: I found another answer here . I updated the output

   After FFT: 
   10.0 |  0.0
   -2.0 |  2.0
   -2.0 |  0.0

but even that there's still 1 element missing -2.0 | -2.0

Community
  • 1
  • 1
hoangpx
  • 470
  • 2
  • 16

1 Answers1

2

Performing a FFT delivers a right hand spectrum and a left hand spectrum. If you have N samples the frequencies you will return are:

( -f(N/2), -f(N/2-1), ... -f(1), f(0), f(1), f(2), ..., f(N/2-1) )

If A(f(i)) is the complex amplitude A of the frequency component f(i) the following relation is true:

Real{A(f(i)} = Real{A(-f(i))}   and Imag{A(f(i)} = -Imag{A(-f(i))}

This means, the information of the right hand spectrum and the left hand spectrum is the same. However, the sign of the imaginary part is different.

Matlab returns the frequency in a different order. Matlab order is:

( f(0), f(1), f(2), ..., f(N/2-1) -f(N/2), -f(N/2-1), ... -f(1), )

To get the upper order use the Matlab function fftshift().

In the case of 4 Samples you have got in Matlab:

a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]

This means:

A(f(0)) = 10 (DC value)
A(f(1)) = -2 + 2i (first frequency component of the right hand spectrum)
A(-f(2) = -2      ( second frequency component of the left hand spectrum)
A(-f(1) = -2 - 2i ( first frequency component of the left hand spectrum)

I do not understand your objective-C code. However, it seems to me that the program returns the right hand spectrum only. So anything is perfect.

Heinz M.
  • 668
  • 3
  • 8