C语言、Matlab实现FFT几种编程实例

合集下载

MATLAB中FFT的运用方法

MATLAB中FFT的运用方法

MATLAB中FFT的使用方法说明:以下资源来源于《数字信号处理的MATLAB实现》万永革主编一.调用方法X=FFT(x);X=FFT(x,N);x=IFFT(X);x=IFFT(X,N)用MATLAB进行谱分析时注意:(1)函数FFT返回值的数据结构具有对称性。

例:N=8;n=0:N-1;xn=[4 3 2 6 7 8 9 0];Xk=fft(xn)→Xk =39.0000 -10.7782 + 6.2929i 0 - 5.0000i 4.7782 - 7.7071i 5.0000 4.7782 + 7.7071i 0 + 5.0000i -10.7782 - 6.2929iXk与xn的维数相同,共有8个元素。

Xk的第一个数对应于直流分量,即频率值为0。

(2)做FFT分析时,幅值大小与FFT选择的点数有关,但不影响分析结果。

在IFFT时已经做了处理。

要得到真实的振幅值的大小,只要将得到的变换后结果乘以2除以N即可。

二.FFT应用举例例1:x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t)。

采样频率fs=100Hz,分别绘制N=128、1024点幅频图。

clf;fs=100;N=128; %采样频率和数据点数n=0:N-1;t=n/fs; %时间序列x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求得Fourier变换后的振幅f=n*fs/N; %频率序列subplot(2,2,1),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;subplot(2,2,2),plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;%对信号采样数据为1024点的处理fs=100;N=1024;n=0:N-1;t=n/fs;x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求取Fourier变换的振幅f=n*fs/N;subplot(2,2,3),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;subplot(2,2,4)plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;运行结果:fs=100Hz,Nyquist频率为fs/2=50Hz。

Matlab编程实现FFT变换

Matlab编程实现FFT变换

Matlab编程实现FFT变换及频谱分析的程序代码内容1.用Matlab产生正弦波,矩形波,以及白噪声信号,并显示各自时域波形图2.进行FFT变换,显示各自频谱图,其中采样率,频率、数据长度自选3.做出上述三种信号的均方根图谱,功率图谱,以及对数均方根图谱4.用IFFT傅立叶反变换恢复信号,并显示恢复的正弦信号时域波形图源程序%*************************************************************** **********%% FFT实践及频谱分析%%*************************************************************** **********%%*************************************************************** **********%%***************1.正弦波****************%fs=100;%设定采样频率N=128;n=0:N-1;t=n/fs;f0=10;%设定正弦信号频率%生成正弦信号x=sin(2*pi*f0*t);figure(1);subplot(231);plot(t,x);%作正弦信号的时域波形xlabel('t');ylabel('y');title('正弦信号y=2*pi*10t时域波形');grid;%进行FFT变换并做频谱图y=fft(x,N);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(1);subplot(232);plot(f,mag);%做频谱图axis([0,100,0,80]);xlabel('频率(Hz)');ylabel('幅值');title('正弦信号y=2*pi*10t幅频谱图N=128');grid;%求均方根谱sq=abs(y);figure(1);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('正弦信号y=2*pi*10t均方根谱');grid;%求功率谱power=sq.^2;figure(1);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('正弦信号y=2*pi*10t功率谱');grid;%求对数谱ln=log(sq);figure(1);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('正弦信号y=2*pi*10t对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(1);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的正弦信号波形');grid;%****************2.矩形波****************% fs=10;%设定采样频率t=-5:0.1:5;x=rectpuls(t,2);x=x(1:99);figure(2);subplot(231);plot(t(1:99),x);%作矩形波的时域波形xlabel('t');ylabel('y');title('矩形波时域波形');grid;%进行FFT变换并做频谱图y=fft(x);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(2);subplot(232);plot(f,mag);%做频谱图xlabel('频率(Hz)');ylabel('幅值');title('矩形波幅频谱图');grid;%求均方根谱sq=abs(y);figure(2);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('矩形波均方根谱');grid;%求功率谱power=sq.^2;figure(2);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('矩形波功率谱');grid;%求对数谱ln=log(sq);figure(2);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('矩形波对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(2);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的矩形波波形');grid;%****************3.白噪声****************% fs=10;%设定采样频率t=-5:0.1:5;x=zeros(1,100);x(50)=100000;figure(3);subplot(231);plot(t(1:100),x);%作白噪声的时域波形xlabel('t');ylabel('y');title('白噪声时域波形');grid;%进行FFT变换并做频谱图y=fft(x);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(3);subplot(232);plot(f,mag);%做频谱图xlabel('频率(Hz)');ylabel('幅值');title('白噪声幅频谱图');grid;%求均方根谱sq=abs(y);figure(3);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('白噪声均方根谱');grid;%求功率谱power=sq.^2;figure(3);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('白噪声功率谱');grid;%求对数谱ln=log(sq);figure(3);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('白噪声对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(3);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的白噪声波形'); grid;。

MATLAB中FFT的运用

MATLAB中FFT的运用

说明:以下资源来源于《数字信号处理的MATLAB实现》万永革主编一.调用方法X=FFT(x);X=FFT(x,N);x=IFFT(X);x=IFFT(X,N)用MATLAB进行谱分析时注意:(1)函数FFT返回值的数据结构具有对称性。

例:N=8;n=0:N-1;xn=[4 3 2 6 7 8 9 0];Xk=fft(xn)→Xk =39.0000 -10.7782 + 6.2929i 0 - 5.0000i 4.7782 - 7.7071i 5.00004.7782 + 7.7071i 0 +5.0000i -10.7782 -6.2929iXk与xn的维数相同,共有8个元素。

Xk的第一个数对应于直流分量,即频率值为0。

(2)做FFT分析时,幅值大小与FFT选择的点数有关,但不影响分析结果。

在IFFT时已经做了处理。

要得到真实的振幅值的大小,只要将得到的变换后结果乘以2除以N即可。

二.FFT应用举例例1:x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t)。

采样频率fs=100Hz,分别绘制N=128、1024点幅频图。

