以下是定义复数头文件,为后面的傅里叶变换做准备,因为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;
}