快速傅里叶变换的原理及实现

图片来自于:https://wenku.baidu.com/view/5cacb2b8bd64783e09122b9a.html
代码来自于:https://blog.csdn.net/u013289254/article/details/74201302
以下内容来自于上述两个链接的总结,将上述两个内容综合起来比较容易看懂。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码:

#include <iostream>
#include<math.h>
#define PI 3.1415926
using namespace std;
void fit(double real[], double imag[], int N, int k, int inv)
{
	int i, j, k1, k2, m, step, factor_step;
	double temp_real, temp_imag, factor_real, factor_imag;

	if (inv != 1 && inv != -1)
	{
		cout << "FFT transformation require:inv=1" << endl;
		cout << "FFT inverse transformation require:inv=-1" << endl;
	}
	//倒序
	//将原始数据进行倒序,方便与下面的FFT算法//
	double tempreal[8];
	double tempimag[8];
	for (i = 0; i < N; i++)
	{
		tempreal[i] = real[i];
		tempimag[i] = imag[i];
	}
	int nInter = 0;
	for (j = 0; j< N; j++)
	{
		nInter = 0;
		for (i = 0; i<k; i++)
		{
			if (j&(1 << i))//判断第i位是否为1 &两个结果为真的的才是真的 1&1 = 0 1%0 = 0
			{
				nInter += 1 << (k - i - 1);
			}
		}
		real[j] = tempreal[nInter];
		imag[j] = tempimag[nInter];
	///
	}
	//蝶形算法
	for (i = 0; i < k; i++)//总共分k层进行计算
	{
		step = 1 << (i + 1);//最低层计算数据为2,然后以2为倍数增加2,4,8
		factor_step = N >> (i + 1);//旋转因,数变化速度...4,2,1,2个数据时N = 2,4个时N = 4, 
		//初始化旋转因子
		factor_real = 1.0;
		factor_imag = 0.0;

		for (j = 0; j < step / 2; j++)//如果求4个数据的fft那么j = 0 ,1即数据量的一半,因为k1属于上一层fft的前半部分。
		{
			for (k1 = j; k1<N; k1 += step)//总共有八个数据那么先求前4个数据的fft,再求另外四个数据的fft。
			{
				k2 = k1 + step / 2;//蝶形运算的两个输入
				temp_real = real[k2] * factor_real - imag[k2] * factor_imag;
				temp_imag = real[k2] * factor_imag + imag[k2] * factor_real;
				real[k2] = real[k1] - temp_real;
				imag[k2] = imag[k1] - temp_imag;
				real[k1] = real[k1] + temp_real;
				imag[k1] = imag[k1] + temp_imag;
			}
			factor_real = inv*cos(-2 * PI*(j + 1)*factor_step / N);
			factor_imag = inv*sin(-2 * PI*(j + 1)*factor_step / N);
		}
	}
	if (inv == -1)
	{
		for (i = 0; i <= N - 1; i++)
		{
			real[i] = real[i] / N;
			imag[i] = imag[i] / N;
		}
	}

}
int main(int argc, char *argv[])
{
	cout << "Hello World!" << endl;
	double real[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	double imag[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	double realTwo1[8][8] = { { 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 },
	{ 1, 2, 3, 4, 5, 6, 7, 8 } };
	double realTwo[8][8] = { { 1, 2, 4, 1, 2, 4, 2, 5 },
	{ 1, 2, 4, 1, 4, 4, 2, 0 },
	{ 8, 2, 4, 1, 8, 4, 2, 5 },
	{ 1, 2, 4, 1, 2, 5, 2, 5 },
	{ 1, 8, 4, 1, 2, 4, 2, 5 },
	{ 1, 2, 8, 0, 2, 4, 2, 5 },
	{ 1, 9, 4, 1, 2, 4, 8, 5 },
	{ 1, 9, 4, 1, 2, 4, 8, 5 } };
	double imagTwo[8][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0 }, };
	fit(real, imag, 8, 3, 1);
	for (int i = 0; i < 8; i++)
	{
		cout << real[i] << " " << imag[i] << endl;
	}
	//cout<<imag[1];
	for (int i = 0; i < 8; i++)
	{
		fit(realTwo[i], imagTwo[i], 8, 3, 1);
	}
	//转置数组
	for (int j = 0; j < 8; j++)
	{
		for (int i = j; i < 8; i++)
		{
			double temprealTwo = 0.0;
			temprealTwo = realTwo[j][i];
			realTwo[j][i] = realTwo[i][j];
			realTwo[i][j] = temprealTwo;
			double tempimagTwo = 0.0;
			tempimagTwo = imagTwo[j][i];
			imagTwo[j][i] = imagTwo[i][j];
			imagTwo[i][j] = tempimagTwo;
		}
	}
	for (int i = 0; i < 8; i++)
	{
		fit(realTwo[i], imagTwo[i], 8, 3, 1);
	}
	//转置数组
	for (int j = 0; j < 8; j++)
	{
		for (int i = j; i < 8; i++)
		{
			double temprealTwo = 0.0;
			temprealTwo = realTwo[j][i];
			realTwo[j][i] = realTwo[i][j];
			realTwo[i][j] = temprealTwo;
			double tempimagTwo = 0.0;
			tempimagTwo = imagTwo[j][i];
			imagTwo[j][i] = imagTwo[i][j];
			imagTwo[i][j] = tempimagTwo;
		}
	}
	for (int j = 0; j < 8; j++)
	{
		for (int i = j; i < 8; i++)
		{
			cout << realTwo[j][i] << endl;
		}
	}
	getchar();
	return 0;
}


  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值