快速傅里叶变换(研二的我终于弄懂了)

article/2025/10/16 10:53:56

研二的我仍然对快速傅里叶变换一知半解,于是乎,本着待在家里,能耗时间就多耗点,不知道何年马月我才可以在外面快乐的奔跑~~


快速傅里叶变换的实现(c++版本)

在做项目的时候,需要用到matlab里的fft,移植到c++时,结果有点出入,于是乎,老板下令给我搞清楚!

csdn上的这篇文章很友好,从数学多项式的角度解释了傅里叶变换的含义(傅里叶变换就是求多项式的点值表达式);But,代码部分我看的有些迷茫,可能这就是菜吧 ;本着无聊消耗时间的心,我决定要弄出个所以然,造福之后的小可爱们
二进制的翻转

void bitReverse(int bitNum,int *position)
{int len= 1 << bitNum;for(int i = 0; i < len; ++i){position[i] = (position[i >> 1] >> 1) | ((1 & i) << (bitNum - 1));}
}
 position[i] = (position[i >> 1] >> 1) | ((1 & i) << (bitNum - 1));

上面这个地方是困扰我时间最长的地方,那么多位的左移右移究竟是个嘛意思?后来在这篇文章里面弄懂了

这里是在计算position [i]的时候,认为position [i-1]的翻转已经计算完毕,并且存储在position [i-1]

计算position [i] ,把前i-1位和最后一位作为两部分进行处理,把最后一位挪到开头,然后在后面接上前i-1位的翻转;

fft变换

