快速傅里叶变换C++递归算法实现
时间:2022-04-26
本文章向大家介绍快速傅里叶变换C++递归算法实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
快速傅里叶变换C++递归算法实现
网上有些算法资料经测试运行结果是错误的,虽然代码的使用的是非递归形式。为了方便验证快速傅里叶变换的准确性,我提供了自己设计的递归算法。
基于时域抽取的“基2”快速傅里叶变换算法代码:
Fouier.h文件:
#pragma once
#include"Complex.h"
class Fouier
{
Complex * data;
void fft(int start,int step,int len);
Complex W(int k,int n);//e^(-i*2*pi*k/n)
public:
Fouier(void);
~Fouier(void);
void fft();
};
Fouier.c文件:
#include "Fouier.h"
#include<iostream>
using namespace std;
#include<cmath>
#include<ctime>
#define DATALEN 32
#define KEYVALUE 10000 //生成随机浮点数的值,保证分子和分母在这个值之内
#define PI 3.14159265358979323846
Fouier::Fouier(void)
{
data=new Complex[DATALEN];
srand(unsigned int(time(0)));
cout<<"源数据:"<<endl;
for(int i=0;i<DATALEN;i++)
{
data[i]=(rand()%(KEYVALUE))/(double)(rand()%(KEYVALUE)+1);
if(i%5==0&&i!=0)
cout<<endl;
cout<<data[i]<<" ";
}
cout<<endl;
}
Fouier::~Fouier(void)
{
delete [] data;
}
Complex Fouier:: W(int k,int n)//欧拉公式
{
double alpha=-2*PI*k/n;
return Complex(cos(alpha),sin(alpha));
}
void Fouier::fft(int start,int step,int len)
{
if(len==1)//一个元素
{
//一个元素不需要变换
return ;
}
fft(start,step*2,len/2);//X1(k)
fft(start+step,step*2,len/2);//X2(k)
Complex X1,X2;
for(int i=0;i<len/2;i++)
{
X1=data[start+step*i*2];
X2=data[start+step*(i*2+1)];
//计算X(k):k=0~N/2-1
data[start+step*i]=X1+W(i,len)*X2;
//计算X(k):k=N/2~N-1
data[start+step*(i+len/2)]=X1-W(i,len)*X2;
}
}
void Fouier::fft()
{
fft(0,1,DATALEN);
cout<<"变换后数据:"<<endl;
for(int i=0;i<DATALEN;i++)
{
if(i%5==0&&i!=0)
cout<<endl;
cout<<data[i]<<" ";
}
}
Complex.h文件:
#pragma once
#include<iostream>
using namespace std;
class Complex//a+b*i
{
double a;//实数部分
double b;//虚数部分
public:
Complex(double a=0,double b=0);
//+操作
friend Complex operator +(Complex &x,Complex &y);
friend Complex operator +(double x,Complex &y);
friend Complex operator +(Complex &x,double y);
//-操作
friend Complex operator -(Complex &x,Complex &y);
friend Complex operator -(double x,Complex &y);
friend Complex operator -(Complex &x,double y);
//*操作
friend Complex operator *(Complex &x,Complex &y);
friend Complex operator *(double x,Complex &y);
friend Complex operator *(Complex &x,double y);
//=操作
Complex operator =(Complex &x);
Complex operator =(double x);
//<<操作
friend ostream & operator<<(ostream&out,Complex&c);
~Complex(void);
};
Complex.c文件:
#include "Complex.h"
Complex::Complex(double a,double b)//虚部默认是0
{
this->a=a;
this->b=b;
}
Complex::~Complex(void)
{
}
Complex operator +(Complex &x,Complex &y)
{
return Complex(x.a+y.a,x.b+y.b);
}
Complex operator +(double x,Complex &y)
{
return Complex(x+y.a,y.b);
}
Complex operator +(Complex &x,double y)
{
return Complex(x.a+y,x.b);
}
Complex operator -(Complex &x,Complex &y)
{
return Complex(x.a-y.a,x.b-y.b);
}
Complex operator -(double x,Complex &y)
{
return Complex(x-y.a,-y.b);
}
Complex operator -(Complex &x,double y)
{
return Complex(x.a-y,x.b);
}
Complex operator *(Complex &x,Complex &y)
{
return Complex(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);
}
Complex operator *(double x,Complex &y)
{
return Complex(x*y.a,x*y.b);
}
Complex operator *(Complex &x,double y)
{
return Complex(x.a*y,x.b*y);
}
Complex Complex::operator =(Complex &x)
{
a=x.a;
b=x.b;
return *this;
}
Complex Complex::operator =(double x)
{
a=x;
b=0;
return *this;
}
ostream & operator<<(ostream&out,Complex&c)
{
if(c.a!=0||c.a==0&&c.b==0)
out<<c.a;
if(c.b!=0)
{
if(c.b>0)
out<<"+";
if(c.b!=1)
out<<c.b;
out<<"i";
}
return out;
}
main.c文件:
#include<iostream>
using namespace std;
#include"Fouier.h"
int main()
{
Fouier f;
f.fft();
return 0;
}
如有错误,欢迎批评指正!
参考资料:http://zhoufazhe2008.blog.163.com/blog/static/63326869200971010421361/
维基百科:http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E5%82%85%E7%AB%8B%E5%8F%B6%E5%8F%98%E6%8D%A2
- 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 数组属性和方法
- Python爬虫之scrapy模拟登陆
- Python爬虫之scrapy中间件的使用
- Python爬虫之scrapy_redis原理分析并实现断点续爬以及分布式爬虫
- Python爬虫之scrapy_splash组件的使用
- Python爬虫之scrapy的日志信息与配置
- Python爬虫之scrapyd部署scrapy项目
- 最近发现一个很有趣的随机小姐姐视频源码 分享给大家
- Codeforces Round #633 (Div. 2)C Powered Addition (贪心,二进制)
- Spring 整合 JUnit
- Java Stax解析XML示例
- Codeforces Round #633 (Div. 2) B Sorted Adjacent Differences(直观感知+排序插放)
- Spring 声明式事务
- Leetcode 1320 二指输入的的最小距离(多情况讨论,DP)
- Spring 基本注解
- Spring 基于注解的 IOC 与 AOP