clf;fs=100;N=128; %采样频率和数据点数n=0:N-1;t=n/fs; %时间序列x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求得Fourier变换后的振幅f=n*fs/N; %频率序列subplot(2,2,1),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;subplot(2,2,2),plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;%对信号采样数据为1024点的处理fs=100;N=1024;n=0:N-1;t=n/fs;x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求取Fourier变换的振幅f=n*fs/N;subplot(2,2,3),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;subplot(2,2,4)plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;运行结果:fs=100Hz,Nyquist频率为fs/2=50Hz。

matlab 快速傅里叶变换

matlab 快速傅里叶变换

matlab 快速傅里叶变换摘要:一、MATLAB快速傅里叶变换的基本概念1.傅里叶变换与快速傅里叶变换(FFT)2.MATLAB中的FFT函数及其用法二、MATLAB快速傅里叶变换的应用1.频谱分析2.信号处理3.图像处理三、MATLAB快速傅里叶变换的实例1.计算信号的傅里叶变换2.计算信号的快速傅里叶变换3.绘制信号的频谱图正文:一、MATLAB快速傅里叶变换的基本概念1.傅里叶变换与快速傅里叶变换(FFT)傅里叶变换是一种将时域信号转换为频域信号的数学方法,它有助于分析信号的频率成分。

然而,传统的傅里叶变换计算量较大,对于大规模数据处理效率较低。

为了解决这个问题,提出了快速傅里叶变换(FFT)算法,它是一种高效的计算傅里叶变换的数值方法。

2.MATLAB中的FFT函数及其用法MATLAB提供了丰富的数字信号处理工具箱,其中包括用于计算快速傅里叶变换的FFT函数。

FFT函数有多种用法,下面列举了常见的几种语法:- FFT(x):计算向量x的快速傅里叶变换。

- FFT(x, n):计算长度为n的向量x的快速傅里叶变换。

- FFT(x, n, dim):计算指定维度下的快速傅里叶变换。

- FFT( [], symflag):创建一个空矩阵,用于存储快速傅里叶变换结果。

二、MATLAB快速傅里叶变换的应用1.频谱分析:通过快速傅里叶变换,可以分析信号的频谱成分,帮助人们了解信号的频率特性。

2.信号处理:在信号处理领域,快速傅里叶变换可用于滤波、去噪、提取特征等任务。

3.图像处理:在图像处理领域,快速傅里叶变换可用于图像的频谱分析、边缘检测、图像重建等。

三、MATLAB快速傅里叶变换的实例1.计算信号的傅里叶变换假设有一个时域信号x,如下:```x = [1, 2, 3, 4, 5];```使用MATLAB计算其傅里叶变换:```matlabX = fft(x);```2.计算信号的快速傅里叶变换对于同样的信号x,使用MATLAB计算其快速傅里叶变换:```matlabX = fft(x, 5);```3.绘制信号的频谱图利用MATLAB绘制信号x的频谱图:```matlabfigure;plot(n, abs(X));xlabel("Frequency");ylabel("Magnitude");title("Frequency Domain Representation of x");```通过以上示例,我们可以看到MATLAB中快速傅里叶变换在信号处理、图像处理等领域的应用。

MATLAB中FFT的使用方法

MATLAB中FFT的使用方法

MATLAB中FFT的使用方法一.调用方法X=FFT(x);X=FFT(x,N);x=IFFT(X);x=IFFT(X,N)用MATLAB进行谱分析时注意:(1)函数FFT返回值的数据结构具有对称性。

例:N=8;n=0:N-1;xn=[4 3 2 6 7 8 9 0];Xk=fft(xn)→Xk =39.0000 -10.7782 + 6.2929i 0 - 5.0000i 4.7782 - 7.7071i 5.0000 4.7782 +7.7071i 0 + 5.0000i -10.7782 - 6.2929iXk与xn的维数相同,共有8个元素。

Xk的第一个数对应于直流分量,即频率值为0。

(2)做FFT分析时,幅值大小与FFT选择的点数有关,但不影响分析结果。

在IFFT时已经做了处理。

要得到真实的振幅值的大小,只要将得到的变换后结果乘以2除以N即可。

二.FFT应用举例例1:x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t)。

采样频率fs=100Hz,分别绘制N=128、1024点幅频图。

clf;fs=100;N=128; %采样频率和数据点数n=0:N-1;t=n/fs; %时间序列x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求得Fourier变换后的振幅f=n*fs/N; %频率序列subplot(2,2,1),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;subplot(2,2,2),plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=128');grid on;%对信号采样数据为1024点的处理fs=100;N=1024;n=0:N-1;t=n/fs;x=0.5*sin(2*pi*15*t)+2*sin(2*pi*40*t); %信号y=fft(x,N); %对信号进行快速Fourier变换mag=abs(y); %求取Fourier变换的振幅f=n*fs/N;subplot(2,2,3),plot(f,mag); %绘出随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;subplot(2,2,4)plot(f(1:N/2),mag(1:N/2)); %绘出Nyquist频率之前随频率变化的振幅xlabel('频率/Hz');ylabel('振幅');title('N=1024');grid on;运行结果:fs=100Hz,Nyquist频率为fs/2=50Hz。

C语言、Matlab实现FFT几种编程实例..

C语言、Matlab实现FFT几种编程实例..
struct compx s[FFT_N];//FFT输入和输出:从S[1]开始存放,根据大小自己定义
/*******************************************************************
函数原型:struct compx EE(struct compx b1,struct compx b2)
函数功能:对两个复数进行乘法运算
输入参数:两个以联合体定义的复数a,b
输出参数:a和b的乘积,以联合体的形式输出
*******************************************************************/
struct compx EE(struct compx a,struct compx b)
while(1);
}
%////二、
%/////////////////////////////////////////////////////////////////////////////////////////////////////////////
%///////////////////////////////////////////////////////////////////////////////////////////////////////////
{
double real;
double img;
}complex;
void fft(); /*快速傅里叶变换*/
void ifft(); /*快速傅里叶逆变换*/
void initW();
void change();
void add(complex ,complex ,complex *); /*复数加法*/

C语言、Matlab实现FFT几种编程实例

C语言、Matlab实现FFT几种编程实例

