MUSIC算法是学者 Schmidt 等人 1979 年提出的, 该算法是空间谱估计理论体系中的标志性算法, 它开创了空间谱估计算法研究的新时代, 促进了特征结构类算法的兴起和发展。MUSIC 算法的基本思想是将阵列输出数据的协方差矩阵进行特征分解, 得到与信号分量相对应的信号子空间和与信号分量正交的噪声子空间, 然后利用这 2 个空间的正交性来估计信号的人射方向、极化信息及信号强度等参数。
在矩阵理论中关于特征值与特征矢量描述如下:
R x u i = λ i u i ( i = 1 , 2 , ⋯ , M ) (2.1) \boldsymbol{R}_x \boldsymbol{u}_i=\lambda_i \boldsymbol{u}_i \quad(i=1,2, \cdots, M)\tag {2.1} Rxui=λiui(i=1,2,⋯,M)(2.1)
假定特征值按照降序排列:
λ 1 > λ 2 > λ 3 > ⋯ > λ M (2.2) \lambda_1>\lambda_2>\lambda_3>\cdots>\lambda_M\tag {2.2} λ1>λ2>λ3>⋯>λM(2.2)
那么:
λ 1 = λ max (2.3) \lambda_1=\lambda_{\max }\tag {2.3} λ1=λmax(2.3)
特征矢量组成矩阵:
U = [ u 1 u 2 ⋯ u M ] (2.4) \boldsymbol{U}=\left[\begin{array}{llll} \boldsymbol{u}_1 & \boldsymbol{u}_2 & \cdots & \boldsymbol{u}_M \end{array}\right]\tag {2.4} U=[u1u2⋯uM](2.4)
那么:
R x U = R x [ u 1 u 2 ⋯ u M ] = [ λ 1 u 1 λ 2 u 2 ⋯ λ M u M ] = [ u 1 u 2 ⋯ u M ] [ λ 1 0 ⋯ 0 0 λ 2 ⋯ 0 ⋮ ⋮ ⋮ 0 0 ⋯ λ M ] = U (2.5) \begin{aligned} \boldsymbol{R}_x \boldsymbol{U}=\boldsymbol{R}_x\left[\begin{array}{llll} u_1 & u_2 & \cdots & u_M \end{array}\right]=\left[\begin{array}{llll} \lambda_1 u_1 & \lambda_2 u_2 & \cdots & \lambda_M u_M \end{array}\right]=\\ {\left[\begin{array}{lllll} u_1 & u_2 & \cdots & u_M \end{array}\right]\left[\begin{array}{cccc} \lambda_1 & 0 & \cdots & 0 \\ 0 & \lambda_2 & \cdots & 0 \\ \vdots & \vdots & & \vdots \\ 0 & 0 & \cdots & \lambda_M \end{array}\right]=\boldsymbol{U} \tag {2.5}} \end{aligned} RxU=Rx[u1u2⋯uM]=[λ1u1λ2u2⋯λMuM]=[u1u2⋯uM]⎣⎢⎢⎢⎡λ10⋮00λ2⋮0⋯⋯⋯00⋮λM⎦⎥⎥⎥⎤=U(2.5)
将阵列快拍信号 x ( t ) \boldsymbol{x}(t) x(t) 的协方差矩阵特征矢量矩阵分解为前 P P P 个特征矢量矩阵 U s ( M × P ) \boldsymbol{U}_{s(M \times P)} Us(M×P) 与后 Q Q Q 个特征矢量矩阵 U n ( M × Q ) \boldsymbol{U}_{n(M \times Q)} Un(M×Q), 即:
U ( M × M ) = [ U s ( M × P ) U n ( M × Q ) ] (2.6) \boldsymbol{U}_{(M \times M)}=\left[\begin{array}{ll} \boldsymbol{U}_{s(M \times P)} & \boldsymbol{U}_{n(M \times Q)} \end{array}\right] \tag {2.6} U(M×M)=[Us(M×P)Un(M×Q)](2.6)
前 P P P 个大特征值对应特征矢量 U s \boldsymbol{U}_s Us, 由信号特征矢量组成; 后 M − P M-P M−P 个小特征值对应特征矢量 U n U_n Un, 由噪声特征矢量组成。
考虑到实际接收数据矩阵是时间有限长的, 数据协方差矩阵的估计为:
R x = 1 L ∑ i = 1 L X X H (2.7) \boldsymbol{R}_x=\frac{1}{L} \sum_{i=1}^L \boldsymbol{X} \boldsymbol{X}^{\mathrm{H}} \tag {2.7} Rx=L1i=1∑LXXH(2.7)
对 R x \boldsymbol{R}_x Rx 进行特征值分解可以计算得到信号子空间 U s U_s Us 噪声子空间 U n U_n Un 和由特征值构成的对角矩阵 Σ \boldsymbol{\Sigma} Σ ,即:
a j H U n U n H a j = 0 ( j = 1 , 2 , ⋯ , P ) (2.8) \boldsymbol{a}_j^{\mathrm{H}} \boldsymbol{U}_n \boldsymbol{U}_n^{\mathrm{H}} \boldsymbol{a}_j=0 \quad(j=1,2, \cdots, P) \tag {2.8} ajHUnUnHaj=0(j=1,2,⋯,P)(2.8)
实际上求 DOA 是以最小优化搜索实现的, 即:
θ Music = arg θ { min ( a H ( θ ) U n U n H a ( θ ) ) } (2.9) \theta_{\text {Music }}=\underset{\theta}{\arg }\left\{\min \left(\boldsymbol{a}^{\mathrm{H}}(\theta) \boldsymbol{U}_n \boldsymbol{U}_n^{\mathrm{H}} \boldsymbol{a}(\theta)\right)\right\} \tag {2.9} θMusic =θarg{min(aH(θ)UnUnHa(θ))}(2.9)
习惯上, 我们构造类似功率谱函数, 搜索最大值替代搜索最小值, 即:
P MusIC = 1 a H ( θ ) U n U n H a ( θ ) (2.10) P_{\text {MusIC }}=\frac{1}{\boldsymbol{a}^{\mathrm{H}}(\theta) \boldsymbol{U}_n \boldsymbol{U}_n^{\mathrm{H}} \boldsymbol{a}(\theta)} \tag {2.10} PMusIC =aH(θ)UnUnHa(θ)1(2.10)
按方位角度 θ \theta θ 进行搜索,取得峰值的 θ 1 , θ 2 , ⋯ , θ N \theta_1, \theta_2, \cdots, \theta_N θ1,θ2,⋯,θN 就是 N N N 个信 号源的波达方向估计值。
也可以采用信号子空间方法构造空间谱函数:
P M U S I C = 1 a H ( θ ) ( I − U S U S H ) a ( θ ) (2.11) P_{\mathrm{MUSIC}}=\frac{1}{\boldsymbol{a}^{\mathrm{H}}(\theta)\left(I-\boldsymbol{U}_S \boldsymbol{U}_{\mathrm{S}}^{\mathrm{H}}\right) \boldsymbol{a}(\theta)}\tag {2.11} PMUSIC=aH(θ)(I−USUSH)a(θ)1(2.11)
# 导入模块
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
# 生成快拍数据
def gen_signal(fre, t_0, theta, speed, numbers, space):
res = []
for i in range(numbers):
res.append(np.exp(2j*np.pi*fre*t_0 - 2j*np.pi*fre*i*space*np.cos(theta)/speed))
return np.array(res)
# 生成方向矢量
def steer_vector(fre, theta, speed, numbers, sapce):
alphas = []
for i in range(numbers):
alphas.append(np.exp(-2j*np.pi*fre*i*space*np.cos(theta)/speed))
return np.array(alphas).reshape(-1, 1)
# Music算法
def cal_music(fre, speed, numbers, space, signals, method='signal'):
R_x = np.matmul(signals, np.conjugate(signals.T)) / signals.shape[1]
lamda, u = np.linalg.eig(R_x)
u_s = u[:, np.argmax(lamda)].reshape(-1, 1)
u_n = np.delete(u, np.argmax(lamda), axis=1)
P = []
thetas = np.linspace(-np.pi/2, np.pi/2, 180)
for _theta in thetas:
_alphas = steer_vector(fre, _theta, speed, numbers, space).reshape(-1, 1)
if method == 'signal':
P_x = 1 / np.matmul(np.matmul(np.conjugate(_alphas).T, np.eye(len(u_s)) - np.matmul(u_s, np.conjugate(u_s.T))), _alphas)
elif method == 'noise':
P_x = 1 / (np.matmul(np.matmul(np.matmul(np.conjugate(_alphas).T, u_n), np.conjugate(u_n.T)), _alphas))
else:
print('there is no ' + method)
break
P.append(P_x)
P = np.array(P).flatten()
return thetas/np.pi*180, P
# 初始化数据
fs = 20000
# 定义源信号
fre = 200
t = np.arange(0, 0.01, 1/fs)
theta1 = np.pi / 3
theta2 = 2 * np.pi / 3
# 传播速度
speed = 340
# 阵元数量
numbers = 32
# 阵元之间距离
space = 1
# 生成模拟快拍数据
signals = []
for t_0 in t:
signal1 = gen_signal(fre, t_0, theta1, speed, numbers, space)
signal2 = gen_signal(fre, t_0, theta2, speed, numbers, space)
signal = signal1 + signal2
signals.append(signal.tolist())
signals = np.array(signals)
# Music算法处理结果
thetas, P = cal_music(fre, speed, numbers, space, signals, method='noise')
plt.figure(figsize=(10, 2))
plt.plot(thetas, abs(P))
plt.xlim(-90, 90)
plt.xlabel('degree')
plt.ylabel('mag')
plt.show()
文中如有错误或不清晰的地方,敬请谅解,可留言指出,笔者将及时答复、更改,希望共同进步,谢谢支持。