Skip to content

子空间方法的频率估计

创建一个长度为 24 个样本的复值信号。该信号由频率为 0.4 Hz 和 0.425 Hz 的两个复指数(正弦波)和加性复高斯白噪声组成。噪声的均值和方差为零0.2的平方在复数白噪声中,实部和虚部的方差都等于总方差的一半。 因为添加有随机高斯白噪声,每次运行结果不一样。

python
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import math
n=np.arange(24)
fs=1000
x=np.exp(2*np.pi*0.4*n*1j)+np.exp(2*np.pi*0.425*n*1j)+0.2/math.sqrt(2)*np.random.normal(size=n.shape)+np.random.normal(size=n.shape)*1.0j
plt.psd(x,NFFT=150,Fs=fs,window=mlab.window_none,noverlap=75, pad_to=512,scale_by_freq=True)
plt.title('Fres=41.6888mHz')
plt.ylabel('Power Spectrum(dB)')
plt.xlabel('Frequency')
plt.grid(True)
plt.show()

png

使用子空间方法来解析两个紧密间隔的峰。在此示例中,使用 MUSIC 方法。估计自相关矩阵并将自相关矩阵输入到pmusic中。指定具有两个正弦分量的模型。绘制结果。

python
from scipy.linalg import toeplitz
import math
import warnings
warnings.filterwarnings("ignore")
N=256
n=np.arange(256)
x=(np.exp(2*np.pi*0.4*n*1j)+np.exp(2*np.pi*0.425*n*1j)+
   0.2/math.sqrt(2)*np.random.normal(size=n.shape)+np.random.normal(size=n.shape)*1.0j)

# 自相关函数
def xcorr(data):
    length =len(data)
    R=[]
    for m in range (0,length):
        sums=0.0
        for nn in range(0,length-m):
            sums=sums+data[nn]*data[nn+m]
        R.append(sums/length)
    return R
# 求自相关
R=xcorr(x)
# 自相关矩阵
Rx =toeplitz(R)
w,v = np.linalg.eig(Rx)
v=np.mat(v)
vh=v.H
P=[]
for index in range(0, N+1):
    ew = []
    w = index / N * np.pi
    for k in range(0, N):
        item = complex(np.cos(k * w), np.sin(k * w))
        ew.append(item)
    ew = np.mat(ew)
    ew = ew.T
    eHw = ew.H
    sums = 0
    sums = np.mat(sums)
    for j in range(3, N + 1):
        sums = sums + v[:, j - 1] * vh[j - 1,:]
    fenzi = eHw * sums * ew
    B=1/fenzi[0,0]
    B=math.log10(B)
    P.append(B)

f = np.linspace(0, N, N + 1) / (2 * N)
plt.plot(f,P)
plt.title('Pseudospectrum Estimate via MUSIC')
plt.xlabel("Frequency")
plt.ylabel("Power(dB)")
plt.tight_layout() # 自动布局
plt.show
<function matplotlib.pyplot.show(close=None, block=None)>

png