C语言、MATLAB实现FFT几种方法总结前人经验,仅供参考///一、///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////c语言程序/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////#include <iom128.h>#include <intrinsics.h>#include<math.h>#define PI 3.1415926535897932384626433832795028841971 //定义圆周率值#define FFT_N 128 //定义福利叶变换的点数struct compx {float real,imag;}; //定义一个复数结构struct compx s[FFT_N]; //FFT输入和输出:从S[1]开始存放,根据大小自己定义/******************************************************************* 函数原型:struct compx EE(struct compx b1,struct compx b2)函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b输出参数:a和b的乘积,以联合体的形式输出*******************************************************************/ struct compx EE(struct compx a,struct compx b){struct compx c;c.real=a.real*b.real-a.imag*b.imag;c.imag=a.real*b.imag+a.imag*b.real;return(c);}/*****************************************************************函数原型:void FFT(struct compx *xin,int N)函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数:*xin复数结构体组的首地址指针,struct型*****************************************************************/ void FFT(struct compx *xin){int f,m,nv2,nm1,i,k,l,j=0;struct compx u,w,t;nv2=FFT_N/2; //变址运算,即把自然顺序变成倒位序,采用雷德算法 nm1=FFT_N-1;for(i=0;i<nm1;i++){if(i<j) //如果i<j,即进行变址{t=xin[j];xin[j]=xin[i];xin[i]=t;}k=nv2; //求j的下一个倒位序while(k<=j) //如果k<=j,表示j的最高位为1{j=j-k; //把最高位变成0k=k/2; //k/2,比较次高位,依次类推,逐个比较,直到某个位为0}j=j+k; //把0改为1}{int le,lei,ip; //FFT运算核,使用蝶形运算完成FFT 运算f=FFT_N;for(l=1;(f=f/2)!=1;l++) //计算l的值,即计算蝶形级数;for(m=1;m<=l;m++) // 控制蝶形结级数{ //m表示第m级蝶形,l为蝶形级总数l=log(2)Nle=2<<(m-1); //le蝶形结距离,即第m级蝶形的蝶形结相距le 点lei=le/2; //同一蝶形结中参加运算的两点的距离u.real=1.0; //u为蝶形结运算系数,初始值为1u.imag=0.0;w.real=cos(PI/lei); //w为系数商,即当前系数与前一个系数的商w.imag=-sin(PI/lei);for(j=0;j<=lei-1;j++) //控制计算不同种蝶形结,即计算系数不同的蝶形结{for(i=j;i<=FFT_N-1;i=i+le) //控制同一蝶形结运算,即计算系数相同蝶形结{ip=i+lei; //i,ip分别表示参加蝶形运算的两个节点 t=EE(xin[ip],u); //蝶形运算,详见公式xin[ip].real=xin[i].real-t.real;xin[ip].imag=xin[i].imag-t.imag;xin[i].real=xin[i].real+t.real;xin[i].imag=xin[i].imag+t.imag;}u=EE(u,w); //改变系数,进行下一个蝶形运算 }}}}/************************************************************函数原型:void main()函数功能:测试FFT变换,演示函数使用方法输入参数:无输出参数:无************************************************************/void main(){int i;for(i=0;i<FFT_N;i++) //给结构体赋值{s[i].real=sin(2*3.141592653589793*i/FFT_N); //实部为正弦波FFT_N 点采样,赋值为1s[i].imag=0; //虚部为0}FFT(s); //进行快速福利叶变换for(i=0;i<FFT_N;i++) //求变换后结果的模值,存入复数的实部部分s[i].real=sqrt(s[i].real*s[i].real+s[i].imag*s[i].imag);while(1);}%////二、%//////////////////////////////////////////////////////////////////// /////////////////////////////////////////%//////////////////////////////////////////////////////////////////// ///////////////////////////////////////%////////////////////////////////MATLAB仿真信号源的源程序:: Clear;Clc;t=O:O.01:3;yl=100*sin(pi/3*t);for t=-O:O.01:10;y2(1,n)=-61.1614*exp(-0.9*t);n=n+;endmin(y2)y=[yl,y2];figure(1);plot(y); %funboxing(O.001+1/3)%////////////////////////%/////////快速傅里叶变换matlab程序:%////////////////////////clc;clear;clf;N=input('Node number')T=input('cai yang jian ge')f=input('frenquency')choise=input('add zero or not? 1/0 ')n=0:T:(N-1)*T; %采样点k=0:N-1;x=sin(2*pi*f*n);if choise==1e=input('Input the number of zeros!')x=[x zeros(1,e)]N=N+e;elseend %加零k=0:N-1; %给k重新赋值,因为有可能出现加零状况bianzhi=bi2de(fliplr(de2bi(k,length(de2bi(N-1)))))+1;%利用库函数进行变址运算for l=1:NX(l)=x(bianzhi(l));%将采样后的值按照变址运算后的顺序放入X矩阵中endfor m=1:log2(N)d2=d1; %做蝶形运算的两个数之间的距离d1=d1*2; %同一级之下蝶形结之间的距离W=1; %蝶形运算系数的初始值dw=exp(-j*pi/d2); %蝶形运算系数的增加量for t=1:d2 %for i=t:d1:Ni1=i+d2;if(i1>N)break; %判断是否超出范围elsep=X(i1)*W;X(i1)=X(i)-p;X(i)=X(i)+p; %蝶形运算endendW=W*dw; %蝶形运算系数的变化endendsubplot(2,2,1);t=0:0.0000001:N*T;plot(t,sin(2*pi*f*t)); %画原曲线subplot(2,2,2);stem(k,x); %画采样后的离散信号subplot(2,2,3);stem(k,abs(X)/max(abs(X))); %画自己的fft的运算结果subplot(2,2,4);stem(k,abs(fft(x))/max(abs(fft(x)))); %调用系统的函数绘制结果,与自己的结果进行比较//////三、///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////FFT的C语言算法实现////////////程序如下:/************FFT***********/#include <stdio.h>#include <math.h>#include <stdlib.h>#define N 1000typedef struct{double real;double img;}complex;void fft(); /*快速傅里叶变换*/void ifft(); /*快速傅里叶逆变换*/void initW();void change();void add(complex ,complex ,complex *); /*复数加法*/ void mul(complex ,complex ,complex *); /*复数乘法*/ void sub(complex ,complex ,complex *); /*复数减法*/ void divi(complex ,complex ,complex *);/*复数除法*/ void output(); /*输出结果*/complex x[N], *W;/*输出序列的值*/int size_x=0;/*输入序列的长度,只限2的N次方*/double PI;int main(){int i,method;system("cls");PI=atan(1)*4;printf("Please input the size of x:\n");/*输入序列的长度*/scanf("%d",&size_x);printf("Please input the data in x[N]:(such as:5 6)\n"); /*输入序列对应的值*/for(i=0;i<size_x;i++)scanf("%lf %lf",&x[i].real,&x[i].img);initW();/*选择FFT或逆FFT运算*/printf("Use FFT(0) or IFFT(1)?\n");scanf("%d",&method);if(method==0)fft();elseifft();output();return 0;}/*进行基-2 FFT运算*/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=1<<i;for(j=0;j<size_x;j+= 2*l ){for(k=0;k<l;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 ifft(){int i=0,j=0,k=0,l=size_x;complex up,down;for(i=0;i< (int)( log(size_x)/log(2) );i++) /*蝶形运算*/ {l/=2;for(j=0;j<size_x;j+= 2*l ){for(k=0;k<l;k++){add(x[j+k],x[j+k+l],&up);up.real/=2;up.img/=2;sub(x[j+k],x[j+k+l],&down);down.real/=2;down.img/=2;divi(down,W[size_x*k/2/l],&down);x[j+k]=up;x[j+k+l]=down;}}}change();}void initW(){int i;W=(complex *)malloc(sizeof(complex) * size_x);for(i=0;i<size_x;i++){W[i].real=cos(2*PI/size_x*i);W[i].img=-1*sin(2*PI/size_x*i);}void change(){complex temp;unsigned short i=0,j=0,k=0;double t;for(i=0;i<size_x;i++){k=i;j=0;t=(log(size_x)/log(2));while( (t--)>0 ){j=j<<1;j|=(k & 1);k=k>>1;}if(j>i){temp=x[i];x[i]=x[j];x[j]=temp;}}}void output() /*输出结果*/{int i;printf("The result are as follows\n"); for(i=0;i<size_x;i++){printf("%.4f",x[i].real);if(x[i].img>=0.0001)printf("+%.4fj\n",x[i].img);else if(fabs(x[i].img)<0.0001)printf("\n");elseprintf("%.4fj\n",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;}void divi(complex a,complex b,complex *c){c->real=( a.real*b.real+a.img*b.img )/(b.real*b.real+b.img*b.img);c->img=( a.img*b.real-a.real*b.img)/(b.real*b.real+b.img*b.img); }/////四、///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////%//////选带傅里叶变换(zoom-fft) MATLAB%移频(将选带的中心频率移动到零频)%数字低通滤波器(防止频率混叠)%重新采样(将采样的数据再次间隔采样,间隔的数据取决于分析的带宽,就是放大倍数)%复FFT (由于经过了移频,所以数据不是实数了)%频率调整(将负半轴的频率成分移到正半轴)function [f, y] = zfft(x, fi, fa, fs)% x为采集的数据% fi为分析的起始频率% fa为分析的截止频率% fs为采集数据的采样频率% f为输出的频率序列% y为输出的幅值序列(实数)f0 = (fi + fa) / 2; %中心频率N = length(x); %数据长度r = 0:N-1;b = 2*pi*f0.*r ./ fs;x1 = x .* exp(-1j .* b); %移频bw = fa - fi;B = fir1(32, bw / fs); %滤波截止频率为0.5bwx2 = filter(B, 1, x1);c = x2(1:floor(fs/bw):N); %重新采样N1 = length(c);f = linspace(fi, fa, N1);y = abs(fft(c)) ./ N1 * 2;y = circshift(y, [0, floor(N1/2)]); %将负半轴的幅值移过来end///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////%上边四程序测试应用实例:fs = 2048;T = 100;t = 0:1/fs:T;x = 30 * cos(2*pi*110.*t) + 30 * cos(2*pi*111.45.*t) + 25*c os(2*pi*112.3*t) + 48*cos(2*pi*113.8.*t)+50*cos(2*pi*114.5.*t); [f, y] = zfft(x, 109, 115, fs);plot(f, y);///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////图片效果:。

