[原创]zoomfft
%ZoomFFT谱%x-信号序列
%fs-采样频率
%N-做谱点数
%fe-分析中心频率
%D-细化倍数
%L-平均段数
%M-滤波器半阶数
%f-返回频率向量
%xz-返回幅值谱
function =ZoomFFT(x,fs,N,fe,D,L,M)
k=1:M;
w=0.5+0.5*cos(pi*k/M); %Hanning窗
fl=max(fe-fs/(4*D),-fs/2.2);
fh=min(fe+fs/(4*D),fs/2.2);
yf=D*fl; %移频量
df=fs/D/N;
f=fl:df:fl+(N/2-1)*df;
xz=zeros(1,N/2);
wl=2*pi*fl/fs;
wh=2*pi*fh/fs;
hr(1)=(wl-wh)/pi;
hr(2:M+1)=(sin(wl*k)-sin(wh*k))./(pi*k).*w;
hi(1)=0;
hi(2:M+1)=(cos(wl*k)-cos(wh*k))./(pi*k).*w;
k=0:N-1;
w=0.5-0.5*cos(2*pi*k/N);
for i=1:L
for k=1:N
kk=(k-1)*D+M+(i-1)*N;
xrz(k)=x(kk+1)*hr(1)+sum(hr(2:M+1).*(x(kk+2:kk+M+1)+x(kk:-1:kk-M+1)));
xiz(k)=x(kk+1)*hi(1)+sum(hi(2:M+1).*(x(kk+2:kk+M+1)-x(kk:-1:kk-M+1)));
end
xzt=(xrz+j*xiz).*exp(-j*2*pi*(0:N-1)*yf/fs);
xzt=xzt.*w;
xzt=xzt-sum(xzt)/N;
xzt=fft(xzt);
xz=xz+(abs(xzt(1:N/2))/N*2).^2;
end
xz=(xz/L).^0.5;
[ 本帖最后由 MVH 于 2006-10-4 15:52 编辑 ] for i=1:L
for k=1:N
kk=(k-1)*D+M+(i-1)*N;
xrz(k)=x(kk+1)*hr(1)+sum(hr(2:M+1).*(x(kk+2:kk+M+1)+x(kk:-1:kk-M+1)));
xiz(k)=x(kk+1)*hi(1)+sum(hi(2:M+1).*(x(kk+2:kk+M+1)-x(kk:-1:kk-M+1)));
end
xzt=(xrz+j*xiz).*exp(-j*2*pi*(0:N-1)*yf/fs);
xzt=xzt.*w;
xzt=xzt-sum(xzt)/N;
xzt=fft(xzt);
xz=xz+(abs(xzt(1:N/2))/N*2).^2;
end
上面ZoomFFT里面这段代码没看明白, j指的是什么?
[ 本帖最后由 MVH 于 2006-10-4 15:53 编辑 ] 没定义i,j的话,它们都是虚数单位 不好意思,还要问一下,语句 xz=(xz/L).^0.5; 中xz是复数,求它的平方根赋给xz ,这样做的意义是什么? 谢谢,谢谢!
回复:(shanghai)不好意思,还要问一下,语句 xz=(xz/...
xz不是复数,而是功率谱,这里开方是求的幅值谱,如果要求其他的谱,可做相应的改动[ 本帖最后由 MVH 于 2006-10-4 15:53 编辑 ] #define N 2048
#define pi 3.1415926
#define M 10
void CAnalysisDlg::ZoomFFT(double *x, double fs, double fe, int D, int L)
{
double wl,wh,fl,fh,yf,df,c;
int kk;
complex N1,L1,w2,x1,x2,sumxzt;
int i,j;
for(i=0;i<M;i++)
{
w0=0.5+0.5*cos(pi*i/M);
}
fl=(fe-fs/(4*D))>(-fs/2.2) ? (fe-fs/(4*D)):(-fs/2.2);
fh=(fe+fs/(4*D))<(fs/2.2) ? (fe+fs/(4*D)):(fs/2.2);
yf=D*fl;
df=fs/D/N;
for(i=0;i<=(N/2-1);i++)
{
f=fl+i*df;
}
wl=2*pi*fl/fs;
wh=2*pi*fh/fs;
hr=(wl-wh)/pi;
for(i=1;i<=M;i++)
{
hr=(sin(wl*i)-sin(wh*i))/(pi*i)*w0;
}
hi=0;
for(i=1;i<=M;i++)
{
hi=(cos(wl*i)-cos(wh*i))/(pi*i)*w0;
}
for(i=0;i<N;i++)
{
w1=0.5-0.5*cos(2*pi*i/N);
}
for(i=0;i<L;i++)
{
for(j=0;j<N;j++)
{
kk=j*D+M+i*N;
for(int m=1;m<=M;m++)
{
sumhr=sumhr+hr*(x+x);
sumhi=sumhi+hi*(x-x);
}
xrz=x*hr+sumhr;
xiz=x*hi+sumhi;
}
}
N1=complex(N,0);
for(int k=0;k<N;k++)
{
x1=complex(xrz,xiz);
x2=complex(cos(2*pi*k*yf/fs),-sin(2*pi*k*yf/fs));
xzt=x1*x2;
w2=complex(w1,0);
xzt=xzt*w2;
sumxzt=sumxzt+xzt;
xzt=xzt-sumxzt/N1;
}
fft(xzt,11);
for(i=0;i<N/2;i++)
{
xz=(xzt.Real()*xzt.Real()+xzt.Imag()*xzt.Imag())/(1024*1024);
}
for(i=0;i<N/2;i++)
{
xz=sqrt(xz/L);
}
}
该程序是我把上面的Matlab版 ZoomFFT改写成Vc++版,该程序通过编译没有问题,我调用函数ZoomFFT(dc,100000.0,3125.0,8,5),但是其中的xiz,xrz始终为0,所以后面的xz当然也是0了,请问这个函数错误在哪里,请指点指点,谢谢!!!
[ 本帖最后由 MVH 于 2006-10-4 15:54 编辑 ] 下标问题我已经注意到了,Vc++中 Hanning窗的一半,是0到M-1,但还是不行. 请问有没有ZoomFFT算法方面的资料,仔细研究一下,谢谢! 我采用的是丁康教授提出的基于复解析带通滤波器的复调制细化选带频谱分析,你可以参考这两篇论文:
丁康,谢明等. 基于复解析带通滤波器的复调制细化频谱分析方法研究. 振动工程学报. 2001, 14(1):29~35.
谢明,丁康. 基于复解析带通滤波器的复调制细化谱分析的算法研究. 振动工程学报. 2002, 15(4):479~483.
[ 本帖最后由 MVH 于 2006-10-4 15:55 编辑 ] for(i=0;i<M;i++)
{
w0=0.5+0.5*cos(pi*i/M);
}
应该改成
for(i=0;i<M;i++)
{
w0=0.5+0.5*cos(pi*(i+1)/M);
}
[ 本帖最后由 MVH 于 2006-10-4 15:55 编辑 ] 谢谢,我再看看这方面的资料! 请问你的ZoomFFT 中平均段数L是什么意思,丁康教授资料中并没有提到这个参数呀!
回复:(shanghai)请问你的ZoomFFT 中平均段数L是什么...
哦,这个是为了减少实际工程信号中随机信号的影响而取了多段信号,然后在功率谱上做平均[ 本帖最后由 MVH 于 2006-10-4 15:55 编辑 ]
好东西
丁康教授教授的论文我也下了,好好看看,向大家学习。滤波器的半阶数是什么意思啊
滤波器的半阶数是什么意思啊kk=(k-1)*D+M+(i-1)*N;是什么意思?
kk=(k-1)*D+M+(i-1)*N;是什么意思?这个程序运行有问题啊?