包含fft算法的c语言实现的词条 大家并不陌生,借来给大家详细说说吧!
求FFT的c语言程序
分类: 教育/科学 学习帮助
问题描述:
追20分
解析:
快速傅里叶变换 要用C++ 才行吧 你可以用MATLAB来实现更方便点啊
此FFT 是用VC6.0编写,由FFT.CPP;STDAFX.H和STDAFX.CPP三个文件组成,编译成功。程序可以用文件输入和输出为文件。文件格式为TXT文件。测试结果如下:
输入文件:8.TXT 或手动输入
8 N
1
2
3
4
5
6
7
8
输出结果为:或保存为TXT文件。(8OUT.TXT)
8
(36,0)
(-4,9.65685)
(-4,4)
(-4,1.65685)
(-4,0)
(-4,-1.65685)
(-4,-4)
(-4,-9.65685)
下面为FFT.CPP文件:
FFT.cpp : 定义控制台应用程序的入口点。
#include “stdafx.h”
#include iostream
#include plex
#include bitset
#include vector
#include conio.h
#include string
#include fstream
using namespace std;
bool inputData(unsigned long , vectorplexdouble ); 手工输入数据
void FFT(unsigned long , vectorplexdouble ); FFT变换
void display(unsigned long , vectorplexdouble ); 显示结果
bool readDataFromFile(unsigned long , vectorplexdouble ); 从文件中读取数据
bool saveResultToFile(unsigned long , vectorplexdouble ); 保存结果至文件中
const double PI = 3.1415926;
int _tmain(int argc, _TCHAR* argv[])
{
vectorplexdouble vecList; 有限长序列
unsigned long ulN = 0; N
char chChoose = ‘ ‘; 功能选择
功能循环
while(chChoose != ‘Q’ chChoose != ‘q’)
{
显示选择项
cout “
Please chose a function” endl;
cout ” 1.Input data manually, press ‘M’:” endl;
cout ” 2.Read data from file, press ‘F’:” endl;
cout ” 3.Quit, press ‘Q'” endl;
cout “Please chose:”;
输入选择
chChoose = getch();
判断
switch(chChoose)
{
case ‘m’: 手工输入数据
case ‘M’:
if(inputData(ulN, vecList))
{
FFT(ulN, vecList);
display(ulN, vecList);
saveResultToFile(ulN, vecList);
}
break;
case ‘f’: 从文档读取数据
case ‘F’:
if(readDataFromFile(ulN, vecList))
{
FFT(ulN, vecList);
display(ulN, vecList);
saveResultToFile(ulN, vecList);
}
break;
}
}
return 0;
}
bool Is2Power(unsigned long ul) 判断是否是2的整数次幂
{
if(ul 2)
return false;
while( ul 1 )
{
if( ul % 2 )
return false;
ul /= 2;
}
return true;
}
bool inputData(unsigned long ulN, vectorplexdouble vecList)
{
题目
cout “
==============================Input Data===============================” endl;
输入N
cout “
Input N:”;
cinulN;
if(!Is2Power(ulN)) 验证N的有效性
{
cout “N is invalid (N must like 2, 4, 8, …..), please retry.” endl;
return false;
}
输入各元素
vecList.clear(); 清空原有序列
plexdouble c;
for(unsigned long i = 0; i ulN; i++)
{
cout “Input x(” i “):”;
cin c;
vecList.push_back(c);
}
return true;
}
bool readDataFromFile(unsigned long ulN, vectorplexdouble vecList) 从文件中读取数据
{
题目
cout “
===============Read Data From File==============” endl;
输入文件名
string strfilename;
cout “Input filename:” ;
cin strfilename;
打开文件
cout “open file ” strfilename “…….” endl;
ifstream loadfile;
loadfile.open(strfilename.c_str());
if(!loadfile)
{
cout ” failed” endl;
return false;
}
else
{
cout ” succeed” endl;
}
vecList.clear();
读取N
loadfile ulN;
if(!loadfile)
{
cout “can’t get N” endl;
return false;
}
else
{
cout “N = ” ulN endl;
}
读取元素
plexdouble c;
for(unsigned long i = 0; i ulN; i++)
{
loadfile c;
if(!loadfile)
{
cout “can’t get enough infomation” endl;
return false;
}
else
cout “x(” i “) = ” c endl;
vecList.push_back(c);
}
关闭文件
loadfile.close();
return true;
}
bool saveResultToFile(unsigned long ulN, vectorplexdouble vecList) 保存结果至文件中
{
询问是否需要将结果保存至文件
char chChoose = ‘ ‘;
cout “Do you want to save the result to file? (y/n):”;
chChoose = _getch();
if(chChoose != ‘y’ chChoose != ‘Y’)
{
return true;
}
输入文件名
string strfilename;
cout “
Input file name:” ;
cin strfilename;
cout “Save result to file ” strfilename “……” endl;
打开文件
ofstream savefile(strfilename.c_str());
if(!savefile)
{
cout “can’t open file” endl;
return false;
}
写入N
savefile ulN endl;
写入元素
for(vectorplexdouble ::iterator i = vecList.begin(); i vecList.end(); i++)
{
savefile *i endl;
}
写入完毕
cout “save succeed.” endl;
关闭文件
savefile.close();
return true;
}
void FFT(unsigned long ulN, vectorplexdouble vecList)
{
得到幂数
unsigned long ulPower = 0; 幂数
unsigned long ulN1 = ulN – 1;
while(ulN1 0)
{
ulPower++;
ulN1 /= 2;
}
反序
bitsetsizeof(unsigned long) * 8 bsIndex; 二进制容器
unsigned long ulIndex; 反转后的序号
unsigned long ulK;
for(unsigned long p = 0; p ulN; p++)
{
ulIndex = 0;
ulK = 1;
bsIndex = bitsetsizeof(unsigned long) * 8(p);
for(unsigned long j = 0; j ulPower; j++)
{
ulIndex += bsIndex.test(ulPower – j – 1) ? ulK : 0;
ulK *= 2;
}
if(ulIndex p)
{
plexdouble c = vecList[p];
vecList[p] = vecList[ulIndex];
vecList[ulIndex] = c;
}
}
计算旋转因子
vectorplexdouble vecW;
for(unsigned long i = 0; i ulN / 2; i++)
{
vecW.push_back(plexdouble(cos(2 * i * PI / ulN) , -1 * sin(2 * i * PI / ulN)));
}
for(unsigned long m = 0; m ulN / 2; m++)
{
cout “
vW[” m “]=” vecW[m];
}
计算FFT
unsigned long ulGroupLength = 1; 段的长度
unsigned long ulHalfLength = 0; 段长度的一半
unsigned long ulGroupCount = 0; 段的数量
plexdouble cw; WH(x)
plexdouble c1; G(x) + WH(x)
plexdouble c2; G(x) – WH(x)
for(unsigned long b = 0; b ulPower; b++)
{
ulHalfLength = ulGroupLength;
ulGroupLength *= 2;
for(unsigned long j = 0; j ulN; j += ulGroupLength)
{
for(unsigned long k = 0; k ulHalfLength; k++)
{
cw = vecW[k * ulN / ulGroupLength] * vecList[j + k + ulHalfLength];
c1 = vecList[j + k] + cw;
c2 = vecList[j + k] – cw;
vecList[j + k] = c1;
vecList[j + k + ulHalfLength] = c2;
}
}
}
}
void display(unsigned long ulN, vectorplexdouble vecList)
{
cout “
===========================Display The Result=========================” endl;
for(unsigned long d = 0; d ulN;d++)
{
cout “X(” d “) = ” vecList[d] endl;
}
}
下面为STDAFX.H文件:
stdafx.h : 标准系统包含文件的包含文件,
或是常用但不常更改的项目特定的包含文件
#pragma once
#include iostream
#include tchar.h
TODO: 在此处引用程序要求的附加头文件
下面为STDAFX.CPP文件:
stdafx.cpp : 只包括标准包含文件的源文件
FFT.pch 将成为预编译头
stdafx.obj 将包含预编译类型信息
#include “stdafx.h”
TODO: 在 STDAFX.H 中
引用任何所需的附加头文件,而不是在此文件中引用
求FFT的C语言实现
#include stdio.h
#include math.h
#include stdlib.h
#define N 1000
/*定义复数类型*/
typedef struct{
double real;
double img;
}complex;
complex x[N], *W; /*输入序列,变换核*/
int size_x=0; /*输入序列的大小,在本程序中仅限2的次幂*/
double PI; /*圆周率*/
void fft(); /*快速傅里叶变换*/
void initW(); /*初始化变换核*/
void change(); /*变址*/
void add(complex ,complex ,complex *); /*复数加法*/
void mul(complex ,complex ,complex *); /*复数乘法*/
void sub(complex ,complex ,complex *); /*复数减法*/
void output();
int main(){
int i; /*输出结果*/
system(“cls”);
PI=atan(1)*4;
printf(“Please input the size of x:
”);
scanf(“%d”,size_x);
printf(“Please input the data in x[N]:
”);
for(i=0;isize_x;i++)
scanf(“%lf%lf”,x[i].real,x[i].img);
initW();
fft();
output();
return 0;
}
/*快速傅里叶变换*/
void fft(){
int i=0,j=0,k=0,l=0;
complex up,down,product;
change();
for(i=0;i log(size_x)/log(2) ;i++){ /*一级蝶形运算*/
l=1i;
for(j=0;jsize_x;j+= 2*l ){ /*一组蝶形运算*/
for(k=0;kl;k++){ /*一个蝶形运算*/
mul(x[j+k+l],W[size_x*k/2/l],product);
add(x[j+k],product,up);
sub(x[j+k],product,down);
x[j+k]=up;
x[j+k+l]=down;
}
}
}
}
/*初始化变换核*/
void initW(){
int i;
W=(complex *)malloc(sizeof(complex) * size_x);
for(i=0;isize_x;i++){
W[i].real=cos(2*PI/size_x*i);
W[i].img=-1*sin(2*PI/size_x*i);
}
}
/*变址计算,将x(n)码位倒置*/
void change(){
complex temp;
unsigned short i=0,j=0,k=0;
double t;
for(i=0;isize_x;i++){
k=i;j=0;
t=(log(size_x)/log(2));
while( (t–)0 ){
j=j1;
j|=(k 1);
k=k1;
}
if(ji){
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
}
}
/*输出傅里叶变换的结果*/
void output(){
int i;
printf(“The result are as follows
”);
for(i=0;isize_x;i++){
printf(“%.4f”,x[i].real);
if(x[i].img=0.0001)printf(“+%.4fj
”,x[i].img);
else if(fabs(x[i].img)0.0001)printf(“
”);
else printf(“%.4fj
”,x[i].img);
}
}
void add(complex a,complex b,complex *c){
c-real=a.real+b.real;
c-img=a.img+b.img;
}
void mul(complex a,complex b,complex *c){
c-real=a.real*b.real – a.img*b.img;
c-img=a.real*b.img + a.img*b.real;
}
void sub(complex a,complex b,complex *c){
c-real=a.real-b.real;
c-img=a.img-b.img;
}
怎么用C语言实现FFT算法 呀
float ar[1024],ai[1024];/* 原始数据实部,虚部 */
float a[2050];
void fft(int nn) /* nn数据长度 */
{
int n1,n2,i,j,k,l,m,s,l1;
float t1,t2,x,y;
float w1,w2,u1,u2,z;
float fsin[10]={0.000000,1.000000,0.707107,0.3826834,0.1950903,0.09801713,0.04906767,0.02454123,0.01227154,0.00613588,};
float fcos[10]={-1.000000,0.000000,0.7071068,0.9238796,0.9807853,0.99518472,0.99879545,0.9996988,0.9999247,0.9999812,};
switch(nn)
{
case 1024: s=10; break;
case 512: s=9; break;
case 256: s=8; break;
}
n1=nn/2; n2=nn-1;
j=1;
for(i=1;i=nn;i++)
{
a[2*i]=ar[i-1];
a[2*i+1]=ai[i-1];
}
for(l=1;ln2;l++)
{
if(lj)
{
t1=a[2*j];
t2=a[2*j+1];
a[2*j]=a[2*l];
a[2*j+1]=a[2*l+1];
a[2*l]=t1;
a[2*l+1]=t2;
}
k=n1;
while (kj)
{
j=j-k;
k=k/2;
}
j=j+k;
}
for(i=1;i=s;i++)
{
u1=1;
u2=0;
m=(1i);
k=m1;
w1=fcos[i-1];
w2=-fsin[i-1];
for(j=1;j=k;j++)
{
for(l=j;lnn;l=l+m)
{
l1=l+k;
t1=a[2*l1]*u1-a[2*l1+1]*u2;
t2=a[2*l1]*u2+a[2*l1+1]*u1;
a[2*l1]=a[2*l]-t1;
a[2*l1+1]=a[2*l+1]-t2;
a[2*l]=a[2*l]+t1;
a[2*l+1]=a[2*l+1]+t2;
}
z=u1*w1-u2*w2;
u2=u1*w2+u2*w1;
u1=z;
}
}
for(i=1;i=nn/2;i++)
{
ar[i]=4*a[2*i+2]/nn; /* 实部 */
ai[i]=-4*a[2*i+3]/nn; /* 虚部 */
a[i]=4*sqrt(ar[i]*ar[i]+ai[i]*ai[i]); /* 幅值 */
}
}
(;si=2)
最后,我要感谢所有支持和关注嗨壳技术分享网(www.heikehao.com)的人们,是你们的支持和鼓励使我们更加坚定了创办这个平台的决心。我们将致力于为大家提供更好的内容和服务,为技术爱好者们搭建一个学习、分享和进步的家园。
原创文章,作者:语言我知,如若转载,请注明出处:https://www.heikehao.com/22826.html