【第22期】观点:IT 行业加班,到底有没有价值?

FFT快速傅立叶算法纯C语言版本

原创 2015年07月08日 16:03:33
</pre><p>快速离散傅立叶变换FFT利用DFT计算的对称性实现的,具体的介绍网上一大堆。这次自己写了个定点FFT头文件,直接用C语言写的很容易移植。</p><p></p><p><pre name="code" class="cpp">/*
     快速离散傅立叶算法V1.0
	   含有:FFT,IFFT
         made by xyt
		  2015/7/8
		   C语言
*/
#ifndef _FFT_H
#define _FFT_H
#include<math.h>

#define FFT_N 8  //点数,要求2的次方

#define PI 3.14159265354
struct fft_complex{
	double r,i;
};
int fft_fi(double in){  //四舍五入转整
	if((in-(int)in)>0.5) return (int)in+1;
	else return (int)in;
}
int fft_fac2(int n){   //返回log2(n)
	int count=0;
	while(n/2!=0){
		n/=2;count++;
	}
	return count;
}
int fft_turndat(int n,int num){ 
	int g=n,m,r=0;
	int count=0;
	while(num/2!=0){
		num/=2;count++;
	} 
	while(count>=0){
		m=g%2;
		r+=m*pow(2,--count);
		g/=2;
	}
	return r;
}
fft_complex fft_t(fft_complex a){
	fft_complex tmp;
	tmp.i=-1*a.i;
	tmp.r=-1*a.r;
	return tmp;
}
fft_complex fft_multi(fft_complex a,fft_complex b){
	fft_complex tmp;
	tmp.r=a.r*b.r-a.i*b.i;
	tmp.i=a.r*b.i+a.i*b.r;
	return tmp;
}
fft_complex fft_add(fft_complex a,fft_complex b){
	fft_complex tmp;
	tmp.r=a.r+b.r;
	tmp.i=a.i+b.i;
	return tmp;
}
/* 定点FFT,返回两个double型数组分别是实部和虚部 */
void FFT(int *in,double *outr,double *outi) 
{
	int i,j;
	int deep;
	const int N=FFT_N/2;
	fft_complex W[N];
	W[0].r=1;W[0].i=0;
	W[1].r=cos(2.0*PI/FFT_N);
	W[1].i=sin(2.0*PI/FFT_N);
	for(i=2;i<N;i++){
		W[i]=fft_multi(W[1],W[i-1]);
	}
	deep=fft_fac2(FFT_N);
	int g=1;
	int ne=0,ge=0;

	fft_complex left[FFT_N];
	fft_complex right[FFT_N];
	for(i=0;i<FFT_N;i++){
		left[i].r=in[fft_turndat(i,FFT_N)];
		left[i].i=0;
	}
	fft_complex tpp;
	int mggtmp;
	while(1)
	{
		if(deep==0) break;
		int adt=pow(2,deep-1);
		mggtmp=pow(2,g);
		for(i=0;i<FFT_N;i+=mggtmp){ 
			ne=0;ge=0;
			for(j=0;j<mggtmp;j++){
				if(j<mggtmp/2){
					tpp=fft_multi(left[i+j+mggtmp/2],W[ne]);
					right[i+j]=fft_add(left[i+j],tpp);ne+=adt;
				}else{
					tpp=fft_t(fft_multi(left[i+j],W[ge]));
					right[i+j]=fft_add(left[i+j-mggtmp/2],tpp);ge+=adt;
				}
			}
		}
		for(i=0;i<FFT_N;i++){
			left[i]=right[i];
		}
		deep--;g++;
	}
	for(i=0;i<FFT_N;i++){
		outr[i]=left[i].r;
		outi[i]=-1*left[i].i;
	}
}
/* 定点IFFT,输入实部和虚部,返回时域int类型 */
void IFFT(double *inr,double *ini,int *out) 
{
	int i,j;
	int deep;
	const int N=FFT_N/2;
	fft_complex W[N];
	W[0].r=1;W[0].i=0;
	W[1].r=cos(2.0*PI/FFT_N);
	W[1].i=-1*sin(2.0*PI/FFT_N);
	for(i=2;i<N;i++){
		W[i]=fft_multi(W[1],W[i-1]);
	}
	deep=fft_fac2(FFT_N);
	int g=1;
	int ne=0,ge=0;

	fft_complex left[FFT_N];
	fft_complex right[FFT_N];
	for(i=0;i<FFT_N;i++){
		left[i].r=inr[fft_turndat(i,FFT_N)];
		left[i].i=-1*ini[fft_turndat(i,FFT_N)];
	}
	fft_complex tpp;
	int mggtmp;
	while(1)
	{
		if(deep==0) break;
		int adt=pow(2,deep-1);
		mggtmp=pow(2,g);
		for(i=0;i<FFT_N;i+=mggtmp){ 
			ne=0;ge=0;
			for(j=0;j<mggtmp;j++){
				if(j<mggtmp/2){
					tpp=fft_multi(left[i+j+mggtmp/2],W[ne]);
					right[i+j]=fft_add(left[i+j],tpp);ne+=adt;
				}else{
					tpp=fft_t(fft_multi(left[i+j],W[ge]));
					right[i+j]=fft_add(left[i+j-mggtmp/2],tpp);ge+=adt;
				}
			}
		}
		for(i=0;i<FFT_N;i++){
			left[i]=right[i];
		}
		deep--;g++;
	}
	for(i=0;i<FFT_N;i++){
		out[i]=fft_fi(left[i].r/FFT_N);
	}
}
#endif



版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

用c语言实现的FFT

一、对FFT的介绍 1. FFT(Fast Fourier Transformation),即为快速傅里叶变换,是离散傅里叶变换的快速算法,它是根据离散傅里叶变换的奇、偶、虚、实等特性,对离散傅里叶变...

FFT快速算法及C语言实现

在word上编辑的文本,上传时发现公式传不上来,我又懒得再敲一遍,截个图传上来。

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

FFT算法理解与c语言的实现

FFT算法分析与c语言实现

FFT的C语言算法实现

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0程序如下:  /************FFT***********/  #incl...

用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台)

代码在2011年全国电子大赛结束后(2011年9月3日)发布,多个版本,注释详细。 /********************************************************...

网上找的纯C实现的FFT,与matlab计算结果完全一样

直接上代码了 fft.c
  • cp1300
  • cp1300
  • 2014-06-06 08:20
  • 15944

推荐一个C语言的FFT开源库

该开源库名为:Fast Forier Transform in the West, FFTW;是MIT的一个名为Matteo Frigo 的人编写的,目前该库经过SSE,SSE2,AVX等X86上汇编...

FFT变换的C语言实现

FFT变换的C语言实现 1、安装FFTW3库文件 FFTW是用来计算一维或者多维的离散傅里叶变换,输入可以为实数序列也可以为复数序列的C语言的子函数库,FFTW是免费软件,是作为fft函数库的各种应用...

二维FFT,IFFT,c语言实现

图像FFT,二维FFT,二维IFFT,C语言实现

包络检波概要

普通条幅波AM可以用包络检波来得到中频信号 下面是包络检波电路: 注意:上图电路中经推算输入电阻约等于R/2 (左端电压除以流经二极管的电流) 基本原理:左端输入电压正向作用于二极管时,电流经...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)