一维快速傅里叶变换代码

上一篇随笔,简要写了一下FFT中数组重新排序的算法。现在把完整的FFT代码分享给大家(有比较详细的注释)。

/*2015年11月10日于河北工业大学*/

#include <complex>
#include <iostream.h>
#include <math.h>
#include <stdlib.h>
const int N=8;      //数组的长度
const double PI=3.141592653589793; //圆周率
const double ZERO= 1.0E-14;   //当绝对值小于这个数的时候认为是0
typedef std::complex<double> complex;

//函数原型声明

void Reverse(complex src[],int n);

void FFT(complex src[],int n);

void Display(complex f[],int n);

/* 主函数 */

int main()
{
 complex src[8];      //原始数组
 for(int i=0;i<8;i++)
 {
  src[i]=complex(   double(i),   0.0  );
 }
 cout<<"原始数组为:"<<endl;
 Display(src,N);

//一维快速傅里叶变换
 FFT(src,N);

cout<<"变换后的数组为:"<<endl;
 Display(src,N);
 
 
 return 0;
}

/***********************************************
*****  一维快速离散傅里叶变换 *************
*****   输入:数组长度n      *************
*****         虚部 imag      *************
*****         实部real            *************
************************************************/
void FFT(complex src[],int n)
{

//原始数组按位码倒序排列
 Reverse(src,n);

cout<<"倒置后的数组为:"<<endl;

Display(src,n);

//计算M,M=log(2,n)表示共有M级蝶形运算
 for(int i=n,M=1;(i=i/2)!=1;M++);

for(int L=1;L<=M;L++)
 {
 // int arrayNum=n/pow(2,L);  //被分成的小的数组的个数
 
  int elementNum=pow(2,L);  //每个小数组的元素的个数
  
  int uniteachArr=elementNum/2; //每个小数组中所包含的蝶形运算单元的个数
  
  int offset=pow(2,L-1);         //每个蝶形运算节点的距离

//cout<<"偏移量为:"<<offset<<endl;

for(int i=0;i<n;i=i+elementNum)
  {
   for(int j=i;j<=i+uniteachArr-1;j++)
   {
    double r=(j-i)*pow(2,M-L);  //W(r,N)中的r
    
   // complex W=complex(cos(2*PI*r/N),sin(2*PI*r/N));

complex temp=src[j+offset]*complex(cos(2*PI*r/double(n)),-sin(2*PI*r/double(n)));
    src[j+offset]=src[j]-temp;
    src[j]=src[j]+temp;

}
  }
  
 }
 
}

/***********************************************
*****   函数功能:实现原始数组重新排序   *******
*****             主要实现按位码倒序的排列 *****
*****   函数输入:原数组     ****
************************************************/
void Reverse(complex src[],int n)
{
 /*
  p1和p2表示要进行交换的两个元素的索引
  其中p1从第二个元素到倒数第二个元素
  扫描,p2则是通过算法确定的与p1进行
  交换的另一个元素的索引

*/

int p1; 
 int p2;
 int middle;  //表示中心点
 int offset;  //表示偏移量
 /*   中心点和偏移量是计算p2的重要参数  */
 
 p2=n/2;   //与p1=1时交换的元素的索引为N/2
 for(p1=1;p1<=n-2;/*第一个元素和最后一个元素不用交换*/p1++)
 {
  /*当p1<p2时交换,避免重复交换*/
  if(p1<p2)
  {
   /*交换*/
   complex temp=src[p1];
   src[p1]=src[p2];
   src[p2]=temp;

}

/*下面开始计算下一个p2*/

middle=n/2;   //初始的中心点
  offset=p2;   //初试的偏移量
  
  //当中心点小于等于偏移量时要更新
  while(middle<=offset)
  {
   offset=offset-middle;
   middle=middle/2;
  }

p2=middle+offset;//p2就等于新的中心点和偏移量的和
 
 }

}

/*显示数据*/
void Display(complex f[],int n)
{
 
 
 for(int i=0;i<n;i++)
 {
  cout.width(9);
  cout.setf(ios::fixed);
  cout.precision(4);
  cout<<f[i].real();
  cout.flags(ios::showpos);
  cout.width(9);
  cout.setf(ios::fixed);
  cout.precision(4);
  cout<<f[i].imag()<<‘i‘<<‘\t‘;
  cout.unsetf(ios::showpos);
  if((i+1)%3==0) cout<<endl;

}
 cout<<endl;
}

时间: 2024-10-26 22:07:16

一维快速傅里叶变换代码的相关文章

快速傅里叶变换(FFT)算法【详解】

