【问题标题】:np.fft.fft off by a factor of 1000 (fitting an powerspectrum)np.fft.fft 关闭 1000 倍(拟合功率谱)
【发布时间】:2012-12-21 12:05:41
【问题描述】:

我正在尝试从我正在读取的实验数据集中制作功率谱,然后将其拟合到理论曲线。现在一切正常,我没有收到错误,除了我的曲线与数据的差异一直为 1000 倍,我完全不知道问题可能是什么。我问了几个人,但无济于事。 (希望大家多多帮忙)

无论如何,我很确定它不是单位,因为我和其他 2 人对它们进行了三次检查。基本上,我需要使用最小二乘法将功率谱拟合到方程中。 我不能发布整个代码,因为它相当长而且有点凌乱,但这是傅立叶部分,我将 cmets 添加到所有未在代码中声明的数组和变量中)

#Calculate stuff
Nm = 10**-6 #micro to meter
KbT = 4.10E-21 #Joule 
T = 297. #K
l = zvalue*Nm #meter

meany = np.mean(cleandatay*Nm) #meter (cleandata is the array that I read in from a cvs at the start.)
SDy = sum((cleandatay*Nm - meany)**2)/len(cleandatay) #meter^2

FmArray[0][i] = ((KbT*l)/SDy) #N
#print FmArray[0][i]

print float((i*100/len(filelist)))#how many % done?

#fourier
dt = cleant[1]-cleant[0] #timestep
N = len(cleandatay) #Same for cleant, its the corresponding time to cleandatay

这是傅立叶部分的开始,我将 fft 转换为功率谱。然后我用数组freqs计算相应的频率步数

fouriery =  np.fft.fft((cleandatay*(10**-6)))
fourierpower = (np.abs(fouriery))**2
fourierpower = fourierpower[1:N/2] #remove 0th datapoint and /2 (remove negative freqs)
fourierpower =  fourierpower*dt #*dt to account for steps

freqs = (1.+np.arange((N/2)-1.))/50.

#Least squares method
eta = 8.9E-4 #pa*s
Rbead = 0.5E-6#meter
constant = 2*KbT/(3*eta*pi*Rbead)    

omega = 2*pi*freqs #rad/s
Wcarray = 2.*pi*np.arange(0,30, 0.02003) #0.02 = 30/len(freqs)
ChiSq = np.zeros(len(Wcarray))

for k in range(0, len(Wcarray)):
    Py = (constant / (Wcarray[k]**2 + omega**2))
    ChiSq[k] = sum((fourierpower - Py)**2)
    pylab.loglog(omega, Py)
    print k*100/len(Wcarray) 


index = np.where(ChiSq == min(ChiSq))
cutoffw = Wcarray[index]    
Pygoed = (constant / (Wcarray[index]**2 + omega**2))
print cutoffw
print constant
print min(ChiSq)
pylab.loglog(omega,ChiSq)

所以我不知道可能出了什么问题,我认为是 fft,因为没有其他事情真的会出错。 下面是我根据光谱绘制所有拟合线时得到的图片,你可以看到它偏离了大约 1000(实际上正好是 1000,因为这留下了 10^-22 的最小二乘残差,但我不能只是随机相乘而不知道为什么) 只是为了详细说明图片。绿点是 fft 频谱,线条是拟合,红点是它认为截止频率所在的位置,蓝线是卡方拟合,寻找最低值。

【问题讨论】:

  • 尝试对您在 numpy 中生成的已知信号进行分析,您可以准确地知道功率谱应该是什么样子,例如,一个简单的正弦波,然后看看结果如何。 (此外,这对于本网站上的人来说更容易调试,因为我们可以运行代码,假设有人如此倾向于。)这些示例是数据分析的单元测试,并且会给你对结果的合理信心。

标签: numpy fft


【解决方案1】:

查看您正在使用的 FFT 的文档。许多 FFT 引入了通常为 N * 结果(样本数)的比例因子。乘以 1/N 将按比例缩放结果。 (你说结果1000太高了……难道你用的是1024大小的FFT?)

【讨论】:

  • 我正在使用 Cooley - Tukey 算法 (docs.scipy.org/doc/numpy/reference/generated/…) 我认为它可以解释这一点,但是即使它不是我的数组大小是 5999,也不是这样。 (或者这里还有其他东西吗?)
  • 通常 FFT 确实希望 FFT 的大小是 2 的幂(例如 FFT 大小 4096)也许隐含的填充会产生一些影响。您可以尝试更小或更大的样本量,看看是否会影响缩放比例?
  • 2 的幂只会让事情变得更快,只要你的尺寸不是质数 Cooley-Tukey 仍然可以大大加快速度。除非被要求这样做,否则 SciPy/NumPy 绝对不会填充。
  • 处理任何 FFT 库的关键是了解它们对世界的看法。有些缩放结果有些不填充其他人不填充的输入。 RT*M 始终是一个不错的起点。
  • Numpy 的 FFT 计算的确切定义在这里:docs.scipy.org/doc/numpy/reference/…
【解决方案2】:

您的库 FFT 例程可能包含 1/sqrt(n) 的比例因子。

检查您使用的 fft 的文档,因为 fft 和 ifft 之间分配的比例因子的比例是任意的。

【讨论】:

  • Numpy 在 ifft 中包含整个 1/n 因子。
猜你喜欢
  • 2012-06-24
  • 1970-01-01
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
相关资源
最近更新 更多