实现功能:
DIF Radix2, DIF Radix4
DIT Radix2, DIT Radix4
FFT complex, IFFT complex
FFT real, IFFT real
使用方法:
lguo@lguo-enst:~$ unzip Algo.zip
lguo@lguo-enst:~$ cd Algo/DIF
lguo@lguo-enst:~/Algo/DIF$ gcc -o FFT_DIF_R2 FFT_DIF_R2.c -lm
lguo@lguo-enst:~/Algo/DIF$ ./FFT_DIF_R2
lguo@lguo-enst:~$ cd Algo/FFT_Test_Linux
lguo@lguo-enst:~/Algo/FFT_Test_Linux$ make
lguo@lguo-enst:~/Algo/FFT_Test_Linux$ ./FFT
说明:
Radix2 可以计算 4,8,16,32, 64,128, 256....点FFT
Radix4 可以计算 4,16, 64, 256, 1024...点FFT
FFT_DIT_general.c 实现了 Radix2 和Radix4 的配合使用,可以计算Radix2可以计算的所有FFT,但效率比Radix2高。
FFT complex 和 FFT real:
FFT real 和 IFFT real 是指输入信号没有虚部,只是实数序列的情况。这里就可以一个N/2点的FFT complex 来计算 N点FFT real。
特别提醒的是 IFFT real 也是指输入信号没有虚部,就是频域信号没有虚部,而输出信号,也就是时域信号有虚部的情况。这在实际应用中不多见。
之后进一步的工作就是要,实现了输入信号有虚部,输出是实序列的IFFT real。这样和FFT complex 组合起来就可以做成一个常用的,时域变到频域,频域处理后再变回时域的应用。
代码下载:
http://www.cppfrance.com/codes/ALGORITHME-FFT_44369.aspx
代码示例:
/***********************************
// DIT radix-4 FFT complex
//
// 1. Maximium points are 2048 because that
// function mylog2(int N) has the limit of maximal points
//
// 2. The last stage is 2 DFT ( for 8, 32, 128, 512, 2048...)
// or 4 DFT ( for 4, 16, 64, 256, 1024 ...).
//
//
// 24 juillet 2007
// purcharse*gmail.com
************************************/

#include
<
math.h
>
#include
<
stdio.h
>
#include
<
stdlib.h
>

typedef
double
real64;
/* floating point */
typedef
float
real32;
/* 32 bit fixed point */

struct
complex
{
real32 real;
real32 imag;
}
complex ;
static
struct
complex multicomplex(
struct
complex,
struct
complex);
static
int
mylog2(
int
); 
static void DFT_2(struct complex *,struct complex *);
static void DFT_4(struct complex *,struct complex *,struct complex *,struct complex *);
static void RunFFT(struct complex *, int);
static void RunIFFT(struct complex *,int);
static void BitReverse(struct complex *, int);
static void FFT_R4(struct complex *, int, int);
static void FFT_L2(struct complex *, int);
struct complex s[257];
int Num = 16;
const float PI=3.1415926535898;
main()
{
int i;
/* rectangle */
/*
for(i=0;i<Num+1;i++)
{
s[i].real=0;
s[i].imag=0;
}
s[0].real = 10;
s[0].imag = 10;
*/
/* sinus*/
for(i=0;i<Num+1;i++)
{
s[i].real=sin(PI*i/Num);
s[i].imag=cos(PI*i/Num);
}
/* */
/*
for(i=0;i<Num+1;i++)
{
s[i].real=0;
s[i].imag=0;
}
for(i=Num*3/8;i<Num/2;i++)
{
s[i].real=(i-Num*3/8);
s[i].imag=0;
}
for(i=Num/2;i<Num*5/8;i++)
{
s[i].real=(Num*5/8-i);
s[i].imag=0;
} */ 
printf("*********** Donnees ***************** ");
for(i=0;i<Num;i++)
{
printf("%.4f ",s[i].real);
printf("%.4f ",s[i].imag);
}
RunFFT(s, Num);
printf("*********** FFT ***************** ");
for(i=0;i<Num;i++)
{
printf("%.4f ",s[i].real);
printf("%.4f ",s[i].imag);
}
RunIFFT(s, Num);
printf("*********** IFFT ***************** ");
for(i=0;i<Num;i++)
{
printf("%.4f ",s[i].real);
printf("%.4f ",s[i].imag);
}
}
/***************** functions ********************/
static struct complex multicomplex(struct complex b1,struct complex b2) /* multiplication of complex */
{
struct complex b3;
b3.real=b1.real*b2.real-b1.imag*b2.imag;
b3.imag=b1.real*b2.imag+b1.imag*b2.real;
return(b3);
}
static int mylog2(int N) /* Max(N) = 4098 */
{
int k=0;
if (N>>12) { k+=12; N>>=12; }
if (N>>8) { k+=8; N>>=8; }
if (N>>4) { k+=4; N>>=4; }
if (N>>2) { k+=2; N>>=2; }
if (N>>1) { k+=1; N>>=1; }
return k ;
}

