zoukankan      html  css  js  c++  java
  • 傅立叶变换—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)。

  • 相关阅读:
    Android 使用WebView显示网页
    Android 使用ProgressBar实现进度条
    Android 使用Spinner实现下拉列表
    Android 使用GridView以表格的形式显示多张图片
    Android 使用DatePicker以及TimePicker显示当前日期和时间
    Android 使用ListView显示信息列表
    IIS配置步骤,绝对有用,百度上的不全面,是百度的补充
    冒烟测试
    广度优先和深度优先
    排序算法二(时间复杂度为O(N*logN))
  • 原文地址:https://www.cnblogs.com/zhangjxblog/p/5016904.html
Copyright © 2011-2022 走看看