FFT的C语言编程

FFT的C语言编程

i-2.878680 i-5.999998 i0.878680 i9.000000 i-7.121320
7.重复上述步骤 5-6,完成上机内容 3;
8.撰写上机实验报告。
四、参考程序
#include <stdio.h>
#include <math.h>
#define re 0
/* re=0,用 re 表示实部 */
temp[2]: 蝶形计算中的临时变量,temp[re]、temp[im]分别代表其实部和虚部;
*/
float arg,wreal,wimag; /* arg 存储旋转因子指数 p(数值上相差-2π/N)。wreal 存储 cos(arg),wimag 存储
-sin(arg) */
float tem,tr,ti;
for(k=j; k<N; k+=2*B) /*第 L 级具有相同旋转因子蝶形计算,每个蝶形相距 2L=2B 个点*/
{
/* 编写蝶蝶形计算的输入节点距离为 B */
/*
蝶形运算

x[i] = x[i + B]
x[i] + WNP x[i + = x[i] − WNP x[i
*/
}
}
/* 计算旋转因子说明 P = j * 2^ (M − L) 、 B = 2L−1 、 N = 2M
有 WNP
=
e−i
2π N
P
= e−i( jπ / B)
= e−iθ
= cosθ
− i sinθ
其中θ = jπ / B
下一个旋转因子旋转角度为 arg
e−iθ * e−i(arg) = (cosθ *cos(arg) − sinθ *sin(arg)) − i(cosθ *sin(arg) + sinθ *cos(arg))

fft c语言程序

fft c语言程序

fft c语言程序以下是一个简单的C语言程序,用于计算一维Fast Fourier Transform(FFT):```#include <stdio.h>#include <complex.h>#include <math.h>// 计算FFTvoid fft(complex double x[], int n) {if (n <= 1)return;complex double *even = malloc(n / 2 * sizeof(complex double)); complex double *odd = malloc(n / 2 * sizeof(complex double)); for (int i = 0; i < n / 2; i++) {even[i] = x[2 * i];odd[i] = x[2 * i + 1];}fft(even, n / 2);fft(odd, n / 2);for (int k = 0; k < n / 2; k++) {double complex t = cexp(-I * 2 * M_PI * k / n) * odd[k];x[k] = even[k] + t;x[k + n / 2] = even[k] - t;}free(even);free(odd);}int main() {int n;printf("输入信号长度n:");scanf("%d", &n);complex double *x = malloc(n * sizeof(complex double));printf("输入信号值:");for (int i = 0; i < n; i++)scanf("%lf", &x[i]);fft(x, n);printf("FFT结果:\n");for (int i = 0; i < n; i++)printf("%.2lf + %.2lfi\n", creal(x[i]), cimag(x[i]));free(x);return 0;}```此程序使用递归方式实现了计算FFT的函数fft(),并在主函数中接收用户输入的信号长度和信号值,调用fft()函数计算FFT,并输出结果。

Matlab编程实现FFT变换及频谱分析的程序代码

Matlab编程实现FFT变换及频谱分析的程序代码

Matlab编程实现FFT变换及频谱分析的程序代码(喜欢进行电磁兼容仿真分析的朋友可以借用)2007-10-08 sysop 点击: 436Matlab编程实现FFT变换及频谱分析的程序代码(喜欢进行电磁兼容仿真分析的朋友可以借用)Matlab编程实现FFT变换及频谱分析的程序代码(喜欢进行电磁兼容仿真分析的朋友可以借用)内容1.用Matlab产生正弦波,矩形波,以及白噪声信号,并显示各自时域波形图2.进行FFT变换,显示各自频谱图,其中采样率,频率、数据长度自选3.做出上述三种信号的均方根图谱,功率图谱,以及对数均方根图谱4.用IFFT傅立叶反变换恢复信号,并显示恢复的正弦信号时域波形图源程序%*************************************************************************%% FFT实践及频谱分析 %%*************************************************************************%%*************************************************************************%%***************1.正弦波****************%fs=100;%设定采样频率N=128;n=0:N-1;t=n/fs;f0=10;%设定正弦信号频率%生成正弦信号x=sin(2*pi*f0*t);figure(1);subplot(231);plot(t,x);%作正弦信号的时域波形xlabel('t');ylabel('y');title('正弦信号y=2*pi*10t时域波形');grid;%进行FFT变换并做频谱图y=fft(x,N);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(1);subplot(232);plot(f,mag);%做频谱图axis([0,100,0,80]);xlabel('频率(Hz)');ylabel('幅值');title('正弦信号y=2*pi*10t幅频谱图N=128'); grid;%求均方根谱sq=abs(y);figure(1);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('正弦信号y=2*pi*10t均方根谱'); grid;%求功率谱power=sq.^2;figure(1);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('正弦信号y=2*pi*10t功率谱');grid;%求对数谱ln=log(sq);figure(1);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('正弦信号y=2*pi*10t对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(1);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的正弦信号波形'); grid;%****************2.矩形波****************% fs=10;%设定采样频率t=-5:0.1:5;x=rectpuls(t,2);x=x(1:99);figure(2);subplot(231);plot(t(1:99),x);%作矩形波的时域波形xlabel('t');ylabel('y');title('矩形波时域波形');grid;%进行FFT变换并做频谱图y=fft(x);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(2);subplot(232);plot(f,mag);%做频谱图xlabel('频率(Hz)');ylabel('幅值');title('矩形波幅频谱图');grid;%求均方根谱sq=abs(y);figure(2);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('矩形波均方根谱');grid;%求功率谱power=sq.^2;figure(2);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('矩形波功率谱');grid;%求对数谱ln=log(sq);figure(2);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('矩形波对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(2);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的矩形波波形');grid;%****************3.白噪声****************%fs=10;%设定采样频率t=-5:0.1:5;x=zeros(1,100);x(50)=100000;figure(3);subplot(231);plot(t(1:100),x);%作白噪声的时域波形xlabel('t');ylabel('y');title('白噪声时域波形');grid;%进行FFT变换并做频谱图y=fft(x);%进行fft变换mag=abs(y);%求幅值f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换figure(3);subplot(232);plot(f,mag);%做频谱图xlabel('频率(Hz)');ylabel('幅值');title('白噪声幅频谱图');grid;%求均方根谱sq=abs(y);figure(3);subplot(233);plot(f,sq);xlabel('频率(Hz)');ylabel('均方根谱');title('白噪声均方根谱');grid;%求功率谱power=sq.^2;figure(3);subplot(234);plot(f,power);xlabel('频率(Hz)');ylabel('功率谱');title('白噪声功率谱');grid;%求对数谱ln=log(sq);figure(3);subplot(235);plot(f,ln);xlabel('频率(Hz)');ylabel('对数谱');title('白噪声对数谱');grid;%用IFFT恢复原始信号xifft=ifft(y);magx=real(xifft);ti=[0:length(xifft)-1]/fs;figure(3);subplot(236);plot(ti,magx);xlabel('t');ylabel('y');title('通过IFFT转换的白噪声波形');grid;本文责任编辑: sysop相关文章? 请教:目前可有哪些用于EMC仿真的软件 - 08-18 10:01 am - 点击: 2718 发表评论查看评论加入收藏 Email给朋友打印本文如果你想对该文章评分, 请先登陆, 如果你仍未注册,请点击注册链接注册成为本站会员. 平均得分 0, 共 0 人评分1 2 3 4 5 6 7 8 9 10。

matlab编程实现傅里叶变换

matlab编程实现傅里叶变换

傅里叶变换是信号处理和图像处理中的重要数学工具,可以将一个信号或图像从时域转换到频域。

MATLAB作为一款强大的数学软件,可以方便地实现傅里叶变换并进行相应的分析和处理。

本文将介绍如何使用MATLAB编程实现傅里叶变换,并探讨其在信号处理和图像处理中的应用。

一、MATLAB中的傅里叶变换函数在MATLAB中,可以使用fft函数来进行一维离散傅里叶变换(DFT)的计算,使用fft2函数进行二维离散傅里叶变换(DFT)的计算。

这两个函数的基本语法如下:1. 一维离散傅里叶变换Y = fft(X)其中,X是输入的一维信号(向量),Y是输出的一维频谱(向量)。

2. 二维离散傅里叶变换Y = fft2(X)其中,X是输入的二维图像(矩阵),Y是输出的二维频谱(矩阵)。

除了fft和fft2函数外,MATLAB还提供了ifft和ifft2函数用于进行离散傅里叶逆变换。

通过这些函数,我们可以方便地实现傅里叶变换和逆变换的计算。

二、MATLAB中的傅里叶变换实例为了更好地理解MATLAB中的傅里叶变换实现,我们可以通过一个具体的实例来进行演示。

假设我们有一个包含两个正弦波的信号,我们首先可以使用MATLAB生成这个信号,并对其进行傅里叶变换。

生成信号fs = 1000; 采样频率为1000Hzt = 0:1/fs:1-1/fs; 时间范围为1秒f1 = 50; 第一个正弦波的频率为50Hzf2 = 120; 第二个正弦波的频率为120Hzx = 0.7*sin(2*pi*f1*t) + sin(2*pi*f2*t); 生成包含两个正弦波的信号进行傅里叶变换N = length(x); 信号的长度X = fft(x)/N; 进行离散傅里叶变换,并进行归一化处理f = (0:N-1)*(fs/N); 计算频率轴figure;subplot(2,1,1);plot(f,abs(X)); 绘制频谱幅度title('单边频谱');xlabel('频率/Hz');ylabel('幅度');subplot(2,1,2);plot(f,angle(X)); 绘制频谱相位title('频谱相位');xlabel('频率/Hz');ylabel('相位');通过上面的实例,我们可以看到,MATLAB可以很方便地实现最常见的傅里叶变换,并且提供了丰富的绘图功能来呈现变换结果。

傅里叶变换的应用,matlab程序,C语言程序文件

傅里叶变换的应用,matlab程序,C语言程序文件

1 利用FFT 计算连续时间信号的傅里叶变换设()x t 是连续时间信号,并假设0t <时()0x t =,则其傅里叶变换由下式给出()()i t X x t e dt ωω∞-=⎰令Γ是一个固定的正实数,N 是一个固定的正整数。

当,0,1,2,,1k k N ω=Γ=-L 时,利用FFT 算法可计算()X ω。

已知一个固定的时间间隔T ,选择T 足够小,使得每一个T 秒的间隔(1)nT t n T ≤<+,()x t 的变化很小,则式中积分可近似为(1)0()()()n Tiwt nTn X e dt x nT ω∞+-==∑⎰(1)01[]()i t t n Tt nT n e x nT i ωω∞-=+==-=∑ 01()i Ti nTn e ex nT i ωωω-∞-=-=∑ (27)假设N 足够大,对于所有n N ≥的整数,幅值()x nT 很小,则式(27)变为101()()i TN i nTn e X ex nT i ωωωω---=-=∑ (28)当2/k NT ωπ=时,式(28)两边的值为2/2/12/0211()()[]2/2/i k Ni k NN i nk Nn k e e X ex nT X k NT i k NTi k NTππππππ----=--==∑ (29)其中[]X k 代表抽样信号[]()x n x nT =的N 点DFT 。

最后令2/NT πΓ=,则上式变为2/1()[]0,1,2,,12/i k Ne X k X k k N i k NTππ--Γ==-L (30) 首先用FFT 算法求出[]X k ,然后可用上式求出0,1,2,,1k N =-L 时的()X k Γ。

应该强调的是,式(28)只是一个近似表示,计算得到的()X ω只是一个近似值。

通过取更小的抽样间隔T ,或者增加点数N ,可以得到更精确的值。

如果B ω>时,幅度谱()X ω很小,对应于奈奎斯特抽样频率2s B ω=,抽样间隔T 选择/B π比较合适。

c语言实现matlab的freqz函数

c语言实现matlab的freqz函数

Matlab的freqz函数用于计算数字滤波器的频率响应。

在C语言中,我们可以通过使用FFTW库(快速傅里叶变换库)来实现类似的功能。

以下是一个简单的示例:c复制代码#include<stdio.h>#include<math.h>#include<complex.h>#include<fftw3.h>int main() {// 定义滤波器系数double a[] = {1.0, -0.5, 0.25};int n = sizeof(a) / sizeof(double);// 创建FFTW复数输入数组fftw_complex *in;in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);for (int i = 0; i < n; ++i) {in[i][0] = a[i];in[i][1] = 0;}// 创建FFTW复数输出数组fftw_complex *out;out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n);// 创建FFTW计划并执行傅里叶变换fftw_plan p;p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE);fftw_execute(p);// 输出频率响应(幅度)for (int i = 0; i < n; ++i) {printf("Frequency response at %d: %f\n", i, creal(out[i]) * creal(out[i]) +cimag(out[i]) * cimag(out[i]));}// 清理并释放内存fftw_destroy_plan(p);fftw_free(in);fftw_free(out);return0;}注意:这个示例使用了FFTW库,你需要先安装它才能编译和运行这个程序。

fft c语言代码

fft c语言代码

以下是使用C语言实现快速傅里叶变换(FFT)的示例代码:c复制代码#include<stdio.h>#include<math.h>#define PI 3.14void fft(double* x, double* out, int n) {if (n == 1) {out[0] = x[0];return;}double w_n = 2 * PI / n;double w_m = exp(-1j * w_n / 2);double w = 1.0;for (int k = 0; k < n / 2; k++) {double t = w * x[2 * k];out[k] = t + x[2 * k + 1];out[k + n / 2] = t - x[2 * k + 1];w *= w_m;}fft(x, out, n / 2);fft(&x[n / 2], &out[n / 2], n / 2);}int main() {int n = 8; // 输入序列长度为8double x[] = {1, 1, 1, 1, 0, 0, 0, 0}; // 输入序列double out[n]; // 输出序列fft(x, out, n); // 进行FFT变换for (int i = 0; i < n; i++) {printf("%f ", out[i]); // 输出FFT变换结果}printf("\n");return0;}以上代码中,fft函数实现了快速傅里叶变换,main函数用于测试。

在fft函数中,首先判断序列长度是否为1,如果是则直接返回序列本身;否则,将序列分为奇数位和偶数位两个子序列,分别进行FFT变换,然后将两个子序列的FFT结果进行合并。

在循环中,使用w表示旋转因子,w_n表示旋转角度,w_m表示旋转因子的乘积因子。

C语言编写FFT程序

C语言编写FFT程序

DSP 课程作业用C 语言编写FFT 程序1,快速傅里叶变换FFT 简介快速傅氏变换(FFT ),是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。

它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。

我们假设 x(n)为N 项的复数序列,由DFT 变换,任一X (m )的计算都需要N 次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N 项复数序列的X (m ),即N 点DFT 变换大约就需要N^2次运算。

当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT 中,利用WN 的周期性和对称性,把一个N 项序列(设N=2k,k 为正整数),分为两个N/2项的子序列,每个N/2点DFT 变换需要(N/2)2次运算,再用N 次运算把两个N/2点的DFT 变换组合成一个N 点的DFT 变换。

这样变换以后,总的运算次数就变成N+2(N/2)2=N+N2/2。

继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。

而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT 运算单元,那么N 点的DFT 变换就只需要Nlog2N 次的运算,N 在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT 的优越性。

2,FFT 算法的基本原理FFT 算法的基本思想:利用DFT 系数的特性,合并DFT 运算中的某些项,吧长序列的DFT —>短序列的DFT ,从而减少其运算量。

FFT 算法分类:时间抽选法DIT: Decimation-In-Time ;频率抽选法DIF: Decimation-In-Frequency按时间抽选的基-2FFT 算法1、算法原理设序列点数 N = 2L ,L 为整数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言、MATLAB实现FFT几种方法总结前人经验,仅供参考///一、/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////c语言程序////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <iom128.h>#include <intrinsics.h>#include<math.h>#define PI 3.1415926535897932384626433832795028841971 //定义圆周率值#define FFT_N 128 //定义福利叶变换的点数struct compx {float real,imag;}; //定义一个复数结构struct compx s[FFT_N]; //FFT输入和输出:从S[1]开始存放,根据大小自己定义/******************************************************************* 函数原型:struct compx EE(struct compx b1,struct compx b2)函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b输出参数:a和b的乘积,以联合体的形式输出*******************************************************************/ struct compx EE(struct compx a,struct compx b){struct compx c;c.real=a.real*b.real-a.imag*b.imag;c.imag=a.real*b.imag+a.imag*b.real;return(c);}/*****************************************************************函数原型:void FFT(struct compx *xin,int N)函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数:*xin复数结构体组的首地址指针,struct型*****************************************************************/ void FFT(struct compx *xin){int f,m,nv2,nm1,i,k,l,j=0;struct compx u,w,t;nv2=FFT_N/2; //变址运算,即把自然顺序变成倒位序,采用雷德算法nm1=FFT_N-1;for(i=0;i<nm1;i++){if(i<j) //如果i<j,即进行变址{t=xin[j];xin[j]=xin[i];xin[i]=t;}k=nv2; //求j的下一个倒位序while(k<=j) //如果k<=j,表示j的最高位为1{j=j-k; //把最高位变成0k=k/2; //k/2,比较次高位,依次类推,逐个比较,直到某个位为0}j=j+k; //把0改为1}{int le,lei,ip; //FFT运算核,使用蝶形运算完成FFT运算f=FFT_N;for(l=1;(f=f/2)!=1;l++) //计算l的值,即计算蝶形级数;for(m=1;m<=l;m++) // 控制蝶形结级数{ //m表示第m级蝶形,l为蝶形级总数l=log(2)N le=2<<(m-1); //le蝶形结距离,即第m级蝶形的蝶形结相距le点lei=le/2; //同一蝶形结中参加运算的两点的距离u.real=1.0; //u为蝶形结运算系数,初始值为1u.imag=0.0;w.real=cos(PI/lei); //w为系数商,即当前系数与前一个系数的商w.imag=-sin(PI/lei);for(j=0;j<=lei-1;j++) //控制计算不同种蝶形结,即计算系数不同的蝶形结{for(i=j;i<=FFT_N-1;i=i+le) //控制同一蝶形结运算,即计算系数相同蝶形结{ip=i+lei; //i,ip分别表示参加蝶形运算的两个节点t=EE(xin[ip],u); //蝶形运算,详见公式xin[ip].real=xin[i].real-t.real;xin[ip].imag=xin[i].imag-t.imag;xin[i].real=xin[i].real+t.real;xin[i].imag=xin[i].imag+t.imag;}u=EE(u,w); //改变系数,进行下一个蝶形运算}}}}/************************************************************函数原型:void main()函数功能:测试FFT变换,演示函数使用方法输入参数:无输出参数:无************************************************************/void main(){int i;for(i=0;i<FFT_N;i++) //给结构体赋值{s[i].real=sin(2*3.141592653589793*i/FFT_N); //实部为正弦波FFT_N点采样,赋值为1s[i].imag=0; //虚部为0}FFT(s); //进行快速福利叶变换for(i=0;i<FFT_N;i++) //求变换后结果的模值,存入复数的实部部分s[i].real=sqrt(s[i].real*s[i].real+s[i].imag*s[i].imag);while(1);}%////二、%/////////////////////////////////////////////////////////////////////////////////////////////////////////////%///////////////////////////////////////////////////////////////////////////////////////////////////////////%////////////////////////////////MATLAB仿真信号源的源程序::Clear;Clc;t=O:O.01:3;yl=100*sin(pi/3*t);n=l;for t=-O:O.01:10;y2(1,n)=-61.1614*exp(-0.9*t);n=n+;endmin(y2)y=[yl,y2];figure(1);plot(y); %funboxing(O.001+1/3)%////////////////////////%/////////快速傅里叶变换matlab程序:%////////////////////////clc;clear;clf;N=input('Node number')T=input('cai yang jian ge')f=input('frenquency')choise=input('add zero or not? 1/0 ')n=0:T:(N-1)*T; %采样点k=0:N-1;x=sin(2*pi*f*n);if choise==1e=input('Input the number of zeros!')x=[x zeros(1,e)]N=N+e;elseend %加零k=0:N-1; %给k重新赋值,因为有可能出现加零状况bianzhi=bi2de(fliplr(de2bi(k,length(de2bi(N-1)))))+1;%利用库函数进行变址运算for l=1:NX(l)=x(bianzhi(l));%将采样后的值按照变址运算后的顺序放入X矩阵中endd1=1;for m=1:log2(N)d2=d1; %做蝶形运算的两个数之间的距离d1=d1*2; %同一级之下蝶形结之间的距离W=1; %蝶形运算系数的初始值dw=exp(-j*pi/d2); %蝶形运算系数的增加量for t=1:d2 %for i=t:d1:Ni1=i+d2;if(i1>N)break; %判断是否超出范围elsep=X(i1)*W;X(i1)=X(i)-p;X(i)=X(i)+p; %蝶形运算endendW=W*dw; %蝶形运算系数的变化endendsubplot(2,2,1);t=0:0.0000001:N*T;plot(t,sin(2*pi*f*t)); %画原曲线subplot(2,2,2);stem(k,x); %画采样后的离散信号subplot(2,2,3);stem(k,abs(X)/max(abs(X))); %画自己的fft的运算结果subplot(2,2,4);stem(k,abs(fft(x))/max(abs(fft(x)))); %调用系统的函数绘制结果,与自己的结果进行比较//////三、/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////FFT的C语言算法实现////////////程序如下:/************FFT***********/#include <stdio.h>#include <math.h>#include <stdlib.h>#define N 1000typedef struct{double real;double img;}complex;void fft(); /*快速傅里叶变换*/void ifft(); /*快速傅里叶逆变换*/void initW();void change();void add(complex ,complex ,complex *); /*复数加法*/void mul(complex ,complex ,complex *); /*复数乘法*/void sub(complex ,complex ,complex *); /*复数减法*/void divi(complex ,complex ,complex *);/*复数除法*/ void output(); /*输出结果*/complex x[N], *W;/*输出序列的值*/int size_x=0;/*输入序列的长度,只限2的N次方*/double PI;int main(){int i,method;system("cls");PI=atan(1)*4;printf("Please input the size of x:\n");/*输入序列的长度*/scanf("%d",&size_x);printf("Please input the data in x[N]:(such as:5 6)\n"); /*输入序列对应的值*/for(i=0;i<size_x;i++)scanf("%lf %lf",&x[i].real,&x[i].img);initW();/*选择FFT或逆FFT运算*/printf("Use FFT(0) or IFFT(1)?\n");scanf("%d",&method);if(method==0)fft();elseifft();output();return 0;}/*进行基-2 FFT运算*/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=1<<i;for(j=0;j<size_x;j+= 2*l ){for(k=0;k<l;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 ifft(){int i=0,j=0,k=0,l=size_x;complex up,down;for(i=0;i< (int)( log(size_x)/log(2) );i++) /*蝶形运算*/ {l/=2;for(j=0;j<size_x;j+= 2*l ){for(k=0;k<l;k++){add(x[j+k],x[j+k+l],&up);up.real/=2;up.img/=2;sub(x[j+k],x[j+k+l],&down);down.real/=2;down.img/=2;divi(down,W[size_x*k/2/l],&down);x[j+k]=up;x[j+k+l]=down;}}}change();}void initW(){int i;W=(complex *)malloc(sizeof(complex) * size_x); for(i=0;i<size_x;i++){W[i].real=cos(2*PI/size_x*i);W[i].img=-1*sin(2*PI/size_x*i);}}void change(){complex temp;unsigned short i=0,j=0,k=0;double t;for(i=0;i<size_x;i++){k=i;j=0;t=(log(size_x)/log(2));while( (t--)>0 ){j=j<<1;j|=(k & 1);k=k>>1;}if(j>i){temp=x[i];x[i]=x[j];x[j]=temp;}}}void output() /*输出结果*/{int i;printf("The result are as follows\n");for(i=0;i<size_x;i++){printf("%.4f",x[i].real);if(x[i].img>=0.0001)printf("+%.4fj\n",x[i].img);else if(fabs(x[i].img)<0.0001)printf("\n");elseprintf("%.4fj\n",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;}void divi(complex a,complex b,complex *c){c->real=( a.real*b.real+a.img*b.img )/(b.real*b.real+b.img*b.img);c->img=( a.img*b.real-a.real*b.img)/(b.real*b.real+b.img*b.img);}/////四、/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// %//////选带傅里叶变换(zoom-fft) MATLAB%移频(将选带的中心频率移动到零频)%数字低通滤波器(防止频率混叠)%重新采样(将采样的数据再次间隔采样,间隔的数据取决于分析的带宽,就是放大倍数)%复FFT (由于经过了移频,所以数据不是实数了)%频率调整(将负半轴的频率成分移到正半轴)function [f, y] = zfft(x, fi, fa, fs)% x为采集的数据% fi为分析的起始频率% fa为分析的截止频率% fs为采集数据的采样频率% f为输出的频率序列% y为输出的幅值序列(实数)f0 = (fi + fa) / 2; %中心频率N = length(x); %数据长度r = 0:N-1;b = 2*pi*f0.*r ./ fs;x1 = x .* exp(-1j .* b); %移频bw = fa - fi;B = fir1(32, bw / fs); %滤波截止频率为0.5bwx2 = filter(B, 1, x1);c = x2(1:floor(fs/bw):N); %重新采样N1 = length(c);f = linspace(fi, fa, N1);y = abs(fft(c)) ./ N1 * 2;y = circshift(y, [0, floor(N1/2)]); %将负半轴的幅值移过来end////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////%上边四程序测试应用实例:fs = 2048;T = 100;t = 0:1/fs:T;x = 30 * cos(2*pi*110.*t) + 30 * cos(2*pi*111.45.*t) + 25*cos(2*pi*112.3*t) + 48*c os(2*pi*113.8.*t)+50*cos(2*pi*114.5.*t);[f, y] = zfft(x, 109, 115, fs);plot(f, y);/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////图片效果:。

相关文档
最新文档