c语言中使用fft函数的简单介绍

想用C语言实现一个1024点的FFT,找到的基2-FFT的程序能实现128以内的FFT,运行结果和matlab的fft()是一样的我也写了个fft程序,256点时计算还正确,但是512和1024点结果就错了,希望楼主答案的话能告知,
求基2、基4、基8FFT(快速傅里叶变换)的c语言程序,要能运行得出来的1.FFTc语言中使用fft函数:
// data为输入和输出c语言中使用fft函数的数据c语言中使用fft函数,N为长度
bool CFFT::Forward(complex *const Data, const unsigned int N)
{
if (!Data || N1 || N(N - 1))
return false;
//排序
Rearrange(Data, N);
//FFT计算c语言中使用fft函数:const bool Inverse = false
Perform(Data, N);
return true;
}
2.IFFT:
// Scale 为是否缩放
bool CFFT::Inverse(complex *const Data, const unsigned int N,
const bool Scale /* = true */)
{
if (!Data || N1 || N(N - 1))
return false;
//排序
Rearrange(Data, N);
//FFT计算c语言中使用fft函数,ture表示是逆运算
Perform(Data, N, true);
//对结果进行缩放
if (Scale)
CFFT::Scale(Data, N);
return true;
}
3.排序:
void CFFT::Rearrange(complex *const Data, const unsigned int N)
{
//Swap position
unsigned int Target = 0;
//Process all positions of input signal
for (unsigned int Position = 0; PositionN;Position)
{
//Only for not yet swapped entries
if (TargetPosition)
{
//Swap entries
const complex Temp(Data[Target]);
Data[Target] = Data[Position];
Data[Position] = Temp;
}
//Bit mask
unsigned int Mask = N;
//While bit is set
while (Target(Mask = 1))
//Drop bit
Target = ~Mask;
//The current bit is 0 - set it
Target |= Mask;
}
}
4.FFT计算:
void CFFT::Perform(complex *const Data, const unsigned int N,
const bool Inverse /* = false */)
{
const double pi = Inverse ? 3.14159265358979323846 : -3.14159265358979323846;
//Iteration through dyads, quadruples, octads and so on...
for (unsigned int Step = 1; StepN; Step = 1)
{
//Jump to the next entry of the same transform factor
const unsigned int Jump = Step1;
【c语言中使用fft函数的简单介绍】//Angle increment
const double delta = pi / double(Step);
//Auxiliary sin(delta / 2)
const double Sine = sin(delta * .5);
//Multiplier for trigonometric recurrence
const complex Multiplier(-2. * Sine * Sine, sin(delta));
//Start value for transform factor, fi = 0
complex Factor(1.);
//Iteration through groups of different transform factor
for (unsigned int Group = 0; GroupStep;Group)
{
//Iteration within group
for (unsigned int Pair = Group; PairN; Pair= Jump)
{
//Match position
const unsigned int Match = PairStep;
//Second term of two-point transform
const complex Product(Factor * Data[Match]);
//Transform for fipi
Data[Match] = Data[Pair] - Product;
//Transform for fi
Data[Pair]= Product;
}
//Successive transform factor via trigonometric recurrence
Factor = Multiplier * FactorFactor;
}
}
}
5.缩放:
void CFFT::Scale(complex *const Data, const unsigned int N)
{
const double Factor = 1. / double(N);
//Scale all data entries
for (unsigned int Position = 0; PositionN;Position)
Data[Position] *= Factor;
}
跪求大师用C语言帮我编一个8点基-2按时间抽取的FFT程序用递归应该比较容易写的,虽然效率差一些
大概思路:
用一个函数做准备:
把数组排列成到位序
计算Wn
对整个数组调用 do_fft函数
do_fft函数:
如果需要计算的序列长为2,两个位置分别写为x[0] x[1]和x[0]-x[1]然后返回
对需要计算的序列前半部分调用do_fft函数
对需要计算的序列后半副本调用do_fft函数
for (int i=0; ilength/2;i) {
x[i length/2] *= Wi;注意这里需要先确定需要的是哪个W
x[i]和x[i length/2] 分别改写为 x[i] x[i length/2]和x[i]-x[i length/2]
}
这样两个函数应该就差不多了
求FFT的c语言程序快速傅里叶变换 要用C才行吧你可以用MATLAB来实现更方便点啊
此FFT 是用VC6.0编写 , 由FFT.CPPc语言中使用fft函数;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 : 定义控制台应用程序c语言中使用fft函数的入口点 。
#include "stdafx.h"
#include iostream
#include complex
#include bitset
#include vector
#include conio.h
#include string
#include fstream
using namespace std;
bool inputData(unsigned long , vectorcomplexdouble );//手工输入数据
void FFT(unsigned long , vectorcomplexdouble );//FFT变换
void display(unsigned long , vectorcomplexdouble );//显示结果
bool readDataFromFile(unsigned long , vectorcomplexdouble );//从文件中读取数据
bool saveResultToFile(unsigned long , vectorcomplexdouble );//保存结果至文件中
const double PI = 3.1415926;
int _tmain(int argc, _TCHAR* argv[])
{
vectorcomplexdoublevecList;//有限长序列
unsigned long ulN = 0;//N
char chChoose = ' ';//功能选择
//功能循环
while(chChoose != 'Q'chChoose != 'q')
{
//显示选择项
cout"\nPlease chose a function"endl;
cout"\t1.Input data manually, press 'M':"endl;
cout"\t2.Read data from file, press 'F':"endl;
cout"\t3.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(ul2)
return false;
while( ul1 )
{
if( ul % 2 )
return false;
ul /= 2;
}
return true;
}
bool inputData(unsigned longulN, vectorcomplexdoublevecList)
{
//题目
cout "\n\n\n==============================Input Datahttps://www.04ip.com/post/==============================="endl;
//输入N
cout "\nInput N:";
cinulN;
if(!Is2Power(ulN))//验证N的有效性
{
cout "N is invalid (N must like 2, 4, 8, .....), please retry."endl;
return false;
}
//输入各元素
vecList.clear();//清空原有序列
complexdouble c;
for(unsigned long i = 0; iulN; i)
{
cout"Input x("i"):";
cinc;
vecList.push_back(c);
}
return true;
}
bool readDataFromFile(unsigned longulN, vectorcomplexdoublevecList)//从文件中读取数据
{
//题目
cout "\n\n\n===============Read Data From File=============="endl;
//输入文件名
string strfilename;
cout"Input filename:" ;
cinstrfilename;
//打开文件
cout"open file "strfilename"......." endl;
ifstream loadfile;
loadfile.open(strfilename.c_str());
if(!loadfile)
{
cout"\tfailed"endl;
return false;
}
else
{
cout"\tsucceed"endl;
}
vecList.clear();
//读取N
loadfileulN;
if(!loadfile)
{
cout"can't get N"endl;
return false;
}
else
{
cout"N = "ulNendl;
}
//读取元素
complexdouble c;
for(unsigned long i = 0; iulN; i)
{
loadfilec;
if(!loadfile)
{
cout"can't get enough infomation"endl;
return false;
}
else
cout"x("i") = "cendl;
vecList.push_back(c);
}
//关闭文件
loadfile.close();
return true;
}
bool saveResultToFile(unsigned longulN, vectorcomplexdoublevecList) //保存结果至文件中
{
//询问是否需要将结果保存至文件
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"\nInput file name:" ;
cinstrfilename;
cout"Save result to file "strfilename"......"endl;
//打开文件
ofstream savefile(strfilename.c_str());
if(!savefile)
{
cout"can't open file"endl;
return false;
}
//写入N
savefileulNendl;
//写入元素
for(vectorcomplexdouble ::iterator i = vecList.begin(); ivecList.end(); i)
{
savefile*iendl;
}
//写入完毕
cout"save succeed."endl;
//关闭文件
savefile.close();
return true;
}
void FFT(unsigned longulN, vectorcomplexdoublevecList)
{
//得到幂数
unsigned long ulPower = 0;//幂数
unsigned long ulN1 = ulN - 1;
while(ulN10)
{
ulPower;
ulN1 /= 2;
}
//反序
bitsetsizeof(unsigned long) * 8 bsIndex;//二进制容器
unsigned long ulIndex;//反转后的序号
unsigned long ulK;
for(unsigned long p = 0; pulN; p)
{
ulIndex = 0;
ulK = 1;
bsIndex = bitsetsizeof(unsigned long) * 8(p);
for(unsigned long j = 0; julPower; j)
{
ulIndex= bsIndex.test(ulPower - j - 1) ? ulK : 0;
ulK *= 2;
}
if(ulIndexp)
{
complexdouble c = vecList[p];
vecList[p] = vecList[ulIndex];
vecList[ulIndex] = c;
}
}
//计算旋转因子
vectorcomplexdoublevecW;
for(unsigned long i = 0; iulN / 2; i)
{
vecW.push_back(complexdouble(cos(2 * i * PI / ulN) , -1 * sin(2 * i * PI / ulN)));
}
for(unsigned long m = 0; mulN / 2; m)
{
cout "\nvW["m"]="vecW[m];
}
//计算FFT
unsigned long ulGroupLength= 1;//段的长度
unsigned long ulHalfLength = 0;//段长度的一半
unsigned long ulGroupCount = 0;//段的数量
complexdouble cw;//WH(x)
complexdouble c1;//G(x)WH(x)
complexdouble c2;//G(x) - WH(x)
for(unsigned long b = 0; bulPower; b)
{
ulHalfLength = ulGroupLength;
ulGroupLength *= 2;
for(unsigned long j = 0; julN; j= ulGroupLength)
{
for(unsigned long k = 0; kulHalfLength; k)
{
cw = vecW[k * ulN / ulGroupLength] * vecList[jkulHalfLength];
c1 = vecList[jk]cw;
c2 = vecList[jk] - cw;
vecList[jk] = c1;
vecList[jkulHalfLength] = c2;
}
}
}
}
void display(unsigned longulN, vectorcomplexdoublevecList)
{
cout"\n\n===========================Display The Result========================="endl;
for(unsigned long d = 0; dulN;d)
{
cout"X("d")\t\t\t = "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 中
//引用任何所需的附加头文件 , 而不是在此文件中引用
关于c语言中使用fft函数和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读