傅里叶频谱、能量谱密度、自相关函数

scipy.fftpack中实现的 FFT 变换为:
X k = ∑ n = 0 N − 1 x [ n ] e − i ω 0 k n X_k = \sum_{n=0}^{N-1} x[n]e^{-i\omega_0 kn} Xk=n=0N1x[n]eiω0kn
逆变换为:
x [ n ] = 1 N ∑ k = 0 N − 1 X k e i ω 0 k n x[n] = \frac{1}{N}\sum_{k=0}^{N-1} X_k e^{i\omega_0 kn} x[n]=N1k=0N1Xkeiω0kn
对应的帕塞瓦尔等式为:
∑ n = 0 N − 1 ∣ x [ n ] ∣ 2 = ∑ n = 0 N − 1 x [ n ] x [ n ] ‾ = 1 N ∑ n = 0 N − 1 x [ n ] ∑ k = 0 N − 1 X k e i ω 0 k n ‾ = 1 N ∑ n = 0 N − 1 x [ n ] ∑ k = 0 N − 1 X k ‾ e − i ω 0 k n = 1 N ∑ k = 0 N − 1 [ ∑ n = 0 N − 1 x [ n ] e − i ω 0 k n ] X k ‾ = 1 N ∑ k = 0 N − 1 X k X k ‾ = 1 N ∑ k = 0 N − 1 ∣ X k ∣ 2 \begin{aligned} &\sum_{n=0}^{N-1} \left|x[n]\right|^2 \\\\ =& \sum_{n=0}^{N-1} x[n]\overline{x[n]} \\\\ =& \frac{1}{N}\sum_{n=0}^{N-1} x[n]\overline{\sum_{k=0}^{N-1} X_k e^{i\omega_0 kn}} \\\\ =& \frac{1}{N}\sum_{n=0}^{N-1} x[n] \sum_{k=0}^{N-1} \overline{X_k} e^{-i\omega_0 kn} \\\\ =& \frac{1}{N} \sum_{k=0}^{N-1} \left[ \sum_{n=0}^{N-1} x[n] e^{-i\omega_0 kn}\right] \overline{X_k} \\\\ =& \frac{1}{N} \sum_{k=0}^{N-1} X_k \overline{X_k} \\\\ =& \frac{1}{N} \sum_{k=0}^{N-1} |X_k|^2 \end{aligned} ======n=0N1x[n]2n=0N1x[n]x[n]N1n=0N1x[n]k=0N1Xkeiω0knN1n=0N1x[n]k=0N1Xkeiω0knN1k=0N1[n=0N1x[n]eiω0kn]XkN1k=0N1XkXkN1k=0N1Xk2
故可以定义能量谱密度:
P k = ∣ X k ∣ 2 N P_k = \frac{|X_k|^2}{N} Pk=NXk2

from scipy.fftpack import fft, fftshift, ifft
from scipy.fftpack import fftfreq
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")

fs = 2048  # 采样频率
N = fs  # 采样点数

num_fft = N

"""
生成原始信号序列

在原始信号中加上噪声
np.random.randn(t.size)
"""
t = np.arange(0, 1, 1/fs)
f0 = 100
f1 = 200
x = np.cos(2*np.pi*f0*t)*1 + np.cos(2*np.pi*f1*t)*3 + np.random.randn(t.size)*10
print('total energy in time domain:', np.sum(x**2))
plt.figure(figsize=(15, 12))
ax=plt.subplot(511)
ax.set_title('original signal')
plt.tight_layout()
plt.plot(x)
"""
FFT(Fast Fourier Transformation)快速傅里叶变换
"""
Y = fft(x, num_fft)
Y = np.abs(Y)

ax=plt.subplot(512)
ax.set_title('fft transform')
plt.plot(np.arange(num_fft//2)*fs/num_fft, Y[:num_fft//2])
"""
功率谱 power spectrum
直接平方
"""
ps = Y**2/num_fft
ax=plt.subplot(513)
ax.set_title('direct method')
plt.plot(np.arange(num_fft//2)*fs/num_fft, ps[:num_fft//2])
print('total energy in frequency domain:', np.sum(ps))
"""
相关功谱率 power spectrum using correlate
间接法
"""
cor_x = np.correlate(x, x, 'same')

ax=plt.subplot(514)
ax.set_title('cor_x')
plt.plot(cor_x[N//2:])
plt.tight_layout()

cor_X = fft(cor_x, num_fft)
ps_cor = np.abs(cor_X)/num_fft

ax=plt.subplot(515)
ax.set_title('indirect method')
plt.plot(np.arange(num_fft//2)*fs/num_fft, ps_cor[:num_fft//2])
plt.tight_layout()
print('total energy by correlate:', np.sum(ps_cor))

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/itnerd/article/details/108872893