Welch方法在Parsevals定理中的应用

时间:2018-08-29 14:21:23

标签: python fft spectrum

对于我的项目,我必须使用下面的代码手动编写welch方法。它几乎涉及到通过fft找到光谱密度,并结合开窗和分段重叠。

我需要知道我的PSD是否正确,因此我正在通过2种方法进行检查。

  1. PSD下的面积根应为RMS(E [x ^ 2]),由于我已经从数据中去除了平均值,因此该值应等于数据的标准偏差
  2. 检查Parseval定理是否成立。

我遇到了两个主要问题。首先,即使在开始时消除了平均值,我仍然获得了0Hz的峰值。删除0Hz峰值的唯一方法是在分割并乘以窗口后取平均值。 (####下降趋势线####)

具有峰值,点1保持良好,但没有峰值,标准偏差与RMS略有不同,但这并不是一个大问题。

我的第二个问题是我无法掌握Parseval定理。我做错了什么吗?帕瑟瓦尔的理论有必要成立吗?如果我的理论是错误的,请告诉我。

关于代码的注释对:

  • 很抱歉,如果编码效率不高,我还是新手
  • 将fft除以(fs *(win * win).sum())是我通过研究发现的内容,也是内置的Welch代码的一部分
  • 最后我正在使用梯形规则进行积分
  • 我的FFT能量小了几个数量级(即E-09)

PSD with 0Hz peak removed

PSD with 0Hz peak

import numpy as np
import matplotlib.pyplot as plt
import os
import math
from scipy.fftpack import fft, ifft, fftfreq, rfft
from scipy.signal import detrend, get_window

plt.clf()
plt.close()

###############################################################################

config = '1perc_damping'

dir0 = os.getcwd()
dir1 = dir0+'/'+config
dir2 = dir1+'/Summary files'

data = np.loadtxt(dir1 + '/000deg_500rpm_An_Mxx.dat')

###############################################################################

fs = 625
nperseg = 1024
noverlap = 512
window_meth = 'hanning'


###############################################################################

#detrend
data = data - np.mean(data)


#get windowing method
win = get_window(window_meth, nperseg)

# number of segments
nseg = np.ceil((len(data)-nperseg)/(nperseg-noverlap)) + 1 

total_n = nperseg + (nseg-1)*(nperseg-noverlap)

# padding with zeros
if total_n > len(data):
    n = total_n - len(data)
    padding = np.zeros(np.int(n))
    data = np.concatenate((data,padding))


# fft 

fft_data = 0

for i in range(0,np.int(nseg)):

    start = i*(nperseg-noverlap)

    f_data = np.multiply(data[start:start+nperseg],win) 
    f_data = f_data- np.mean(f_data)   #### Detrend line ### 

    transf = fft(f_data)
    transf_c = (transf*np.conj(transf))/(fs*(win*win).sum())

    fft_data = fft_data + transf_c


Pxx = np.real(fft_data)/(nseg)
fx = fftfreq(nperseg, 1/fs)

plt.figure(1)
plt.plot(fx[0:512],2*Pxx[0:512])
#plt.plot(fx,Pxx)

plt.figure(2)
x = np.linspace(0,len(data),len(data))
plt.plot(x,data)

#Finding RMS
l = np.int(len(fx)/2 -1)
c = 2
A = 0

for i in range(1,l+1):
    A = A + 0.5*(c*Pxx[i]+c*Pxx[i-1])*(fx[i]-fx[i-1])

RMS = np.sqrt(A)

# Checking Parseval's theorem
data_energy = 0
FFT_energy = 0

for i in range(1,l+1):
    FFT_energy = FFT_energy + 0.5*(np.power(c*Pxx[i],2)+np.power(c*Pxx[i-1],2))*(fx[i]-fx[i-1])

for i in range(1,len(data)):
    data_energy = data_energy + 0.5*(np.power(abs(data[][1][i]),2)+np.power(abs(data[i-1]),2))*(i-(i-1))*(1/625)

0 个答案:

没有答案