栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python-用特征分解法估计随机信号的频率并求估计的均方误差

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python-用特征分解法估计随机信号的频率并求估计的均方误差

估计频率:

import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import toeplitz
from numpy.linalg import eig
import statsmodels.tsa.api as smt
pi = math.pi


#添加噪声的函数
def awgn(x,snr):
    snr=10**(snr/10)  #转化为单位为1
    xp=np.sum(x**2)
    nop=xp/snr   #计算噪声能量
    noise=np.random.randn(len(x)) #得出噪声序列
    pnoise=sum(noise**2)  #计算噪声能量
    n_noise=math.sqrt(pnoise)  #用于计算噪声值
    noise=noise/n_noise   #将噪声的能量变为1
    noise=noise*(math.sqrt(nop))   #得出噪声序列
    xr=x+noise
    return xr

#求自相关函数的函数
def zxg(x):
    x=list(x)
    l=len(x)
    r=[0]*(l)
    xnp=np.array(x)
    xx=x
    r[0]=sum(xnp*xnp)
    for i in range(0,l-1):
        xx.insert(0,0)
        xxnp=np.array(xx[0:l])    #时延为几就在列表前加几个0,然后取前128个
        r[i+1]=sum(xnp*xxnp)
    tem=list(reversed(r))
    tem1=tem[0:l-1]
    rx=tem1+r     #rx为自相关函数
    return rx


N=127
n = np.arange(0, N+1, 1)
x=10*np.cos(2*pi*0.1*n+pi/3)+10*np.cos(2*pi*0.11*n+pi/5)
xr = awgn(x, 10)

rx=zxg(xr)
rx=rx[127:255]
Rx=toeplitz(rx)  #求出特征矩阵,即托步列兹阵
w, v = eig(Rx)  #求特征分解,w为特征值,v为特征向量
w = list(sorted(w, reverse=True))
#下面求出信号的个数m
m = 0
for i in range(0, len(w)):
    if w[i]/w[0] > 0.5:
        m = m+1
    else:
        break

buchang=0.01
ww=np.arange(0,pi,buchang)
leng=len(ww)
p=[]
ll=1  #用于给p赋值
v=np.mat(v)  #将特征向量v变为矩阵形式
vh=v.H   #特征向量v的共轭转置
for i in range(0,leng):
    ww=i*buchang    #ww为频率
    ei=[]
    for k in range(0,N+1):
        temp=complex(np.cos(k*ww),np.sin(k*ww))
        ei.append(temp)
    ei=np.mat(ei)
    ei=ei.T   #信号向量的转置
    ei1=ei.H  #信号向量的共轭转置
    ei2=ei
    summ=0
    for n in range(m,N+1):      #注意:python中的小特征值的特征向量从第3个开始,索引值为2
        summ=summ+v[:,n]*vh[n,:]
    pp=1/(ei1*summ*ei2)
    pp=pp[0,0]
    p.append(abs(pp))



#plt画图是找不到字体,需要手动设置:
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False
f=list(range(0,len(p)))
f=np.array(f)
f=f/(2*len(p))
f=list(f)

plt.plot(f,p)
plt.xlabel('f/Hz')
plt.ylabel('p')
plt.title('似功率谱')
plt.show()


p=np.array(p)
ff1=np.argmax(p)
p[ff1]=0
f1=ff1/(2*len(p))
ff2=np.argmax(p)
f2=ff2/(2*len(p))
print('f1的估计为:',f1)
print('f2的估计为:',f2)






均方误差:

import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import toeplitz
from numpy.linalg import eig
import statsmodels.tsa.api as smt
pi = math.pi

#添加噪声的函数
def awgn(x,snr):
    snr=10**(snr/10)  #转化为单位为1
    xp=np.sum(x**2)
    nop=xp/snr   #计算噪声能量
    noise=np.random.randn(len(x)) #得出噪声序列
    pnoise=sum(noise**2)  #计算噪声能量
    n_noise=math.sqrt(pnoise)  #用于计算噪声值
    noise=noise/n_noise   #将噪声的能量变为1
    noise=noise*(math.sqrt(nop))   #得出噪声序列
    xr=x+noise
    return xr

def zxg(x):
    x=list(x)
    l=len(x)
    r=[0]*(l)
    xnp=np.array(x)
    xx=x
    r[0]=sum(xnp*xnp)
    for i in range(0,l-1):
        xx.insert(0,0)
        xxnp=np.array(xx[0:l])    #时延为几就在列表前加几个0,然后取前128个
        r[i+1]=sum(xnp*xxnp)
    tem=list(reversed(r))
    tem1=tem[0:l-1]
    rx=tem1+r     #rx为自相关函数
    return rx


N=127
n = np.arange(0,N+1,1)
x=np.cos(2*pi*0.1*n+pi/3)+np.cos(2*pi*0.11*n+pi/5)

