/* 快速傅里叶变换实用程序 */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
typedef struct complexnumber
{
double rpart;
double ipart;
}cnumber;
void quickfft(cnumber p[],int n,int k,cnumber f[],int l,int il)
{
int it,m,is,i,j,nv,l0;
double t,q,s,vr,vi,r;
cnumber podd;
for (it=0; it<n; it++){
m=it; is=0;
for (i=0; i<k; i++){
j=m/2;
is=2*is+(m-2*j);
m=j;
}
f[it].rpart=p[is].rpart;
f[it].ipart=p[is].ipart;
}
p[0].rpart=1.0;
p[0].ipart=0.0;
t=2*PI/(1.0*n);
p[1].rpart=cos(t);
p[1].ipart=-sin(t);
if (l!=0) p[1].ipart=-p[1].ipart;
for (i=2; i<n; i++) {
t=p[i-1].rpart*p[1].rpart;
q=p[i-1].ipart*p[1].ipart;
s=(p[i-1].rpart+p[i-1].ipart)*(p[1].rpart+p[1].ipart);
p[i].rpart=t-q; p[i].ipart=s-t-q;
}
for (it=0; it<n-1; it+=2){
vr=f[it].rpart;
vi=f[it].ipart;
f[it].rpart=vr+f[it+1].rpart;
f[it].ipart=vi+f[it+1].ipart;
f[it+1].rpart=vr-f[it+1].rpart;
f[it+1].ipart=vi-f[it+1].ipart;
}
m=n/2; nv=2;
for (l0=k-2; l0>=0; l0--){
m=m/2; nv=2*nv;
for (it=0; it<=(m-1)*nv; it+=nv)
for (j=0; j<=(nv/2)-1; j++) {
t=p[m*j].rpart*f[it+j+nv/2].rpart;
q=p[m*j].ipart*f[it+j+nv/2].ipart;
s=p[m*j].rpart+p[m*j].ipart;
s=s*(f[it+j+nv/2].rpart+f[it+j+nv/2].ipart);
podd.rpart=t-q;
podd.ipart=s-t-q;
f[it+j+nv/2].rpart=f[it+j].rpart-podd.rpart;
f[it+j+nv/2].ipart=f[it+j].ipart-podd.ipart;
f[it+j].rpart=f[it+j].rpart+podd.rpart;
f[it+j].ipart=f[it+j].ipart+podd.ipart;
}
}
if (l!=0)
for (i=0; i<n; i++){
f[i].rpart/=n; f[i].ipart/=n;
}
if (il!=0)
for (i=0; i<n; i++){
p[i].rpart=sqrt(f[i].rpart*f[i].rpart+f[i].ipart*f[i].ipart);
if (fabs(f[i].rpart)<0.000001*fabs(f[i].ipart)) {
if ((f[i].ipart*f[i].rpart)>0) p[i].ipart=90.0;
else p[i].ipart=-90.0;
}
else
p[i].ipart=atan(f[i].ipart/f[i].rpart)*360.0/(2*PI);
}
}
int main()
{
int i,j;
cnumber p[64],f[64];
for (i=0; i<64; i++){
p[i].rpart=exp(-0.1*(i+0.5));
p[i].ipart=0.0;
}
printf("/n");
for (i=0; i<8; i++){
for (j=0; j<8; j++)
printf("%2.5lf;",p[8*i+j].rpart);
printf("/n");
}
printf("/n");
quickfft(p,64,6,f,0,1);
for (i=0; i<16; i++){
for (j=0; j<4; j++){
printf("%2.5lf",f[4*i+j].rpart);
if(f[4*i+j].ipart<0) {
printf("%2.5lfi;",f[4*i+j].ipart);
}
else {
printf("+%2.5lfi;",f[4*i+j].ipart);
}
}
printf("/n");
}
system("pause");
return 0;
}
下面是MATLAB自带的FFT函数
/*
* fft_rt.c - Cooley-Tukey radix-2 DIF FFT
* Complex input data in arrays x and y
* C.S. Burrus, Rice University, Sept. 1983
*
* Copyright 1995-2002 The MathWorks, Inc.
* $Revision: 1.15 $ $Date: 2002/04/12 22:18:20 $
*/
static void fft(int_T n, real_T *x, real_T *y)
{
real_T a, e, xt, yt;
int_T n1, n2, i, j, k, m;
/*
* Calculate m such that n=2^m
*
* NOTE: If frexp() == 1, then frexp does not conform
* to the ANSI C spec of [0.5, 1)
*/
if ( frexp((real_T)n, &m) != 1.0 ) {
m--;
}
/* --------------MAIN FFT LOOPS----------------------------- */
/* Parameter adjustments */
--y;
--x;
/* Function Body */
n2 = n;
for (k = 1; k <= m; ++k) {
n1 = n2;
n2 /= 2;
e = (real_T)6.283185307179586476925286766559005768394 / n1;
a = 0.0;
for (j = 1; j <= n2; ++j) {
real_T c = cos(a);
real_T s = sin(a);
a = j * e;
for (i = j; n1 < 0 ? i >= n : i <= n; i += n1) {
int_T q = i + n2;
xt = x[i] - x[q];
x[i] += x[q];
yt = y[i] - y[q];
y[i] += y[q];
x[q] = c * xt + s * yt;
y[q] = c * yt - s * xt;
}
}
}
/* ------------DIGIT REVERSE COUNTER----------------- */
j = 1;
n1 = n - 1;
for (i = 1; i <= n1; ++i) {
if (i < j) {
xt = x[j]; x[j] = x[i]; x[i] = xt;
xt = y[j]; y[j] = y[i]; y[i] = xt;
}
k = n / 2;
while (k<j) {
j -= k;
k /= 2;
}
j += k;
}
}
/* [EOF] fft_rt.c */
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/guochandaniu/archive/2010/05/05/5560825.aspx