傅立叶变换—FFT

FFT(快速傅立叶变换)使用“分而治之”的策略来计算一个n阶多项式的n阶DFT系数的值。定义n为2的整数幂数,为了计算一个n阶多项式f(x),算法定义了连个新的n/2阶多项式,函数f[0](x)包含了f(x)中的x偶次幂项,函数f[1](x)f(x)中的x奇次幂项。

f[0]=a0+a2x+a4x2+ ...+an-2xn/2-1

f[1]=a1+a3x+a5x2+ ...+an-1xn/2-1

则f(x) = f[0](x2)+ xf[1](x2),因此wn0,wn1,...wnn-1点计算f(x)的值得问题转化成计算f[0]和f[1]在(wn0)2,(wn1)2,...(wnn-1)2点的问题,然后计算f(x) = f[0](x2)+ xf[1](x2)。

FFT Code:

#include "stdio.h"
#include "math.h"

#define  LENGTH 4
#define  PI 3.1415926

typedef struct Complex
{
  float real;
  float img;
}Complex;

void Recursive_FFT(float *a,Complex *y,int len);
Complex Mul(Complex w,Complex y1_var);
Complex Add(Complex y0_var,int op,Complex mul_result );

int main()
{
  float a[LENGTH] = {1,2,3,4};
  
  Complex f[LENGTH];
  Recursive_FFT(a,f,LENGTH);
  
  int i;
  for(i=0;i<LENGTH;i++)
  {
    if(f[i].real !=0)
    {
      printf("%3.1f",f[i].real);
    }
    if(f[i].img !=0)
    {
      printf("+%3.1fi",f[i].img);
    } 
    printf("
");
  }
}

//递归求解,a为输入的初始矩阵,y为计算出来的频率矩阵
void Recursive_FFT(float *a,Complex *y,int len)
{
  Complex w0,wn;
  Complex y0[len/2],y1[len/2];
  
  w0.real = 1.0;
  w0.img = 0.0;
  
  wn.real = cos(-2 * PI /(float) len);
  wn.img = sin(-2 * PI / (float) len);
  
  float a0[len/2];
  float a1[len/2];
  int count_a0 = 0;
  int count_a1 = 0;
  
  int i;
  if(len == 1)
  {
     y[0].real = a[0];
     y[0].img = 0;
  }
  else
  {
    for(i=0;i<len;i++)
    {
      if(i % 2)
      {
    a0[count_a0++] = a[i];
      }
      else
      {
    a1[count_a1++] = a[i];
      }
    }
    
    Recursive_FFT(a0,y0,len/2);
    Recursive_FFT(a1,y1,len/2);
    
    int k;
    Complex w = w0;;
    for(k=0;k<len/2;k++)
    {
      y[k] = Add(y0[k],1,Mul(w,y1[k])); 
      y[k+len/2] = Add(y0[k],-1,Mul(w,y1[k]));
      w = Mul(w,wn);
    }
  }
  
}

//乘法运算
Complex Mul(Complex w,Complex y1_var)
{
  Complex result;
  result.real = w.real * y1_var.real - w.img * y1_var.img;
  result.img = w.real * y1_var.img + w.img * y1_var.real;
  return result;
}

//op为1则为加法运算,-1为减法运算 Complex Add(Complex y0_var,
int op,Complex mul_result ) { Complex result; if(op == 1) { result.real = y0_var.real + mul_result.real; result.img = y0_var.img + mul_result.img; } else { result.real = y0_var.real - mul_result.real; result.img = y0_var.img - mul_result.img; } return result; }

时间复杂度:O(n*logn)。

原文地址:https://www.cnblogs.com/zhangjxblog/p/5016904.html