C语言做快速傅里叶变换和快速逆傅里叶变换

  快速傅里叶变换(FFT)和快速逆傅里叶变换(IFFT)要求做傅里叶变换的数据点数只能是2的整数次幂,比如2,4,8,16,32,64,128,256,512,1024,2048,.......如果是2000个数据,那么用快速傅里叶变换(FFT)的结果就不对了,就需要使用对数据点数不限制的离散傅里叶变化(DFT)了,据说也可以使用补0的方法凑够2048个点来使用FFT。这里只分享C语言做快速傅里叶变化的代码,以后再分享C语言做傅里叶变换的代码。C语言做快速傅里叶变化(FFT)的时间复杂度是O(nlogn),傅里叶变化(DFT)的时间复杂度是O(n*n).
以下是做快速傅里叶变换和快速逆傅里叶变换的代码(包含测试代码):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>//定义复数结构体
typedef struct
{double real;double img;
}complex;void initW(complex W[], int size_x, double PI); //初始化变化核
void change(int size_x, complex x[]);
void add(complex a, complex b, complex *c);
void mul(complex a, complex b, complex *c);
void sub(complex a, complex b, complex *c);
void divi(complex a, complex b, complex *c);
void output(int size_x, complex x[]);  //输出结果
void fft(int size_x, complex x[], complex W[]);
void ifft(int size_x, complex x[], complex W[]);#define    N     1000int main()
{int size_x = 0;     //输入序列的长度,只限2的N次方complex x[N], W[N]; //输出序列的值double PI;PI = atan(1) * 4;                   //pi等于4乘以1.0的正切值size_x = 16;
//    x[0].real = 136, x[0].img=0;
//    x[1].real = -8, x[1].img=40.2187;
//    x[2].real = -8, x[2].img=19.3137;
//    x[3].real = -8, x[3].img=11.9728;
//    x[4].real = -8, x[4].img=8;
//    x[5].real = -8, x[5].img=5.3454;
//    x[6].real = -8, x[6].img=3.3137;
//    x[7].real = -8, x[7].img=1.5913;
//    x[8].real = -8, x[8].img=0;
//    x[9].real = -8, x[9].img=-1.5913;
//    x[10].real = -8, x[10].img=-3.3137;
//    x[11].real = -8 x[11].img=-5.3454;
//    x[12].real = -8, x[12].img=-8;
//    x[13].real = -8, x[13].img=-11.9728;
//    x[14].real = -8, x[14].img=-19.3137;
//    x[15].real = -8, x[15].img=-40.2187;x[0].real = 1,   x[0].img=0;x[1].real = 2,   x[1].img=0;x[2].real = 3,   x[2].img=0;x[3].real = 4,   x[3].img=0;x[4].real = 5,   x[4].img=0;x[5].real = 6,   x[5].img=0;x[6].real = 7,   x[6].img=0;x[7].real = 8,   x[7].img=0;x[8].real = 9,   x[8].img=0;x[9].real = 10,  x[9].img=0;x[10].real = 11, x[10].img=0;x[11].real = 12, x[11].img=0;x[12].real = 13, x[12].img=0;x[13].real = 14, x[13].img=0;x[14].real = 15, x[14].img=0;x[15].real = 16, x[15].img=0;initW(W, size_x, PI);fft(size_x, x, W);         //做傅里叶变换//ifft(size_x, x, W);     //做逆傅里叶变换output(size_x, x);return 0;
}void initW(complex W[], int size_x, double PI)
{for(int i = 0; i < size_x; i++){W[i].real = cos(2 * PI / size_x * i);W[i].img = -1 * sin(2 * PI / size_x * i);}
}void change(int size_x, complex x[])
{complex temp;unsigned short i =0, j = 0, k = 0;double t;for(i = 0; i < size_x; i++){k = i;j = 0;t = (log(size_x) / log(2));while((t--)>0){j = j << 1;j |= (k&1);k = k >> 1;}if(j > i){temp = x[i];x[i] = x[j];x[j] = temp;}}
}void add(complex a, complex b, complex *c)
{c->real = a.real + b.real;c->img = a.img + b.img;
}void mul(complex a, complex b, complex *c)
{c->real = a.real * b.real - a.img * b.img;c->img = a.real * b.img + a.img * b.real;
}void sub(complex a, complex b, complex *c)
{c->real = a.real - b.real;c->img = a.img - b.img;
}void divi(complex a, complex b, complex *c)
{c->real = (a.real * b.real + a.img * b.img) / (b.real * b.real + b.img * b.img);c->img = (a.img * b.real - a.real * b.img) / (b.real * b.real + b.img * b.img);
}void output(int size_x, complex x[])
{int i;printf("The result are as follows\n");for(i = 0; i < size_x; i++){printf("%.4f", x[i].real);if(x[i].img >= 0.0001){printf("+%.4fj\n",x[i].img);}else if(fabs(x[i].img) < 0.0001){printf("\n");}else{printf("%.4fj\n",x[i].img);}}
}void fft(int size_x, complex x[], complex W[])
{int i = 0, j = 0, k = 0, l = 0;complex up, down, product;change(size_x, x);for(i = 0; i < (int)(log10(size_x)/log10(2)); i++)    //一级蝶形运算{l = 1 << i;for(j = 0; j < size_x; j += 2 * l)    //一组蝶形运算{for(k = 0; k < l; k++)    //一个蝶形运算{mul(x[j+k+l], W[size_x*k/2/l], &product);add(x[j+k], product, &up);sub(x[j+k], product, &down);x[j+k] = up;x[j+k+l] = down;}}}
}void ifft(int size_x, complex x[], complex W[])
{int i = 0, j = 0, k = 0, l = size_x;complex up, down;for(i = 0; i < (int)(log(size_x) / log(2)); i++)     //一级蝶形运算{l/=2;for(j = 0; j < size_x; j += 2 * l)    //一组蝶形运算{for(k = 0; k < l; k++)      //一个蝶形运算{add(x[j + k], x[j + k +l], &up);up.real /= 2;up.img /= 2;sub(x[j+k], x[j+k+l], &down);down.real /= 2;down.img /=2;divi(down, W[size_x * k / 2 / l], &down);x[j + k] = up;x[j + k + l] = down;}}}change(size_x, x);
}
 分享一个在线做傅里叶变换的网站,可以验证自己做傅里叶变换的结果。http://www.yunsuan.info/signalprocessing/compute_fft_2d.htm

