2013-07-09 51 views
1

我想了解由matplotlib.mlab.psd()函数返回的频率仓。matplotlib返回的PSD频率最大值是否错误?

使用下面的代码我可以检查返回的频率,我不相信他们是正确的。

import matplotlib.mlab as ml 
import numpy as np 
sampf=500. 
nfft=2**4 
testdat=np.random.randn(10000,) 
p2,f2=ml.psd(testdat, nfft,sampf,sides='twosided') 
p1,f1=ml.psd(testdat, nfft,sampf,sides='onesided') 

print testdat.shape 
print "Twosided" 
print "\tbin1  : {:f} ".format(f2[0]) 
print "\tbin2  : {:f} ".format(f2[1]) 
print "\tbinlast : {:f} ".format(f2[-1]) 

print "onesided" 
print "\tbin1  : {:f} ".format(f1[0]) 
print "\tbin2  : {:f} ".format(f1[1]) 
print "\tbinlast : {:f} ".format(f1[-1]) 

print "recreate" 
f3=np.arange(nfft)*(sampf/2.)/nfft 
print "\tbin1  : {:f} ".format(f3[0]) 
print "\tbin2  : {:f} ".format(f3[1]) 
print "\tbinlast : {:f} ".format(f3[-1]) 

其给出这个输出:

Twosided 
    bin1  : -250.000000 
    bin2  : -218.750000 
    binlast : 218.750000 
onesided 
    bin1  : 0.000000 
    bin2  : 31.250000 
    binlast : 250.000000 
recreate 
    bin1  : 0.000000 
    bin2  : 15.625000 
    binlast : 234.375000 

我是正确的思想,对于双面情况下,最大频率(binlast)应该是采样频率的一半?

正在关注this SO post我认为它的范围应该是sampf/2。

回答

2

所有的单方面都没有回报消极的一面。因为你正在交出一个真实的信号f_hat(w) = conj(f_hat(-w))(即负Ω的傅立叶分量是ω分量的复共轭),因此它们将具有相同的幅度,因此在功率谱方面是多余的。

如果您错过了sampf/2,那是因为如果您打算包含0并且是完全对称的,则需要有偶数个步骤但需要奇数个点的偏差问题。请注意,在双面的情况下,最负的频率是-sampf/2,最大错过sampf/2一个bin步骤。您的重建箱最后是(nfft-1)/nfft * (sampf/2)并错过了由于我怀疑浮动四舍五入错误的价值。

+0

是的,我知道我传递的数据是实数,因此我只需要一半的FFT。我的问题是频率箱应该标注什么值?如果我做了双面fft,那么最大频率应该是(sampf/2)还是应该是((sampf/2) - (2/nfft))? – mor22

+0

再次阅读我的答案的最后一段,然后阅读https://en.wikipedia.org/wiki/Fast_Fourier_transform。 – tacaswell

+0

好的,我已经用较低的nfft重新计算了值,表明没有舍入误差。 wiki页面(和其他人)表示单面fft的最后一个bin应该是((sampf/2) - (1/nfft))。因此,关于双面fft实数据的对称性质的观点表明,第一个箱应标记为 - ((sampf/2) - (1/nfft))。这不是matplotlib函数返回的结果,这是我想要的。我想知道我是否可以信任股票函数。 – mor22