对于我的项目,我必须使用下面的代码手动编写welch方法。它几乎涉及到通过fft找到光谱密度,并结合开窗和分段重叠。
我需要知道我的PSD是否正确,因此我正在通过2种方法进行检查。
我遇到了两个主要问题。首先,即使在开始时消除了平均值,我仍然获得了0Hz的峰值。删除0Hz峰值的唯一方法是在分割并乘以窗口后取平均值。 (####下降趋势线####)
具有峰值,点1保持良好,但没有峰值,标准偏差与RMS略有不同,但这并不是一个大问题。
我的第二个问题是我无法掌握Parseval定理。我做错了什么吗?帕瑟瓦尔的理论有必要成立吗?如果我的理论是错误的,请告诉我。
关于代码的注释对:
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)