#include "stdafx.h"
#include <iostream>
#include <complex>
#include <cmath>
#include <vector>
#define eps 1e-6
#define PI 3.14159265354
typedef std::complex<double> complex_t;
using namespace std;//旋转因子的计算
complex_t W(int k,int n,int N){return complex_t(cos(2*PI*k*n/N),-sin(2*PI*k*n/N));
}//格式化 零
complex_t format(complex_t &c){if(fabs(c.real())<eps)c = complex_t(0,c.imag());if(fabs(c.imag())<eps) c = complex_t(c.real(),0);return c;
}double format(double &c){if(fabs(c)<eps) c=0;return c;
}//离散序列的DFT计算,只针对实数序列 ,完全按照DFT的公式来计算,O(n^2)的复杂度
void DFT(vector<double> &x_n,vector<complex_t> &X_k){X_k.clear();int N=x_n.size();for(int k=0;k<N;++k){complex_t t(0,0);for(int n=0;n<N;++n){t+=x_n[n]*W(k,n,N);}X_k.push_back(format(t));}for(int i=0;i<N;++i){cout<<format(X_k[i])<<endl;}}//IDFT的计算,只针对实数序列
void IDFT(vector<complex_t> &X_k,vector<double> &x_n){x_n.clear();int N=X_k.size();for(int n=0;n<N;++n){complex_t t(0,0);for(int k=0;k<N;++k){t+=X_k[k]*W(k,-n,N);}x_n.push_back(t.real()/N);//运算结果只剩下实部 //cout<<(t/(double)N)<<endl; }for(int i=0;i<N;++i){cout<<format(x_n[i])<<endl;}}void DFT_test(){int N=64;vector<double> x_n(N);vector<complex_t> X_k(N);for(int i=0;i<N;++i){x_n[i]=i;}DFT(x_n,X_k);IDFT(X_k,x_n);
}//保证N是2的n次幂
int bitlen(int N){int n=0;while((N&1)==0){n++;N>>=1;}return n;
}int reverse_bit(int n,int len){//bit反转 int tmp=0;while(len--){tmp+=((n&1)<<len);n>>=1;}return tmp;}//序数重排
void resort(vector<complex_t> &x_n,int N){vector<complex_t> v(x_n);int len=bitlen(N);for(int i=0;i<N;++i){x_n[i]=v[reverse_bit(i,len)];}
}//基2,FFT算法实现,O(nlogn)的复杂度
void FFT(vector<complex_t> &x_n){int N=x_n.size();int r=bitlen(N);vector<complex_t> W(N);//预先计算旋转因子 for(int i=0;i<N;++i){double angle=-i*2*PI/N;W[i]=complex_t(cos(angle),sin(angle));}for(int k=0;k<r;++k){//迭代次数 for(int j=0;j<(1<<k);++j){int butterfly=1<<(r-k);int p=j*butterfly;int s=p+butterfly/2;for(int i=0;i<butterfly/2;++i){complex_t c=x_n[i+p]+x_n[i+s];x_n[i+s]=(x_n[i+p]-x_n[i+s])*W[i*(1<<k)];x_n[i+p]=c;}}}//次序重排 resort(x_n,N);for(int i=0;i<N;++i){cout<<format(x_n[i])<<endl;}}//IFFT,与FFT基本一致
void IFFT(vector<complex_t> &x_n){int N=x_n.size();int r=bitlen(N);vector<complex_t> W(N);//预先计算旋转因子 for(int i=0;i<N;++i){double angle=i*2*PI/N;//IFFT的旋转因子与FFT的旋转因子差一个负号 W[i]=complex_t(cos(angle),sin(angle));}for(int k=0;k<r;++k){//迭代次数 for(int j=0;j<(1<<k);++j){int butterfly=1<<(r-k);int p=j*butterfly;int s=p+butterfly/2;for(int i=0;i<butterfly/2;++i){complex_t c=x_n[i+p]+x_n[i+s];x_n[i+s]=(x_n[i+p]-x_n[i+s])*W[i*(1<<k)];x_n[i+p]=c;}}}//次序重排 resort(x_n,N);for(int i=0;i<N;++i){x_n[i]/=N;//IFFT与FFT还差一个系数 cout<<format(x_n[i])<<endl;}
}void FFT_test(){int N=64;vector<complex_t> x_n;complex_t c(0,0);for(int i=0;i<N;++i){c = complex_t(i,0);x_n.push_back(c);}FFT(x_n);IFFT(x_n);
}int main(){DFT_test();cout<<endl;FFT_test();return 0;
}

DFT,IDFT,FFT,IFFT算法的C++实现相关推荐

  1. C语言实现傅里叶变换函数dft,idft,fft,ifft

    自定义结构体complex(复数) typedef struct{double re; //实部 double im; //虚部 }complex; 用于为离散序列倒码排序的函数 int revers ...

  2. (2)DFT和FFT原理与实现

    目录 1.图像变换 2.离散傅里叶变换(Discrete Fourier Transform) 3.DFT性质 4.DFT与数字图像处理 5.FFT-快速傅里叶变换 6.DFT与FFT的算法实现 1. ...

  3. 离散傅里叶变换(DFT/IDFT、FFT/IFFT)运算量的讨论

    前言:关于为什么要写这个博客 最近在重新看<合成孔径雷达成像 算法与实现>这本书,看到"离散傅里叶变换记其逆变换的运算量级为"这句话,就想起当初在学<数字信号处理 ...

  4. 【FFT/IDFT】高效算法

    题目: 设x(n)是长度为2N的有限长实序列,X(k)为x(n)的2N点 DFT. (1)试设计用一次N点FFT完成计算X(k)的高效算法; (2)若已知 X(k),试设计用一次N点 IFFT实现求X ...

  5. 【DSP数字信号处理学习笔记】—— 详细推导DFT的快速实现算法:FFT 基于库利-图基算法的实现

    引言:尽管离散傅里叶变换(DFT)让频谱分析技术在计算机上的实现成为可能,但是受限于DFT算法庞大的计算量 O(N2)O(N^2)O(N2),使得DFT在一开始并没有被广泛使用,直到快速傅里叶变换算法 ...

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

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

  7. 离散傅里叶变换DFT与FFT,MATLAB的FFT函数使用(原创)——如何使用fft()绘制出真正的频谱图像

    以前一直对MATLAB中fft()函数的使用一直存在疑惑,为什么要加一 些参数,并且如何确定这些参数,也查了许多资料,但很多都感觉只是 表面一说根本没有讲清其本质.但随着学习的推进,慢慢有所领悟,所 ...

  8. matlab fft实现dft,matlab实现dft和fft

    对任意长度的序列进行傅里叶变换 DFT 与 FFT 的运算时间比较 设计要求 利用 Matlab 或者 C 语言设计 DFT 和 FFT 程序,比较两种频谱分析方法的 计算速度,并与...... DF ...

  9. dft变换的两幅图_离散傅立叶变换DTFT、DFT和FFT在工程与数学结合的通俗理解

    1.离散时间傅里叶变换DTFT 何为DTFT?就是对连续时间非周期信号进行抽样(乘积),得到的离散时间非周期信号再求傅里叶变换的过程就是DTFT.其实等同于信号频谱与脉冲信号频谱的卷积,这样得到的就是 ...

最新文章

  1. 【进阶玩法】Angular用emit()实现类似Vue.js的v-model双向绑定[(ngModel)]功能
  2. 修复电脑右键没有新建记事本
  3. 砸下数百万美元分析CEO语气,这帮投资者用AI发现了比财报更多的细节
  4. 测试DeltaCopy
  5. 《Netty 实战》Netty In Action中文版 第2章——你的第一款Netty应用程序(一)
  6. Yarn 资源调度框架
  7. oracle+dblink不管用,oracle dblink问题
  8. matlab里a1不能做变量,在matlab中将含有变量“w”的表达式存入矩阵元素,无法生成矩阵。哪里出问题了?...
  9. 下单送奖励金的实现思路
  10. transfer learning(matlab 实现)
  11. k8s优先级priority的使用
  12. spring mvc 重新定向到一个新的Url
  13. [安全攻防进阶篇] 九.熊猫烧香病毒机理IDA和OD逆向分析(上)
  14. Linux驱动——设备树
  15. 机顶盒文件服务器,智能网络机顶盒常见的六大玩法,别浪费了资源!
  16. Java将汉字数字日期转换为数字日期(例如: 二〇二〇年十一月二十一日 → 2020年11月21日)
  17. Android集成阿里云一键登录步骤
  18. [转帖]龙芯下一代处理器微结构GS464E细节曝光
  19. 孩子学python_小孩子的内心世界
  20. 应用程序无法正常启动(0xc000007b)的解决办法

热门文章

  1. ASP.NET的Application
  2. 正弦函数及其FFT变换(一)
  3. 10年+工作经验总结:测试工程师职业成长路线图
  4. 涡河网(GuoHeNet.Cn)简介
  5. NOIP模拟赛 密室逃脱
  6. QQ音乐MP3文件下载
  7. OKR工具有哪些?如何选择适合自己的?
  8. 如何配置FS726T的链路聚合--Trunking
  9. kotlin-stdlib_使用Kotlin stdlib使您的生活更轻松
  10. linux进阶34——无名管道