void fft(cp *a, int *rev, int n, int flag)
{for (int i = 0; i < n; i++){//i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。if (i < rev[i])swap(a[i], a[rev[i]]);}for (int h = 1; h < n; h *= 2) //h是准备合并序列的长度的二分之一{cp wn = exp(cp(0, flag * -1 * pie / h)); //求单位根w_n^1for (int j = 0; j < n; j += h * 2)       //j表示合并到了哪一个序列{cp w(1, 0);for (int k = j; k < j + h; k++) //k表示合并到了序列里的哪一位{cp x = a[k];cp y = w * a[k + h];a[k] = x + y; //这两步是蝴蝶变换a[k + h] = x - y;w *= wn; //求w_n^k}}//判断是否是FFT还是IFFTif (flag == -1)for (int i = 0; i < n; i++)a[i] /= n;}
}
cp wn = exp(cp(0, flag * -1 * pie / h)); //求单位根w_n^1

1 在这一块代码里面,困扰我比较久的是这里的单位根,文章里面没有加负号,算出的结果也就无法和matlab的结果匹配;后来我查阅文章,原来信号处理里面的旋转因子是有负号的
w n k = e − j 2 p i k / N w_n^k=e^{-j2pik/N} wnk=ej2pik/N

2 h,j,k的含义;
h表示将要合并序列的长度的一半
j是序列的个数
k是序列中合并到了哪一位
在这里插入图片描述
比如N=8,8点fft,一共处理三轮得到最终的结果;
第一轮有4个2点的fft序列 h=1; j=0,1,2,3; k=0;
第二轮有2个4点的fft序列 h=2; j=0,1 ; k=0,1;
第三轮有1个8点的fft序列 h=4; j=0 ; k=0,1,2,3;

结果验证:
在这里插入图片描述
MATLAB 结果:
在这里插入图片描述

附上完整代码:

#include <bits/stdc++.h> //万能的头文件,包含了常用的头文件
using namespace std;
typedef complex<double> cp;
const double pie = acos(-1); //很巧妙的一种定义pi的方式
//1.将最终的位置确定出来,二进制翻转
//2.fft变换//1.将最终的位置确定出来,二进制翻转
void bitReverse(int bitNum, int *position)
{int len = 1 << bitNum;for (int i = 0; i < len; ++i){position[i] = (position[i >> 1] >> 1) | ((1 & i) << (bitNum - 1));}
}//2.fft变换
void fft(cp *a, int *rev, int n, int flag)
{for (int i = 0; i < n; i++){//i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。if (i < rev[i])swap(a[i], a[rev[i]]);}for (int h = 1; h < n; h *= 2) //h是准备合并序列的长度的二分之一{cp wn = exp(cp(0, flag * -1 * pie / h)); //求单位根w_n^1for (int j = 0; j < n; j += h * 2)       //j表示合并到了哪一个序列{cp w(1, 0);for (int k = j; k < j + h; k++) //k表示合并到了序列里的哪一位{cp x = a[k];cp y = w * a[k + h];a[k] = x + y; //这两步是蝴蝶变换a[k + h] = x - y;w *= wn; //求w_n^k}}//判断是否是FFT还是IFFTif (flag == -1)for (int i = 0; i < n; i++)a[i] /= n;}
}int main()
{int length = 8;                     int bit_len = log(length) / log(2); int *Position = new int[length]();bitReverse(bit_len, Position); cp *data = new cp[length]();for (int i = 0; i < 8; ++i)data[i] = i + 1;cout << "data" << endl;for (int i = 0; i < 8; ++i)cout << data[i] << endl;fft(data,Position,length,1);cout << "fft result" << endl;for (int i = 0; i < 8; ++i)cout << data[i] << endl;delete Position;return 0;
}

总结:

花了几天时间,终于对自己有了一个交代,感慨万千,原本应该大学里就弄懂的知识一拖再拖,拖到了现在;这也让我更加崇拜那些学霸们,他们三下五除二就弄懂的知识在我这个菜鸡面前是座大山,不过好在我已经翻过去了,多的不说,继续加油吧!
(。◕ˇ∀ˇ◕)
附上菜鸡这几天的草稿纸
在这里插入图片描述


http://chatgpt.dhexx.cn/article/AuEXAmW8.shtml

相关文章

华电软工非全研究生学习工作总结-研二开学总结

昨晚加班太晚,就打算调休一天,养好精神,晚上开车回老家,开启假期模式。午休过后没啥事,随后就想着水一篇文章吧。 1、研究生学习 1.1、学生证来啦 今天对学生们来说,最大的喜事就是,期待了一学期的研究生学生证从北京邮寄了。看到微信群同学们开心的晒着学生证,我也期…

爆肝三天,我整理了这份春招攻略【针对大三/研二】

大家好&#xff0c;我是菜饼。长文预警&#xff0c;建议收藏。 18级的师弟妹们&#xff0c;这份春招攻略&#xff0c;希望可以让你们清醒一下。 &#xff08;当然&#xff0c;本篇不仅仅适用于大三同学&#xff0c;也适用于研一研二&#xff0c;打算走互联网开发方向的同学。&…

再见北理工:忆北京研究生的编程时光

两年前&#xff0c;我本科毕业写了这样一篇文章&#xff1a;《 回忆自己的大学四年得与失 》&#xff0c;感慨了自己在北理软院四年的所得所失&#xff1b;两年后&#xff0c;我离开了帝都&#xff0c;回到了贵州家乡&#xff0c;准备开启一段新的教师生涯&#xff0c;在此也写…

研究生学姐二次考研的感悟:关于择校选专业专硕or学硕

今天想跟大家分享一下我第一次考研&#xff0c;第二次考研&#xff0c;以及现在读研的一些经历。如果你能从中获得启发&#xff0c;我很荣幸&#xff0c;如果你觉得我说得不对&#xff0c;那就是你对。以下我输出的观点仅代表我个人&#xff0c;每个人的成长环境和想法都不一样…

优秀!研二实习生“阿里+字节+拼多多+美团”四杀offer

本人就读于某无导师制培训班&#xff0c;研二在百度腾讯实习过&#xff0c;目前想转java技术栈或wlb一下&#xff0c;就投递了一些外企和美团阿里&#xff0c;至于字节与拼多多&#xff0c;个人实在无法接受周末上班&#xff0c;就没有投递了。 年前准备了一下简历&#xff0c…

研一一整年都在搞深度学习,研二醒悟打算转开发

作者&#xff1a;阿秀阿秀的学习笔记&#xff1a;https://interviewguide.cn 你好&#xff0c;我是阿秀。 最近阿秀组建了自己的学习圈子&#xff0c;其实圈子里以前只有我一个人的&#xff0c;每天适当充电、看看书或者看一些教学视频&#xff0c;也会简单打卡记录自己的学习进…

【阶段总结】研二上学期总结

写在前面 距离上一篇【阶段总结】研一上学期总结又过去了将近一年的时间&#xff0c;而这一篇的阶段性总结也是在我入驻csdn平台后的第四篇的年度总结。从一开始的犹犹豫豫到现在坚持不定期的写作和总结&#xff0c;回想这几年的历程&#xff0c;还好有个csdn这个平台可以记录…

NLP领域论文笔记【研一下研二上】01

一、《Heterogeneous Graph Neural Networks for Extractive Document Summarization》 1、除句子外&#xff0c;还包含不同粒度级别的语义节点&#xff0c;这些另外的节点可以作为句子间的媒介&#xff0c;以加强句子间的关系。文件摘要是提取原始文档中的句子&#xff0c;把…

网页加载慢的测试方法

测试网页代码加载速度 背景测试方法 背景 最近用Hbuilder写了一个简单的网页&#xff0c;但是用到了很多的图片&#xff0c;本地加载很快&#xff0c;但是别人访问的时候加载很慢。 测试方法 百度的话 都是一些不着调的。打开你的网页&#xff0c;然后F12&#xff0c;选择ne…

Selenium自动化测试网页加载太慢怎么办

遇到网页加载慢&#xff0c;selenium运行效率降低&#xff0c;可以通过修改页面加载策略提升自动化效率。 selenium加载很慢 通过URL导航到新页面时&#xff0c;默认情况下&#xff0c;Selenium将等待文档完全被加载才会执行下面的操作&#xff0c;此时网页的加载状态为 comp…

php 加载慢,PHP开发中,网页加载速度很慢怎么办

有没有发现一种情况&#xff0c;总有一个用户需要等待某个平台的页面加载。最后他们会因为等得太久&#xff0c;被消耗了耐心&#xff0c;而直接关闭了加载该页面的窗口。 一般来说&#xff0c;页面在512KB的连接速率下&#xff0c;超过5秒打不开网页&#xff0c;用户就会很烦躁…

JS网页加载状态判断

网页加载状态一共分为5种,分别是: //&#xff08;未初始化&#xff09;还没有调用send()方法 1.uninitialized&#xff1a;(Uninitialized) the send( ) method has not yet been invoked. //&#xff08;载入&#xff09;已调用send()方法&#xff0c;正在发送请求 2.loadi…

提高网页加载速度的一些方法和技巧

网页的加载速度是评估网站质量一个重要指标&#xff0c;原因在于大多数用户能够容忍的网页加载时间只有几秒&#xff0c;如果超出了访客的忍受范围他们会毫不留情地关掉你的网页&#xff0c;所以网页载入速度会极大地影响网站的流量和访问。 以下总结了几种可以明显提高网站加…

jQuery页面加载事件

在jQuery对象与js对象之间的转换的案例中,我们看到所有的js代码都放到了body标签之后,如果把js代码放到head标签中,js代码就会报错,这个问题我们已经在js中学过,就是需要让页面加载完成之后再执行. <!DOCTYPE html> <html lang"en"> <head><me…

html页面加载完成之后,网页加载时页面显示进度条加载完成之后显示网页内容...

现在网上有很多网页加载进度条 &#xff0c;但大多都是时间固定的。 下面的当查询大量数据时&#xff0c;网页加载较慢&#xff0c;在网页加载时&#xff0c;显示进度条&#xff0c;当网页加载完成时&#xff0c;进度条消失&#xff0c;显示网页已经加载完成的内容。 Dim Bar, …

html加载状态,js等待页面加载完成

页面加载完成后等待一段时间在执行js的方法,时间例如方法: function test(){return 1;} 页面加载完毕事件: window.onload = function(){ setTimeout(test,1000);//1000毫秒=1秒后执行test方法 } 如果你使用jquery的话可以: $(window).load(function(){ setTimeout(test,10…

超详细讲解页面加载过程

说一说从输入URL到页面呈现发生了什么&#xff1f;&#xff08;知识点&#xff09; 这个题可以说是面试最常见也是一道可以无限难的题了&#xff0c;一般面试官出这道题就是为了考察你的前端知识的深度与广度。 1.浏览器接受URL开启网络请求线程&#xff08;涉及到&#xff1a;…

页面加载的几种方式和区别

目录 页面加载的几种方式 DOM文档加载步骤原生JS的 ready阶段 执行方法怎么写&#xff1f;全部方式的演示代码window和document的区别 页面加载的几种方式&#xff08;原生JS和jQuery&#xff09; 1. window.onload function(){}; —— 原生JS 2. $(window).load(function(){…

页面加载过程(url->页面)

当我们在浏览器输入URL地址开始&#xff0c;到web页面加载完毕&#xff0c;这个过程称作网页加载过程。具体如下&#xff1a; 在浏览器地址栏输入URLDNS域名解析发送HTTP请求服务器接收请求做出响应浏览器解析渲染页面 1.浏览器接受URL开启网络请求线程&#xff08;涉及到&…

登录校验总结1.0

登录校验 问题分析 基础的登录功能&#xff1a; 接受前端请求传递的用户名和密码&#xff0c;然后再根据用户名和密码查询用户信息&#xff0c;如果用户信息存在&#xff0c;则说明用户输入的用户名和密码正确。如果查询的用户不存在&#xff0c;则说明输入的用户名和密码错误…