c++ 实现数字信号处理FFT 算法

 以下是定义复数头文件,为后面的傅里叶变换做准备,因为c语言中并不支持复数运算,所以需要重载运算符并定义复数类。

​
#ifndef FUSHU_H
#define FUSHU_H
#include <iostream>

using namespace std;
#include "yinzi.h"

#define PI 3.1415926

class Z
{
private:
	float r;
	float i;
public:
	Z(float R = 0, float I = 0);
	~Z() {};
	Z operator=(const Z z1);
	Z operator+(const Z z1);
	Z operator-(const Z z1);
	Z operator*(const Z z1);
	Z operator/(const Z z1);
	void priZ();
	void getZ(float R , float I );
};


Z::Z(float R , float I )
{
	r = R;
	i = I;
}
Z Z::operator=(const Z z1)
{
	this->r = z1.r;
	this->i = z1.i;
	return *this;
}



Z Z:: operator+(const Z z1)
{
	Z temp;
	temp.r = this->r + z1.r;
	temp.i = this->i + z1.i;
	return temp;
}
Z Z::operator-(const Z z1)
{
	Z temp;
	temp.r = this->r - z1.r;
	temp.i = this->i - z1.i;
	return temp;
}
Z Z::operator*(const Z z1)
{
	Z temp;
	temp.r = (this->r * z1.r) - (this->i*z1.i);
	temp.i = (this->r*z1.i) + (this->i*z1.r);
	return temp;
}
Z Z::operator/(const Z z1)
{
	return 0;
}

void Z::priZ()
{
	//cout << r << "+ i" << i;
	printf("%f + i(%f)", r, i);
}

void Z::getZ(float R , float I )
{
	r = R;
	i = I;
}


#endif

​

以下头文件 是定义fft算法中的旋转因子 

#ifndef YINZI_H
#define YINZI_H
#include "fushu.h"
#include <math.h>
#define PI 3.1415926

class W 
{
public:
	int N;
	int P;
	float r;
	float i;
	W(int n, int p);
	void getW(int n, int p);
	Z operator*(Z z1);
	void priW();
};
W::W(int n, int p)
{
	N = n;
	P = p;
	r = cos((2 * PI / N)*P);
	i = -sin((2 * PI / N)*P);

}
void W::getW(int n, int p)
{
	N = n;
	P = p;
	r = cos((2 * PI / N)*P);
	i = -sin((2 * PI / N)*P);
}
Z W::operator*(Z z1)
{
	Z temp(r,i);
	temp = temp * z1;
	return temp;
}
void W:: priW()
{
	//cout << r << "+ i" << i;
	printf("%f + i(%f)",r,i);

}


#endif

接下来就是快速傅里叶变换的代码段

#include "fushu.h"
void FourierTrans(Z *arr, int N);
void arrTrans(Z *arr, int N, int M);
void arrTrans1(Z *arr, int N);












void FourierTrans(Z *arr, int N)
{
	int M=0;//数组变换级数
	int Q = 1;//当N不是2的M次方时,取除以2的M-1次方的余数
	int count = N;
	Z *arr1 = new Z[N];
	for (int i=0;i<N;i++)
	{
		arr1[i] = arr[i];

	}
	for (;;)//得到数组级数
	{
		if (count % 2 == 0)
		{
			M++;
		}
		else
		{
			Q = count ;
			break;

		}
		count = count / 2;
	}
	//cout << M << endl << Q;
	if (Q == 1)
	{
		arrTrans(arr1,  N,  M);
	}
	else//Q不为1
	{

	}
	for (int i = M; i >0; i--)
	{
		int DCount = N /pow(2,i) ;
		W w(N / pow(2, i - 1), 0);
		//int c = 0;
		bool x =true;
		int j = 0;
		int temp = 0;
		for (int c = 0; c < N;c++)
		{
			int p = c % DCount;
			w.getW(N / pow(2, i - 1), p);
			if (x) 
			{
				arr[c] = arr1[j] + w * arr1[j + DCount];
			
			}
			else
			{
				arr[c] = arr1[j] - w * arr1[j + DCount];
			
			}
			j++;

			if (c % (2 * DCount) == 2 * DCount - 1)temp = temp + 2 * DCount;//3
			if (c % DCount == DCount - 1)//每DCount个一组  每组运算过程一变//1
			{
				x = !x;
				j = temp;
			}
			
		}
		for (int i = 0; i<N; i++)
		{
			arr1[i] = arr[i];
		}
	}

	delete[]arr1;
}

void arrTrans(Z *arr, int N, int M)
{
	Z *arr1 = new Z[N];
	for (int i = 0; i<N; i++)
	{
		arr1[i] = arr[i];
	}
	for (int i = 0; i <M; i++)
	{
		int duanshu = pow(2, i);
		for (int j = 0; j < duanshu; j++)
		{
			arrTrans1((arr + j * (N / duanshu)), N / duanshu);
		}
	}
	delete[]arr1;
}


void arrTrans1(Z *arr, int N)
{
	Z *arr1 = new Z[N];
	for (int i = 0; i<N; i++)
	{
		arr1[i] = arr[i];
	}
	int n=0;
	for (int i = 0; i < N; i++)
	{
		if (i % 2 == 0)
		{
			arr[n] = arr1[i];
		}
		else
		{
			arr[n + N / 2] = arr1[i];
			n++;
		}
		
	}
	delete[]arr1;

}

然后就是在主函数中测试傅里叶变换的结果

#include <iostream>
#include <stdlib.h>
#include "yinzi.h"
#include "fuliye.h"
using namespace std;
#define PI 3.1415926


int main()
{

	Z x[8];
	for (int i = 0; i < 8; i++)
	{
		x[i].getZ(i, 0);
	}
	for (int i = 0; i < 8; i++)
	{
		x[i].priZ();
		cout << endl;
	}

	cout << "******************************" << endl;

	FourierTrans(x, 8);
	for (int i = 0; i < 8; i++)
	{
		x[i].priZ();
		cout << endl;
	}

	system("pause");
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值