快速傅里叶变换c语言版
时间:2019-09-30
本文章向大家介绍快速傅里叶变换c语言版,主要包括快速傅里叶变换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()方法结果相差无几
原文地址:https://www.cnblogs.com/The-Shining/p/11613090.html
- Shell系列-编写及执行脚本
- Spring Security 入门(五):在 Spring-Boot中的应用
- Go语言Goroutine与Channel内存模型
- Tarjan--LCA算法的个人理解即模板
- spark sql编程之实现合并Parquet格式的DataFrame的schema
- Oracle压缩黑科技(一)—基础表压缩
- 12 条用于 Linux 的 MySQL/MariaDB 安全最佳实践
- hdu----(4545)魔法串(LCS)
- Oracle压缩黑科技(二)—压缩数据的修改
- 在Pivotal Web Service上发布Spring Boot应用
- hdu---(1325)Is It A Tree?(并查集)
- spark2 sql编程样例:sql操作
- hdu----(1599)最大子矩阵(几何/dp)
- Go语言简单的TCP编程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法