python中一个实际问题离散功率谱密度的正确归一化
我正在努力实现功率谱密度(及其逆功率谱密度)的正确标准化 我遇到了一个真正的问题,比如加速度计的读数,以功率谱密度(psd)的形式表示,单位为振幅^2/Hz。我想把它转换成一个随机时间序列。然而,首先我想了解“前进”方向,时间序列到PSD 根据[1],时间序列x(t)的PSD可通过以下公式计算:python中一个实际问题离散功率谱密度的正确归一化,python,fft,normalization,dft,spectral-density,Python,Fft,Normalization,Dft,Spectral Density,我正在努力实现功率谱密度(及其逆功率谱密度)的正确标准化 我遇到了一个真正的问题,比如加速度计的读数,以功率谱密度(psd)的形式表示,单位为振幅^2/Hz。我想把它转换成一个随机时间序列。然而,首先我想了解“前进”方向,时间序列到PSD 根据[1],时间序列x(t)的PSD可通过以下公式计算: PSD(w) = 1/T * abs(F(w))^2 = df * abs(F(w))^2 其中T是x(T)的采样时间,F(w)是x(T)的傅里叶变换,df=1/T是傅里叶空间中的频率分辨率。然而,我
PSD(w) = 1/T * abs(F(w))^2 = df * abs(F(w))^2
其中T是x(T)的采样时间,F(w)是x(T)的傅里叶变换,df=1/T是傅里叶空间中的频率分辨率。然而,我得到的结果并不等于我使用scipy-Welch方法得到的结果,请参见下面的代码
第一段代码取自scipy.welch纪录片:
from scipy import signal
import matplotlib.pyplot as plt
fs = 10e3
N = 1e5
amp = 2*np.sqrt(2)
freq = 1234.0
noise_power = 0.001 * fs / 2
time = np.arange(N) / fs
x = amp*np.sin(2*np.pi*freq*time)
x += np.random.normal(scale=np.sqrt(noise_power), size=time.shape)
f, Pxx_den = signal.welch(x, fs, nperseg=1024)
plt.semilogy(f, Pxx_den)
plt.ylim(\[0.5e-3, 1\])
plt.xlabel('frequency \[Hz\]')
plt.ylabel('PSD \[V**2/Hz\]')
plt.show()
我注意到的第一件事是,绘制的psd随变量fs而变化,这对我来说似乎很奇怪。(也许我需要相应地调整nperseg参数?为什么nperseg不能自动设置为fs?)
我的代码如下:(注意,我定义了自己的fft_全函数,它已经处理了正确的傅里叶变换规范化,我通过检查Parsevals定理来验证)
不幸的是,我还不允许发布图片,但两个情节看起来不一样
如果有人能向我解释我错在哪里,并一劳永逸地解决这个问题,我将不胜感激:)
[1] :等式2.82。航天器结构设计中的随机振动
理论与应用,作者:Wijker,J.Jaap,2009
scipy库使用Welch方法估计PSD。这种方法比只取离散傅里叶变换的平方模更复杂。简言之,其进展如下:
import scipy.fftpack as fftpack
def fft_full(xt,yt):
dt = xt[1] - xt[0]
x_fft=fftpack.fftfreq(xt.size,dt)
y_fft=fftpack.fft(yt)*dt
return (x_fft,y_fft)
xf,yf=fft_full(time,x)
df=xf[1] - xf[0]
psd=np.abs(yf)**2 *df
plt.figure()
plt.semilogy(xf, psd)
#plt.ylim([0.5e-3, 1])
plt.xlim(0,)
plt.xlabel('frequency [Hz]')
plt.ylabel('PSD [V**2/Hz]')
plt.show()