快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的“对称性”,并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶变换)本身就是离散傅里叶变换(Discrete

[学习笔记] 多项式与快速傅里叶变换(FFT)基础

引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积(或者多项式乘法/高精度乘法), 而代码量却非常小. 博主一年半前曾经因COGS的一道叫做"神秘的常数 $\pi$"的题目而去学习过FFT, 但是基本就是照着板子打打完并不知道自己在写些什么鬼畜的东西OwO 不过...博主这几天突然照着算法导论自己看了一遍发现自己似乎突然意识到了什么OwO然后就打了一道板子题还1A了OwO再加上午考试差点AK

快速傅里叶变换(FFT)

快速傅里叶变换(FFT)算法[详解] 快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的"对称性",并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶

快速傅里叶变换中的位码倒置算法

最近一直在看傅里叶变换,看到FFT算法,其实算法的关键之一,蝶形运算,只要看懂了,编码实现并不难.反倒是其中位码倒序的环节,看很容易看懂,但是编码实现不是那么容易的.在网上参考了很多资料后,决定把下面这个算法分享给大家,在这里要感谢百度文库用户letsgotoyy123提供的<快速傅里叶变换FFT及其应用>一文(http://wenku.baidu.com/view/7e9f6e6ea1c7aa00b42acb84)还要感谢星星同学,在一些基础知识上的指点,谢谢. #include<io

Matlab之快速傅里叶变换

一.快速傅里叶介绍 傅立叶原理表明:任何连续测量的时序或信号,都可以表示为不同频率的余弦(或正弦)波信号的无限叠加.FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域.那其在实际应用中,有哪些用途呢? 1.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征(频率,幅值,初相位): 2.FFT可以将一个信号的频谱提取出来,进行频谱分析,为后续滤波准备: 3.通过对一个系统的输入信号和输出信号进行快速傅里叶变换后,两者进行对比,对系统可以有一个初步认识. 假设采样

FFT算法实现——基于GPU的基2快速傅里叶变换

最近做一个东西,要用到快速傅里叶变换,抱着蛋疼的心态,自己尝试写了一下,遇到一些问题. 首先看一下什么叫做快速傅里叶变换(FFT)(来自Wiki): 快速傅里叶变换(英语:Fast Fourier Transform, FFT),是离散傅里叶变换的快速算法,也可用于计算离散傅里叶变换的逆变换.快速傅里叶变换有广泛的应用,如数字信号处理.计算大整数乘法.求解偏微分方程等等. 对于复数串行,离散傅里叶变换公式为: 直接变换的计算复杂度是O(n^2).快速傅里叶变换可以计算出与直接计算相同的结果,但只

【笔记篇】(理论向)快速傅里叶变换(FFT)学习笔记w

现在真是一碰电脑就很颓废啊... 于是早晨把电脑锁上然后在旁边啃了一节课多的算导, 把FFT的基本原理整明白了.. 但是我并不觉得自己能讲明白... Fast Fourier Transformation, 快速傅里叶变换, 是DFT(Discrete Fourier Transform, 离散傅里叶变换)的快速实现版本. 据说在信号处理领域广泛的应用, 而且在OI中也有广泛的应用(比如SDOI2017 R2至少考了两道), 所以有必要学习一波.. 划重点: 其实学习FFT最好的教材是<算法导论

【转】快速傅里叶变换(FFT)详解

目录 前言 多项式 系数表示法 点值表示法 复数 向量 圆的弧度制 平行四边形定则 复数 运算法则 单位根 单位根的性质 快速傅里叶变换 快速傅里叶逆变换 理论总结 递归实现 迭代实现 本文只讨论FFT在信息学奥赛中的应用 文中内容均为个人理解,如有错误请指出,不胜感激 回到顶部 前言 先解释几个比较容易混淆的缩写吧 DFT:离散傅里叶变换->O(n2)O(n2)计算多项式乘法 FFT:快速傅里叶变换->O(n?log(n)O(n?log?(n)计算多项式乘法 FNTT/NTT:快速傅里叶变换

【Delphi】如何在三轴加速器的频谱分析中使用FFT(快速傅里叶变换)算法

关于傅里叶变换的作用,网上说的太过学术化,且都在说原理,已经如何编码实现,可能很多人有个模糊影响,在人工智能,图像识别,运动分析,机器学习等中,频谱分析成为了必备的手段,可将离散信号量转换为数字信息进行归类分析. 今天这里将的不是如何实现,而是如何使用傅里叶变换 但频谱分析中,涉及到的信号处理知识对大部分软件开发的人来说,太过于晦涩难懂,傅里叶变换,拉普拉斯,卷积,模相,实数,虚数,复数,三角函数等等,已经能让软件工程师望而却步,造成懂知识的人无法开发,懂开发的人无法分析,而同时具备两种技能的人