c语言做快速傅里叶变换和快速逆傅里叶变换相关推荐

  1. 卷积、傅里叶级数、傅里叶变换、快速傅里叶变换、pytorch中的fft,rfft

    卷积: 连续形式: 离散形式:  '卷' :  翻转 和 滑动    '积' : 积分 翻转:g(t)  - >  g(-t) 滑动:g(-t) - > g(n-t) 平移n个单位 举个例 ...

  2. Numpy和OpenCV实现傅里叶和逆傅里叶变换

    不得不说还是我python香啊 py才是世界上最好的语言 I think so 1.什么是傅里叶变换及其理论基础 2.Numpy实现傅里叶和逆傅里叶变换以及高通滤波示例 3.OpenCV实现傅里叶和逆 ...

  3. 图像算法四:【图像增强--频率域】傅里叶变换、快速傅里叶变换、频域滤波、频域低通滤波、频域高通滤波

    频率域滤波与空间域滤波殊途同归,空间域图像增强与频率域图像增强是两种截然不同的技术,实际上在相当程度上说它们是在不同的领域做相同的事情,只是有些滤波更适合在空间域完成,而有些则更适合在频率域中完成. ...

  4. C语言做离散傅里叶变换和逆变换

    C语言做离散傅里叶变换和逆变换 快速傅里叶换要求做傅里叶变换的数据点数是2的整数次幂,即点数是2,4,8,16,32,64,128,256,512,1024,-.实际使用中很多数据点数并不是2的整数次 ...

  5. python语言编程基础-Python语言入门详解!快速学成Python!

    原标题:Python语言入门详解!快速学成Python! 很多技能是被职场所需要的,但很可惜... 这些技能在大学中并学习不到. 大学和职场现实存在的横沟对大部分同学来说难以跨越或碰得头破血流... ...

  6. python语言入门-Python语言入门详解!快速学成Python!

    原标题:Python语言入门详解!快速学成Python! 很多技能是被职场所需要的,但很可惜... 这些技能在大学中并学习不到. 大学和职场现实存在的横沟对大部分同学来说难以跨越或碰得头破血流... ...

  7. 傅里叶变换与快速傅里叶变换

    傅里叶变换与快速傅里叶变换 作为电子信息专业的学生老说,这个不知道,或者理解不清楚,是十分不应该的,作为一个学渣,有时候确实是理解不清楚的 1.首先离散傅里叶变换目的: 简单点说: 就是将一个信号从时 ...

  8. 【从FT到DFT和FFT】(三)从离散傅里叶变换到快速傅里叶变换

    文章目录 推荐阅读 前言 从离散傅里叶变换到快速傅里叶变换 单位根 对DFT进行分治得到FFT 计算前半截 计算后半截 快速傅里叶逆变换(IFFT) 推荐阅读 前置阅读 [从FT到DFT和FFT](一 ...

  9. 快速傅里叶变换python_快速傅里叶变换及python代码实现

    一.前言 我想认真写好快速傅里叶变换(Fast Fourier Transform,FFT),所以这篇文章会由浅到细,由窄到宽的讲解,但是傅里叶变换对于寻常人并不是很容易理解的,所以对于基础不牢的人我 ...

最新文章

  1. Python 列表生成式的使用
  2. IOS获取焦点页面上移问题
  3. Java同步工具类——信号量
  4. 利用优盘安装win2008r2系统
  5. kaggle 房价预测经典文章
  6. Silverlight 4 Beta开发版带着许多新特性发布
  7. Valgrind简单用法
  8. w3c java_无法从W3C加载Java类
  9. oracle ocr掉盘,恢复OCR磁盘组一则
  10. 加密+拜占庭将军_屡屡被提及拜占庭将军问题,究竟和比特币是什么关系?
  11. 透过“简书钻”来探究简书的商业模式转变
  12. 射线法判断点在多边形内适用范围_电力行业NDT无损检测技术应用大盘点!
  13. java pv uv_使用Spark计算PV、UV
  14. 【Linux】动态防火墙,实现对攻击IP的动态拦截,一定程度上解决云服务器主机经常被境外IP尝试登录,屏蔽指定地区、国家的IP连接
  15. Java中如何判断一个集合中的一个元素不在另一个集合中?把不存在的元素移除
  16. 幼儿园案例经验迁移_浅谈在幼儿园数学教学中如何为迁移而教
  17. Run-down Protection
  18. 零基础入门金融风控之贷款违约预测挑战赛-task01
  19. 机器人工程专业学习金字塔
  20. 超超超简单Typora修改字体颜色

热门文章

  1. 62 stm32 usb自定义hid复合设备修改实验
  2. 安卓手机调试微信网页, 真机调试模式开启
  3. GT21L16S2W特殊字符计算地址
  4. matlab安装c盘吗,matlab的安装步骤(附winC盘“用户”文件夹下账户名的更改方法).doc...
  5. aspiration搭配_明3你们最喜欢的组合有哪些?
  6. 基于MVC的社团信息管理系统
  7. PHP文件怎么改tne,修改 · thinkphp6文档 · 看云
  8. win7安装python3.8失败_Python3 | Win7系统下无法安装问题解决
  9. 使用第三方账号认证(一):钉钉扫码登录
  10. LINUX学习-在LCD上显示多行文字