flag=0

mse1=[]    #用于记录f1估计的均方差
mse2=[]    #用于记录f2估计的均方差
c=np.zeros((1,100))    #存储每一个信噪比中10次f1的估计值
d=np.zeros((1,100))    #存储每一个信噪比中10次f1的估计值
e=np.zeros((1,100))    #为了求f1估计的方差
f=np.zeros((1,100))    #为了求f2估计的方差

for snr in range(-30,30,2):
    for i in range(0,100):
        xr=awgn(x,snr)
        rx = zxg(xr)
        rx = rx[127:255]
        Rx = toeplitz(rx)  # 求出特征矩阵,即托步列兹阵
        w, v = eig(Rx)  # 求特征分解,w为特征值,v为特征向量
        w = list(sorted(w, reverse=True))
        # 下面求出信号的个数m
        m = 0
        for ii in range(0, len(w)):
            if w[ii] / w[0] > 0.5:
                m = m + 1
            else:
                break

        buchang = 0.01
        ww = np.arange(0, pi, buchang)
        leng = len(ww)
        p = []
        ll = 1  # 用于给p赋值
        v = np.mat(v)  # 将特征向量v变为矩阵形式
        vh = v.H  # 特征向量v的共轭转置
        for ii in range(0, leng):
            ww = ii * buchang  # ww为频率
            ei = []
            for k in range(0, N + 1):
                temp = complex(np.cos(k * ww), np.sin(k * ww))
                ei.append(temp)
            ei = np.mat(ei)
            ei = ei.T  # 信号向量的转置
            ei1 = ei.H  # 信号向量的共轭转置
            ei2 = ei
            summ = 0
            # 注意:python中的小特征值的特征向量从第3个开始,索引值为2
            for n in range(m, N + 1):
                summ = summ + v[:, n] * vh[n, :]
            pp = 1 / (ei1 * summ * ei2)
            pp = pp[0, 0]
            p.append(abs(pp))

        #下面估计频率f1,f2
        num=len(p)
        p=np.array(p)
        pxr = abs(p)  #执行后pxr是信号的功率谱
        ff1 = np.argmax(pxr)
        pxr[ff1] = 0
        if ff1==0:
            pxr[num-1]=0
        else:
            pxr[num - ff1] = 0
        f1 = ff1 / (2*(len(pxr)))
        for ii in range(0, len(pxr)):
            ff2 = np.argmax(pxr)
            f2 = ff2 / (2*(len(pxr)))
            if abs(f2 - f1) < 0.01:
                pxr[ff2] = 0
                if ff2==0:
                    pxr[num-1]=0
                else:
                    pxr[num-ff2]=0
            else:
                break

        if (abs(f1-0.1)abs(f2-0.1)):
            c[0,i]=f2
            d[0,i]=f1
        elif (abs(f1-0.1)>=abs(f1-0.13)) and (abs(f1-0.13)<=abs(f2-0.13)):
            c[0,i]=f2
            d[0,i]=f1
        elif (abs(f1-0.1)>=abs(f1-0.13)) and (abs(f1-0.13)>abs(f2-0.13)):
            c[0,i]=f1
            d[0,i]=f2
        else:
            c[0,i]=f2
            d[0,i]=f1

        print(flag,i)

    flag=flag+1
    ave1=sum(c[0,:])/100  #此信噪比下频率f1的均值
    ave2=sum(d[0,:])/100  #此信噪比下频率f2的均值
    for j in range(0,100):
        e[0,j]=(c[0,j]-ave1)**2
        f[0,j]=(d[0,j]-ave2)**2

    var1=sum(e[0,:])/100    #此信噪比下f1估计的方差
    var2=sum(f[0,:])/100  #此信噪比下f2估计的方差
    bia1=0.1-ave1   #f1估计的偏
    bia2=0.13-ave2   #f2估计的偏
    tem1=var1+bia1**2
    mse1.append(tem1)   #python索引从0开始
    tem2=var2+bia2**2
    mse2.append(tem2)


te_mse1=mse1
te_mse2=mse2

#下面画图
nf1=np.arange(0,2*len(mse1),2)
nf1=nf1-30
nf2=np.arange(0,2*len(mse2),2)
nf2=nf2-30

#plt画图是找不到字体,需要手动设置:
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False

plt.figure(1)
ax1=plt.subplot(2,1,1)
ax2=plt.subplot(2,1,2)

plt.sca(ax1)
plt.plot(nf1,mse1[0:])
plt.xlabel('snr/dB')
plt.ylabel('mse')
plt.title('特征分解_f1的均方差')

plt.sca(ax2)
plt.plot(nf2,mse2[0:])
plt.xlabel('snr/dB')
plt.ylabel('mse')
plt.title('特征分解_f2的均方差')
plt.show()

若有不当之处请多多指正

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/275490.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号