快速傅里叶变换c语言版

Posted the-shining

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速傅里叶变换c语言版相关的知识,希望对你有一定的参考价值。

理论部分,我这里不介绍了。使用说明程序里面有,应该可以在单片机上跑。代码写的不美观,只是为了自己学习总结。下面直接上代码,使用说明代码里面有:

  1 /*
  2 用法:
  3      通过调用FFT(double *data)函数,在此函数中的临时复数数组_data[]就是
  4      傅里叶变换后的结果。想要得到幅值显示可以用sqrt()函数。幅值就是实部
  5      的平方加上虚部的平方再开方。
  6      注:宏定义中lengh必须要和传入的数组data的长度一样长,此函数支持的
  7      傅里叶变换的位数为2,4,8,16,32,64。理论上可以应用于单片机上(这本来
  8      也是出发目的)
  9 */
 10 #include "stdafx.h"
 11 #include <iostream>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #define lengh 8
 15 #define pi 3.1415
 16 
 17 typedef struct complex
 18 
 19     double real;
 20     double imag;
 21 complex;
 22 
 23 void daoxu(int a[])
 24 
 25     int i,j,N = 0;
 26     unsigned int _daoxu,k;
 27     for (i = 0; i < 8; i++)          //算出是多少次方  ,最多频谱是64位
 28         if ((1 << i) == lengh)
 29             N = i;
 30     
 31 
 32     for (i = 0; i < lengh; i++)     //初始化查表空间
 33         k = i;
 34         _daoxu = 0;
 35         for (j = 0; j < N; j++)     //倒序
 36             _daoxu = _daoxu << 1;
 37             _daoxu += (1 & k);
 38             k = k >> 1;
 39         
 40         a[i] = _daoxu;
 41     
 42 
 43 /*
 44    参数:data是输入数据数组实数
 45    返回值:无
 46 */
 47 void FFT(double *data)  
 48 
 49     int i, j, N = 0,x1,x2,step,_lengh;
 50     int daoxu_data[lengh] =  0 ;
 51     complex Wn, tem_variable,_data[lengh];
 52 
 53 
 54     daoxu(daoxu_data);      //生成倒序表
 55     
 56 
 57     for (i = 0; i < 8; i++)          //算出是多少次方  ,最多频谱是64位
 58         if ((1 << i) == lengh)
 59             N = i;
 60     
 61     for (i = 0; i < lengh; i++)          //把实数转换成复数,并且把倒序后的数据传过去
 62         _data[i].real = data[daoxu_data[i]];
 63         _data[i].imag = 0;
 64         printf("_data[%d].real:%f\n", i, _data[i].real);
 65     
 66 
 67     for (i = 0; i < N; i++)   //分级
 68         step = 1 << (i + 1);    //确定运算几大步,
 69         Wn.real = 1.0;
 70         Wn.imag = 0.0;
 71         printf("第几次蝶形运算:%d\n", i);
 72         for (j = 0; j < (step / 2); j++) 
 73             for (x1 = j; x1 < lengh; x1 += step) 
 74                 x2 = x1 + (step / 2);
 75 
 76 
 77                 tem_variable.real = 0.0;
 78                 tem_variable.imag = 0.0;
 79 
 80                 tem_variable.real = (_data[x1].real + _data[x2].real*Wn.real - _data[x2].imag*Wn.imag);
 81                 tem_variable.imag = (_data[x1].imag + _data[x2].real*Wn.imag + _data[x2].imag*Wn.real);
 82 
 83                 _data[x2].real = (_data[x1].real - _data[x2].real*Wn.real + _data[x2].imag*Wn.imag);
 84                 _data[x2].imag = (_data[x1].imag - _data[x2].real*Wn.imag - _data[x2].imag*Wn.real);
 85                 _data[x1].real = tem_variable.real;
 86                 _data[x1].imag = tem_variable.imag;
 87                 printf("x1:%d,x2:%d\n", x1, x2);
 88             
 89             _lengh = lengh;
 90             printf("Wn实部:%f,Wn的虚部:%f\n", Wn.real, Wn.imag);
 91             Wn.real = (cos(2 * pi*(j + 1) / (_lengh >> (N - (i + 1)))));
 92             Wn.imag = -(sin(2 * pi*(j + 1) / (_lengh >> (N - (i + 1)))));
 93 
 94         
 95     
 96     for (i = 0; i < lengh; i++) 
 97         printf("实部:%f ,虚部:%f。\n", _data[i].real,_data[i].imag);
 98     
 99 
100 
101 int main(void)
102 
103     double data[] = 0,1,2,3,4,5,6,7,8;
104     FFT(data);
105     return 0;
106 

运行结果为:

_data[0].real:0.000000
_data[1].real:4.000000
_data[2].real:2.000000
_data[3].real:6.000000
_data[4].real:1.000000
_data[5].real:5.000000
_data[6].real:3.000000
_data[7].real:7.000000
第几次蝶形运算:0
x1:0,x2:1
x1:2,x2:3
x1:4,x2:5
x1:6,x2:7
Wn实部:1.000000,Wn的虚部:0.000000
第几次蝶形运算:1
x1:0,x2:2
x1:4,x2:6
Wn实部:1.000000,Wn的虚部:0.000000
x1:1,x2:3
x1:5,x2:7
Wn实部:0.000046,Wn的虚部:-1.000000
第几次蝶形运算:2
x1:0,x2:4
Wn实部:1.000000,Wn的虚部:0.000000
x1:1,x2:5
Wn实部:0.707123,Wn的虚部:-0.707090
x1:2,x2:6
Wn实部:0.000046,Wn的虚部:-1.000000
x1:3,x2:7
Wn实部:-0.707058,Wn的虚部:-0.707156
实部:28.000000 ,虚部:0.000000。
实部:-4.000447 ,虚部:9.656985。
实部:-4.000185 ,虚部:4.000000。
实部:-4.000208 ,虚部:1.656777。
实部:-4.000000 ,虚部:0.000000。
实部:-3.999923 ,虚部:-1.656800。
实部:-3.999815 ,虚部:-3.999815。
实部:-3.999422 ,虚部:-9.656129

运行结果与我用numpy自带的fft()方法结果相差无几

以上是关于快速傅里叶变换c语言版的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV C++(十)----傅里叶变换

傅里叶变换通俗解释及快速傅里叶变换的python实现

音频算法入门-傅里叶变换

关于快速傅里叶变换

FFT(快速傅里叶变换)

快速傅里叶变换fft