I started with the FFT example provided with DSPLIB (version 3.4.0.0) which I found in C:\ti\dsplib_c66x_3_4_0_0\examples\fft_sp_ex\fft_example_sp.c.
I noticed that for many strictly real inputs I tried, the data does not show the expected symmetry. I modified the example and produced the output given below. The DFT function I wrote does not agree with TI's FFT function, but the DFT function does agree with Octave.
Am I missing something here?
I should mention that I've tried this with N = 256, and I get similar results.
Here is my code and my output:
#include <stdint.h>
#include <math.h>
#include <ti/dsplib/dsplib.h>
#include <stdio.h>
#include <complex.h>
#define MAXN 256
#pragma DATA_ALIGN(x_sp, 8);
float x_sp [2*MAXN];
#pragma DATA_ALIGN(y_sp, 8);
float y_sp [2*MAXN];
#pragma DATA_ALIGN(w_sp, 8);
float w_sp [2*MAXN];
unsigned char brev[64] = {
0x0, 0x20, 0x10, 0x30, 0x8, 0x28, 0x18, 0x38,
0x4, 0x24, 0x14, 0x34, 0xc, 0x2c, 0x1c, 0x3c,
0x2, 0x22, 0x12, 0x32, 0xa, 0x2a, 0x1a, 0x3a,
0x6, 0x26, 0x16, 0x36, 0xe, 0x2e, 0x1e, 0x3e,
0x1, 0x21, 0x11, 0x31, 0x9, 0x29, 0x19, 0x39,
0x5, 0x25, 0x15, 0x35, 0xd, 0x2d, 0x1d, 0x3d,
0x3, 0x23, 0x13, 0x33, 0xb, 0x2b, 0x1b, 0x3b,
0x7, 0x27, 0x17, 0x37, 0xf, 0x2f, 0x1f, 0x3f
};
static void print_cpx(const float* x, int n)
{
for(int i = 0; i < n; i++)
printf("%4d: %10.4f %+10.4fi\n",i, x[2*i],x[2*i+1] );
printf("\n");
}
void generateInput(int N) {
for(int i = 0; i < N; ++i) {
x_sp[2*i] = (float)i/4.0f;
x_sp[2*i] += (i%4)==0 ? 1.0f : 0.0f;
x_sp[2*i+1] = 0.0f;
}
}
// a simple (but slow N^2) DFT function.
void slow_dft( const float complex* xin, float complex* xout, unsigned int N )
{
double twoPi_N = 2.0f*3.141592654/(double)N;
for(int k = 0; k < N; ++k)
{
double complex Xk = 0.0;
double w = k*twoPi_N;
for(int n = 0; n < N; ++n)
{
double complex e_iwn = cexp(-I*w*n);
Xk += xin[n]*e_iwn;
}
xout[k] = (float complex)Xk;
}
}
/* Function for generating Specialized sequence of twiddle factors */
void gen_twiddle_fft_sp (float *w, int n)
{
int i, j, k;
double x_t, y_t, theta1, theta2, theta3;
const double PI = 3.141592654;
for (j = 1, k = 0; j <= n >> 2; j = j << 2)
{
for (i = 0; i < n >> 2; i += j)
{
theta1 = 2 * PI * i / n;
x_t = cos (theta1);
y_t = sin (theta1);
w[k] = (float) x_t;
w[k + 1] = (float) y_t;
theta2 = 4 * PI * i / n;
x_t = cos (theta2);
y_t = sin (theta2);
w[k + 2] = (float) x_t;
w[k + 3] = (float) y_t;
theta3 = 6 * PI * i / n;
x_t = cos (theta3);
y_t = sin (theta3);
w[k + 4] = (float) x_t;
w[k + 5] = (float) y_t;
k += 6;
}
}
}
void main (void) {
int N = 16;
/* Generate the input data */
generateInput(N);
printf("Input:\n");
print_cpx(x_sp,N);
/* Genarate twiddle factors */
gen_twiddle_fft_sp(w_sp, N);
/* Call FFT routine */
DSPF_sp_fftSPxSP(N, x_sp, w_sp, y_sp, brev, 4, 0, N);
printf("TI FFT:\n");
print_cpx(y_sp,N);
/* Re-generate the input data */
generateInput(N);
slow_dft((const float complex*)x_sp,(float complex*)y_sp,N);
printf("Simple DFT:\n");
print_cpx(y_sp,N);
}
///////////////////////////////////////////////////////////////////////////
Input:
0: 1.0000 +0.0000i
1: 0.2500 +0.0000i
2: 0.5000 +0.0000i
3: 0.7500 +0.0000i
4: 2.0000 +0.0000i
5: 1.2500 +0.0000i
6: 1.5000 +0.0000i
7: 1.7500 +0.0000i
8: 3.0000 +0.0000i
9: 2.2500 +0.0000i
10: 2.5000 +0.0000i
11: 2.7500 +0.0000i
12: 4.0000 +0.0000i
13: 3.2500 +0.0000i
14: 3.5000 +0.0000i
15: 3.7500 +0.0000i
TI FFT:
0: 34.0000 +0.0000i
1: 2.0000 +10.0547i
2: -4.8284 +2.0000i
3: -2.0000 -2.9932i
4: 2.0000 +2.0000i
5: 2.0000 -2.9932i
6: 4.8284 +2.0000i
7: -2.0000 +10.0547i
8: 2.0000 +0.0000i
9: 2.0000 -0.3978i
10: 0.8284 +2.0000i
11: -2.0000 +1.3364i
12: 2.0000 -2.0000i
13: 2.0000 +1.3364i
14: -0.8284 +2.0000i
15: -2.0000 -0.3978i
Simple DFT:
0: 34.0000 +0.0000i
1: -2.0000 +10.0547i
2: -2.0000 +4.8284i
3: -2.0000 +2.9932i
4: 2.0000 +2.0000i
5: -2.0000 +1.3364i
6: -2.0000 +0.8284i
7: -2.0000 +0.3978i
8: 2.0000 +0.0000i
9: -2.0000 -0.3978i
10: -2.0000 -0.8284i
11: -2.0000 -1.3364i
12: 2.0000 -2.0000i
13: -2.0000 -2.9932i
14: -2.0000 -4.8284i
15: -2.0000 -10.0547i