当前位置: 代码迷 >> VC >> 关于FFT的有关问题
  详细解决方案

关于FFT的有关问题

热度:1493   发布时间:2013-02-25 00:00:00.0
关于FFT的问题
问题是这样的:考虑一个波形,在一个周期中,等间距的采集点,比如采集256个点..,然后去做FFT,因为FFT要求输入的点列必须是复数点列,所以必须把前面的实数点列变为复数,我采用的办法是:复数的实部就是前面得到的点,虚部统统为0。然后做FFT,结果就出来了,但结果不太对.....可以肯定的是FFT的算法肯定是对的,我用MatLab做,结果是一样的,所以我考虑是不是我把虚部都放零出了错.....请大家帮我看看。

例如:{1,1,1,1,1,1.01,1.01,1.01,1.01,1.01,.......},这个点列的特点是,5个“1”,然后接下去5个“1.01”,然后再5个“1”,这样继续下去,到256个为止...对这个序列,我做FFT后和书上的结果不一样...FFT出的结果也是复数,我考虑这些复数的模,我的结果是:做完变换后,第一项的模是书上算出结果的256倍。后面的项也投不上,我用C和Matlab都算过,就是投不上,不晓得问题出再了哪里,我的考虑就是:虚部都给零,是不是不对....请各位大哥大姐帮帮我

------解决方案--------------------------------------------------------
兄弟,你这是算法问题。可能是你区间点分的不合理,不过没玩过FFT。
也不知道怎么分才可以控制精度。
建议转战算法区
老哥在这里友情UP一下。
------解决方案--------------------------------------------------------
fft只能用复数吗?MATLAB有个指令complex可以将实数变复数,你可以查查用法。傅里叶变换的结果是复数很正常,差256倍可能是书上的公式除以了采样点数,这没什么。另外你说的第一项和后面项指什么我没看懂,matlab里fft的结果对应的是频域上[0,2pi)区间的,fft的结果是以2pi为周期的,且实数变换结果是关于y轴对称的。书上显示的结果可能是-pi到pi区间的。
------解决方案--------------------------------------------------------
同志, 两点, 一点你就通:
1, FFT原序列是实数, 变换后为复数, 凡复数必有实部与虚部, 而从另外一个角度看复数, 则必有幅值与幅角(相位). 所以, 一般FFT后, 我们要研究的是幅度谱,相位谱一般不理会. 所以, 集中火力看幅度谱. 设c=a+bi, 则幅度= (a^2 + b^2)^1/2
2, FFT有一个极其重要的特性: 对称性, 你细心观察一下一个变换后的序列, 是否呈现两边幅度对称, 而相位刚好相反!
例如: 你有一个100个元素的序列a, a[0]是直流分量, 跳出三界外不在五行中, 不看也罢. 看看a[1]和a[100], 看看其规律,再用Matlab来看看.
------解决方案--------------------------------------------------------
隆重推荐离散余弦变换, 因为FFT的复数很烦人, 我们有实数对实数的变换:DCT. 同样能反映频率特性, 同样有能量集中的特性
------解决方案--------------------------------------------------------
我的同事以前常用这个,顶。现在搞研究的人太少了!
------解决方案--------------------------------------------------------
虚部置0没有错。
------解决方案--------------------------------------------------------
下面是我写的fft,你可以用matlab测试一下。我测试过了,应该没有问题。


function F = MyFFT(f, M)
% 实现一维FFT算法,
% F = MyFFT(f, M),其中f是输入数据,M是f中要处理的数据个数,必须是2的整数次幂
% F 是返回的FFT结果

if M == 1
% 递归结束
F(1) = f(1);
return;
end


% 把数据分离成偶数部分和奇数部分
fe = f(1:2:end);
fo = f(2:2:end);


% 对分离出来的偶数部分和奇数部分的数据分别递归实现FFT
Feven = MyFFT(fe, M/2);
Fodd = MyFFT(fo, M/2);


u = 1:M/2; % 前半部分的数据索引
uk =M/2+1:M; % 后半部分的数据索引

% 将偶数部分和奇数部分的计算结果合并到结果的前后两个部分
F(u) = (Feven + Fodd.* exp(-j.*2.*pi.*(u-1)./M));
F(uk) = (Feven - Fodd.* exp(-j.*2.*pi.*(u-1)./M));

return;


------解决方案--------------------------------------------------------
其实不一定要把虚部为0,可以利用共轭对称性,来做,把点分为两部份,一半做实部,一半做虚部,这样可以减少一半的点....不过貌似复杂度不会变就是了.......具体我也忘记了...

不过跟LZ的错误关系不大,只是给个建议.....
  相关解决方案