快速傅里叶变换 及MATLAB函数

/* 快速傅里叶变换实用程序 */
#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

你可能感兴趣的:(快速傅里叶变换 及MATLAB函数)