static void BitReverse(struct complex *xin, int N)
{
int LH, i, j, k;
struct complex tmp;
LH=N/2;
j = N/2;
for( i = 1; i <= (N -2); i++)
{
if(i < j)
{
tmp = xin[j];
xin[j] = xin[i];
xin[i] = tmp;
}
k = LH;
while(j >= k)
{
j = j-k;
k = k/2;
}
j = j + k;
}
}
static void DFT_2(struct complex *b1,struct complex *b2)
{
struct complex tmp;
tmp = *b1;
(*b1).real = (*b1).real + (*b2).real;
(*b1).imag = (*b1).imag + (*b2).imag;
(*b2).real = tmp.real - (*b2).real;
(*b2).imag = tmp.imag - (*b2).imag;
}
static void DFT_4(struct complex* b0, struct complex* b1, struct complex* b2,struct complex* b3)
{
/*variables locales*/
struct complex temp[4];
/*calcul x1*/
temp[0].real=(*b0).real+(*b1).real;
temp[0].imag=(*b0).imag+(*b1).imag;
/*calcul x2*/
temp[1].real=(*b0).real-(*b1).real;
temp[1].imag=(*b0).imag-(*b1).imag;
/*calcul x3*/
temp[2].real=(*b2).real+(*b3).real;
temp[2].imag=(*b2).imag+(*b3).imag;
/*calcul x4 + multiplication with -j*/
temp[3].imag=(*b3).real-(*b2).real;
temp[3].real=(*b2).imag-(*b3).imag; 
/*the last stage*/
(*b0).real=temp[0].real+temp[2].real;
(*b0).imag=temp[0].imag+temp[2].imag;
(*b1).real=temp[1].real+temp[3].real;
(*b1).imag=temp[1].imag+temp[3].imag;
(*b2).real=temp[0].real-temp[2].real;
(*b2).imag=temp[0].imag-temp[2].imag;
(*b3).real=temp[1].real-temp[3].real;
(*b3).imag=temp[1].imag-temp[3].imag;
}
static void FFT_R4(struct complex *xin, int N, int m)
{
int i, L, j;
double ps1, ps2, ps3, p ;
int le,B;
struct complex w[4];
for( L = 1; L <= m; L++)
{
le = pow(4 ,L);
B = le/4; /*the distance of buttefly*/
p = N/le;
for(j = 0; j <= B-1 ; j++)
{
// ps0 = (2*pp/N) * 0 * j;
// w[0].real = cos(ps0);
// w[0].imag = -sin(ps0);
ps1 = (2*PI/N)*p*2*j;
w[1].real = cos(ps1);
w[1].imag = -sin(ps1);
ps2 = (2*PI/N)*p*1*j;
w[2].real = cos(ps2);
w[2].imag = -sin(ps2);
ps3 = (2*PI/N)*p*3*j;
w[3].real = cos(ps3);
w[3].imag = -sin(ps3);
for(i = j; i <= N-1; i = i + le) /* controle those same butteflies*/
{
/* multiple with W */
// xin[i] = multicomplex(xin[i], w[0]);
xin[i + B] = multicomplex(xin[i + B], w[1]);
xin[i + 2*B] = multicomplex(xin[i + 2*B], w[2]);
xin[i + 3*B] = multicomplex(xin[i + 3*B], w[3]);
/* DFT-4 */
DFT_4(xin + i, xin + i + B, xin + i + 2*B, xin + i + 3*B);
}
}
/*
printf("*****N°%d ********** ", L);
for(i=0;i<Num;i++)
{
printf("%.8f ",xin[i].real);
printf("%.8f ",xin[i].imag);
}
*/
}
}//fin du FFT_R4
static void FFT_L2(struct complex *xin, int N)
{ /* For the last stage 2 DFT*/
int j, B;
double p, ps ;
struct complex w;
B = N/2;
for(j = 0; j <= B - 1; j++)
{
ps = (2*PI/N)*j;
w.real = cos(ps);
w.imag = -sin(ps);
/* multiple avec W */
xin[j+ B] = multicomplex(xin[j + B], w);
DFT_2(xin + j ,xin + j + B);
}
}//fin du FFT_L2
static void RunFFT(struct complex *xin, int N)
{
int m, i;
BitReverse(xin, N);
m = mylog2(N);
if( (m%2) == 0 )
{
/*All the stages are radix 4*/
FFT_R4(xin, N, m/2);
}
else
{
/*the last stage is radix 2*/
FFT_R4(xin, N, m/2);
FFT_L2(xin, N);
}
}
static void RunIFFT(struct complex *xin,int N)
{ /* inverse FFT */
int i;
for(i=0; i < Num + 1 ; i++)
{
xin[i].imag = -xin[i].imag;
}
RunFFT(xin,N);
for(i = 0; i < Num + 1 ; i++)
{
xin[i].real = xin[i].real/Num;
xin[i].imag = -xin[i].imag/Num;
}
}
本文介绍了快速傅里叶变换(FFT)的DIF和DIT Radix2、Radix4算法的实现,包括复数和实数的FFT与IFFT。提供了Linux环境下编译和运行代码的步骤,并强调了不同情况下FFT和IFFT的应用。代码可在指定链接下载,用于计算不同点数的FFT,并展示了如何进行复数乘法和位反转等关键操作。
4万+

被折叠的 条评论
为什么被折叠?



