【通信系统】MIMO阵列信号来向DOA估计实现~含FOCUSS、OMP、贝叶斯学习(SBL)等稀疏重构法和常规、子空间法、空间平滑滤波法

news2024/11/25 8:19:36

MIMO阵列目标信号来向估计原理与实现~基于常规法、子空间变换法和稀疏恢复法

  • 写在最前
  • 前言
    • 空间谱估计的历史发展
  • 仿真原理
    • 离散时间阵列信号模型
    • 波束形成矩阵(完备字典)
    • 回波生成
    • 空间平滑滤波
    • 传统方法
      • CBF~常规波束成型
      • Capon~最小方差无失真响应法
      • ML~最大似然估计法
    • 子空间方法
      • MUSIC~多重信号分类法
      • ESPRIT~旋转不变子空间法
        • 最小二乘准则
        • 总体最小二乘准则
    • 稀疏恢复方法
      • FOCUSS~欠定系统聚焦法
      • OMP~正交匹配追踪法
      • 伪逆法
      • EM-SBL~最大期望-稀疏贝叶斯学习法
      • CVX~凸优化法
  • 仿真实现
    • 代码下载
    • 可修改的参数
    • 仿真结果
      • 常规情况
      • 低信噪比情况
      • 相干信源情况
      • 少快拍情况
    • 仿真小结
  • 后语
  • 附录代码
    • DOA_CBF.m
    • DOA_Capon.m
    • DOA_MUSIC
    • DOA_ESPRIT.m
    • DOA_ML.m
    • DOA_FOCUSS.m
    • DOA_OMP.m
    • DOA_PINV.m
    • DOA_EM_SBL.m
    • DOA_CVX.m
    • space_smooth.m

写在最前

本文章的代码已开源,基于凸优化法(CVX)实现DOA时,依赖CVX工具箱,如果你的MATLAB没有安装,请前往这里下载,解压后在MATLAB命令行,cd到解压目录并执行其中的“cvx_setup.m”文件进行安装。如果不做CVX部分的仿真,可忽略这一步。

前言

波达方向估计(Direction Of Arrival, DOA)也称为测向、空间谱估计,为利用电磁波来获取目标或信源对天线阵列的角度信息,主要应用于雷达、通信、电子侦察与对抗等领域。
本文利用MIMO天线阵列实现DOA相关算法的总结,主要仿真实现了常规波束形成(CBF)、Capon和最大似然估计(ML)三种常规方法,多重信号分类法(MUSIC)、LS-ESPRIT和TLS-ESPRIT三种子空间方法,欠定系统聚焦法(FOCUSS)、正交匹配追踪法(OMP)、凸优化法(CVX)、伪逆法(PINV)和期望最大化-稀疏贝叶斯学习法(EM-SBL)等稀疏恢复方法。对比了上述方法在常规、低信噪比、低快拍以及信源相干情况下的性能,并研究了空间平滑算法在处理相干信源问题上的表现。

空间谱估计的历史发展

常规波束形成
Capon自适应波束形成
信号子空间分类方法
最大似然估计法
压缩感知或稀疏恢复法
深度学习法

本文不涉及深度学习法。

仿真原理

离散时间阵列信号模型

天线阵元示意图如下图所示,在仿真中,默认最左边的阵元为相位中心,仿真的前提为信源发射的信号为窄带信号且为远场信号,阵元为全向天线其阵元之间没有互耦和误差。

天线阵列信号接收示意图

为了方便数字化处理,仿真采用了离散时间阵列信号模型:
[ x 1 ( n ) x 2 ( n ) ⋮ x M ( n ) ] = [ 1 1 ⋯ 1 e − j 2 π d s i n θ 1 / λ e − j 2 π d s i n θ 2 / λ ⋯ e − j 2 π d s i n θ p / λ ⋮ ⋮ ⋱ ⋮ e − j 2 π ( M − 1 ) d s i n θ 1 / λ e − j 2 π ( M − 1 ) d s i n θ 2 / λ ⋯ e − j 2 π ( M − 1 ) d s i n θ p / λ ] [ s 1 ( n ) s 2 ( n ) ⋮ s p ( n ) ] + [ n 1 ( n ) n 2 ( n ) ⋮ n M ( n ) ]     x = A ( θ ) s + n \begin{bmatrix} x_1(n) \\ x_2(n) \\ \vdots \\ x_M(n) \end{bmatrix} = \begin{bmatrix} &1 &1 & \cdots &1 \\ & e^{-j2\pi d \mathrm {sin}\theta _1/\lambda } & e^{-j2\pi d \mathrm {sin}\theta _2/\lambda } & \cdots & e^{-j2\pi d \mathrm {sin}\theta _p/\lambda } \\ & \vdots & \vdots & \ddots & \vdots \\ & e^{-j2\pi (M-1)d \mathrm {sin}\theta _1/\lambda } & e^{-j2\pi (M-1)d \mathrm {sin}\theta _2/\lambda } & \cdots & e^{-j2\pi (M-1)d \mathrm {sin}\theta _p/\lambda } \end{bmatrix} \begin{bmatrix} s_1(n) \\ s_2(n) \\ \vdots \\ s_p(n) \end{bmatrix} + \begin{bmatrix} n_1(n) \\ n_2(n) \\ \vdots \\ n_M(n) \end{bmatrix} \, \\ \, \\ \mathbf{x}=\mathbf{A}(\theta) \mathbf{s}+\mathbf{n} x1(n)x2(n)xM(n) = 1ej2πdsinθ1/λej2π(M1)dsinθ1/λ1ej2πdsinθ2/λej2π(M1)dsinθ2/λ1ej2πdsinθp/λej2π(M1)dsinθp/λ s1(n)s2(n)sp(n) + n1(n)n2(n)nM(n) x=A(θ)s+n
其中, x ∈ C M × N \mathbf{x}\in \mathbb{C}^{M \times N} xCM×N为天线阵列接收到的信号; A ∈ C M × P \mathbf{A}\in \mathbb{C}^{M \times P} ACM×P为空域导向矢量; s ∈ C p × N \mathbf{s} \in \mathbb{C}^{p \times N} sCp×N为目标发出的信号; n ∈ C M × N \mathbf{n} \in \mathbb{C}^{M \times N} nCM×N为噪声; d d d为阵元间隔; λ \lambda λ为载频信号的波长; N N N为快拍数; M M M为阵元数量; P P P为目标数量。

波束形成矩阵(完备字典)

该矩阵也称为DOA栅格矩阵,用于估算在每个角度上的功率,该矩阵的表达式为:
a ( θ 0 , θ 1 , … , θ k ) = [ 1 1 ⋯ 1 e j 2 π d s i n θ 0 / λ e j 2 π d s i n θ 1 / λ ⋯ e j 2 π d s i n θ k / λ e j 2 π ( 2 d ) s i n θ 0 / λ e j 2 π ( 2 d ) s i n θ 1 / λ ⋯ e j 2 π ( 2 d ) s i n θ k / λ ⋮ ⋮ ⋱ ⋮ e j 2 π ( M − 1 ) d s i n θ 0 / λ e j 2 π ( M − 1 ) d s i n θ 1 / λ ⋯ e j 2 π ( M − 1 ) d s i n θ k / λ ] a(\theta_0,\theta_1,\dots,\theta_k)=\begin{bmatrix} & 1 & 1 & \cdots & 1 \\ & e^{j2\pi d \mathrm{sin}\theta _0/\lambda} & e^{j2\pi d \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi d \mathrm{sin}\theta _k/\lambda} \\ & e^{j2\pi (2d) \mathrm{sin}\theta _0/\lambda} & e^{j2\pi (2d) \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi (2d) \mathrm{sin}\theta _k/\lambda} \\ & \vdots & \vdots & \ddots & \vdots \\ & e^{j2\pi (M-1)d \mathrm{sin}\theta _0/\lambda} & e^{j2\pi (M-1)d \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi (M-1)d \mathrm{sin}\theta _k/\lambda} \\ \end{bmatrix} a(θ0,θ1,,θk)= 1ej2πdsinθ0/λej2π(2d)sinθ0/λej2π(M1)dsinθ0/λ1ej2πdsinθ1/λej2π(2d)sinθ1/λej2π(M1)dsinθ1/λ1ej2πdsinθk/λej2π(2d)sinθk/λej2π(M1)dsinθk/λ
其中, θ 0 , θ 1 , … , θ k \theta_0,\theta_1,\dots,\theta_k θ0,θ1,,θk为需要做功率估计的等间距的来向角度; a ∈ C M × ( k + 1 ) a\in \mathbb{C}^{M \times (k+1)} aCM×(k+1)为波束形成矩阵。

回波生成

为了保证信号的正交性,省去上变频步骤,本仿真使用随机数+带通滤波方法实现指定带宽与中心频率的信源生成。针对每个信源在 [ f 0 − b w , f 0 + b w ] [f_0-bw,f_0+bw] [f0bw,f0+bw]之间等间隔地划分k个频段,用高斯分布的随机数初始化矩阵 s s s后,对矩阵的每一行执行对应频段的带通滤波以获得频域正交的信号,是不是有种OFDM的感觉了。

空间平滑滤波

在实际使用中,由于存在多径传输等影响因素。阵列接收到的信源信号往往是相干而非完全独立的,为了解决相干源的DOA估计问题,需要使用空间平滑滤波破坏掉接收信号的相干性。该方法将等数量的相邻的实际阵列构成子阵列,并利用所有子阵列的自相关矩阵的平均数作为阵列接收信号的自相关矩阵估计,从而解决实际自相关矩阵的相干问题。当子阵大小L越大时,去相关能力越强,但等效阵列数会越小,从而降低空间分辨率。该方法可表示为:
R x x ^ = E { R i } \hat {R_{xx}}=E\{ R_i \} Rxx^=E{Ri}
其中 R i R_i Ri为第 i i i个子阵列的自相关矩阵。

传统方法

CBF~常规波束成型

该方法大约在二战期间被提出,其本质是傅里叶变换在空域的直接应用,其分辨率受限于瑞丽限。该方法可表示为:
J C B F ( θ ) = a H ( θ ) R x x a ( θ ) ∣ a H ( θ ) a ( θ ) ∣ 2 J_{CBF}(\theta)=\frac {a^H(\theta)R_{xx}a(\theta)}{|a^H(\theta)a(\theta)|^{2}} JCBF(θ)=aH(θ)a(θ)2aH(θ)Rxxa(θ)

Capon~最小方差无失真响应法

这是一种自适应方法,提出于60年代,它将维纳滤波的思想应用于空域处理,相比于CBF法,分辨率得到了一定的提高。Capon法可表示为:
J C a p o n ( θ ) = 1 a H ( θ ) R x x − 1 a ( θ ) J_{Capon}(\theta)=\frac{1}{a^H(\theta)R_{xx}^{-1}a(\theta)} JCapon(θ)=aH(θ)Rxx1a(θ)1

ML~最大似然估计法

最大似然估计在九十年代提出,实质为给定观测数据,评估模型参数。在DOA估计中,ML法可表示为:
J M L ( θ ) = t r a c ( a ( θ ) a H ( θ ) ( a H ( θ ) a ( θ ) ) − 1 ∗ R x x ) / M J_{ML}(\theta)=\mathrm {trac}(\frac{a(\theta)a^H(\theta)}{(a^H(\theta)a(\theta))^{-1}}*R_{xx})/M JML(θ)=trac((aH(θ)a(θ))1a(θ)aH(θ)Rxx)/M
在只有一个目标信源时,该方法等效于CBF法,在多个信源时,ML法为多目标优化问题,运算量较大。

子空间方法

MUSIC~多重信号分类法

时间回到上世纪八十年代,多重信号分类法在这个时候被提出。相比于CBF和Capon法仅使用接收数据的自相关矩阵直接处理,该方法考虑了信号和噪声的分布特性,通过对自相关矩阵做特征分解得到信号子空间和噪声子空间,利用两个子空间的正交特性进行DOA估计。
由于接收信号的自相关矩阵为赫米特(Hermite)矩阵,满足 R H = R R^H=R RH=R,根据相关引理, R R R酉相似于对角矩阵,可进行酉对角化分解,即存在 酉矩阵 U U U和对角阵 V V V,使 U H R U = V U^HRU=V UHRU=V,且V主对角线上的元素为 R R R的特征值。
MUSIC方法可表示为:
J M U S I C ( θ ) = a H ( θ ) a ( θ ) a H ( θ ) ( I − U s U s H ) a ( θ )   或   J M U S I C ( θ ) = a H ( θ ) a ( θ ) a H ( θ ) ( U n U n H ) a ( θ ) J_{MUSIC}(\theta)=\frac{a^H(\theta)a(\theta)}{a^H(\theta)(I-U_sU_s^H)a(\theta)}\, 或 \\ \, \\ J_{MUSIC}(\theta)=\frac{a^H(\theta)a(\theta)}{a^H(\theta)(U_nU_n^H)a(\theta)} JMUSIC(θ)=aH(θ)(IUsUsH)a(θ)aH(θ)a(θ)JMUSIC(θ)=aH(θ)(UnUnH)a(θ)aH(θ)a(θ)
其中, U s ∈ C M × k U_s\in \mathbb{C}^{M\times k} UsCM×k为信号子空间,为 U U U k k k个最大特征值所对应的特征列向量组成的矩阵; U n ∈ C M × ( M − k ) U_n\in \mathbb{C}^{M\times (M-k)} UnCM×(Mk)为噪声子空间; k k k表示信源个数。在应用中可根据信源数量选择信号子空间解法或噪声子空间解法。

ESPRIT~旋转不变子空间法

与MUSIC法在同一时期被提出的子空间方法还有旋转不变子空间法,区别于MUSIC使用酉对角化后信号和噪声子空间的正交性,ESPRIT利用信号子空间的旋转不变特性来求解DOA。
假设存在两个完全相同的子阵列,且子阵列的间距 Δ \Delta Δ已知,假设两个子阵列接收到数据分别为 x 1 x_1 x1 x 2 x_2 x2,则:
x 1 = A s + n 1   x 2 = A Φ s + n 2   Φ = d i a g ( e j ϕ 1   e j ϕ 2   ⋯   e j ϕ p ) x_1=As+n_1 \\ \, \\ x_2=A\Phi s+n_2 \\ \, \\ \Phi=\mathrm {diag}(e^{j\phi_1} \, e^{j\phi_2} \, \cdots \, e^{j\phi_p}) x1=As+n1x2=AΦs+n2Φ=diag(ejϕ1ejϕ2ejϕp)
只要得到两个子阵列的旋转不变关系 Φ \Phi Φ,就能得到信号的到达角,完成DOA估计。
仿真时,令 x 1 x_1 x1 x 2 x_2 x2分别为接收到的信号 x \mathbf{x} x的前 M − 1 M-1 M1行和后 M − 1 M-1 M1行所构成的两个子矩阵,令回波子阵列合并为 x e x p = [ x 1 ; x 2 ] x_{exp}=[x_1;x_2] xexp=[x1;x2],计算 x e x p x_{exp} xexp的自相关矩阵 R e s p = E { x e x p ∗ x e x p H } R_{esp}=E\{x_{exp}*x_{exp}^H\} Resp=E{xexpxexpH},对 R e s p R_{esp} Resp做酉对角化分解,得到酉矩阵 U e s p U_{esp} Uesp和特征值对角矩阵 V e x p V_{exp} Vexp。根据目标数量从 U e s p U_{esp} Uesp中提取信号子空间并进行拆分得到 U s U_s Us的前M-1行 U s 1 U_{s1} Us1和后M-1行 U s 2 U_{s2} Us2,接下来需要求解ESPRIT矩阵 Ξ \Xi Ξ,使:
U s 1 Ξ = U s 2 U_{s1}\Xi=U_{s2} Us1Ξ=Us2
求解出ESPRIT矩阵 Ξ \Xi Ξ后,通过求取该矩阵的特征值并求其复角度即可得到来向角的正弦值,即:
D O A e x p = a r c s i n ( − a n g l e ( V e s p ) ∗ λ 2 π d ) DOA_{exp}=\mathrm{arcsin}(\frac {-\mathrm {angle}(V_{esp})*\lambda}{2\pi d}) DOAexp=arcsin(2πdangle(Vesp)λ)
其中, V e s p ∈ C P × 1 V_{esp}\in \mathbb{C}^{P \times 1} VespCP×1是由 Ξ \Xi Ξ的特征值构成的向量。
求解ESPRIT矩阵 Ξ \Xi Ξ可以使用最小二乘准则或总体最小二乘准则。

最小二乘准则

不难证明,在最小二乘准则下,使用下式对ESPRIT矩阵 Ξ L S \Xi_{LS} ΞLS进行求解:
Ξ L S = p i n v ( U s 1 ) ∗ U s 2 \Xi_{LS}=\mathrm {pinv}(U_{s1})*U_{s2} ΞLS=pinv(Us1)Us2

总体最小二乘准则

在总体最小二乘准则下,令 V T L S − e s p = [ U s 1 , U s 2 ] V_{TLS-esp}=[U_{s1},U_{s2}] VTLSesp=[Us1,Us2]并对V做奇异值分解得到右奇异矩阵 V T L S − E S P ∈ C ( P ∗ 2 ) × ( P ∗ 2 ) V_{TLS-ESP}\in \mathbb{C}^{(P*2)\times (P*2)} VTLSESPC(P2)×(P2),将 V T L S − E S P V_{TLS-ESP} VTLSESP等分为4个方阵并取右上角方阵和右下角方阵分别记为 E 12 E_{12} E12 E 22 E_{22} E22,即可解出ESPRIT矩阵 Ξ T L S \Xi_{TLS} ΞTLS
Ξ T L S = − E 12 ∗ i n v ( E 22 ) \Xi_{TLS}=-E_{12} * \mathrm {inv}(E_{22}) ΞTLS=E12inv(E22)

稀疏恢复方法

终于写到我最感兴趣的部分了。
2004年,陶哲轩、Emmanuel Candes和David Donoho等人证明了“如果信号是稀疏的,那么它可以由远低于采样定理要求的采样点恢复信号”,紧接着提出了“压缩感知”概念。总得来讲,稀疏恢复的前提条件之一为信号的稀疏性,即信号在某个域(常用作信号处理的领域包括时域、频域、多普勒域和空域等)上是稀疏的,在该域上零点的数量远远大于非零点的数量;前提条件之二为观测矩阵和稀疏表示基之间的不相关。如果一个信号在某个变换域是稀疏的,那么可以用一个与变换基不相关观测矩阵将变换所得高维信号投影到一个低维空间上,然后通过求解一个优化问题可从这些少量投影中以高概率重构出信号。
压缩感知的步骤包括压缩采样和信号重构:
压缩采样:
y = Φ Ψ s = Θ s y=\Phi \Psi s=\Theta s y=ΦΨs=Θs
Φ \Phi Φ Ψ \Psi Ψ分别为观测矩阵和稀疏表示基,它们是不相关的; Θ \Theta Θ为传感矩阵
信号重构:
min ⁡ s ∥ s ∥ 0   s . t .   y = Θ s \min_{s}\| s \|_0 \, \mathrm{s.t.} \, y=\Theta s smins0s.t.y=Θs
其中 ∥ ⋅ ∥ 0 \| \cdot \|_0 0 p 0 p_0 p0范数,表示 x x x中非零元素的个数,在实际求解中,一般将该约束松弛为 p 1 p_1 p1 p 2 p_2 p2等范数。
对于方程: y = Θ s y=\Theta s y=Θs,已知 y y y Θ \Theta Θ求解未知数 x x x时,如果超定方程,问题实质为拟合问题;如果 Θ \Theta Θ为满秩的方阵,问题则为线性方程组求解;当 Θ \Theta Θ为欠定时,才是稀疏恢复问题。
在仿真中,对接收信号的自相关矩阵 R x x R_{xx} Rxx做酉对角化后,取酉矩阵中最大特征值对应的特征向量作为稀疏恢复的观测值矩阵y,将波束形成矩阵 a a a作为传感器矩阵,稀疏恢复得到的 s s s即为DOA估计结果,即求解方程:
y = a s y=as y=as

FOCUSS~欠定系统聚焦法

在该方法中,首先确定 s 0 s_0 s0的迭代初始值为:
s 0 = a H i n v ( a a H ) y s_0=a^H\mathrm {inv}(aa^H)y s0=aHinv(aaH)y
迭代过程为:
W = d i a g ( s k 1 − λ s p e / 2 )   s k + 1 = W W H a H ∗ i n v ( a W W H a H + λ r e g I ) ∗ y W=\mathrm{diag}(s_k^{1-\lambda_{spe}/2}) \\ \, \\ s_{k+1}=WW^Ha^H*\mathrm{inv}(aWW^Ha^H+\lambda_{reg}I)*y W=diag(sk1λspe/2)sk+1=WWHaHinv(aWWHaH+λregI)y
其中, λ r e g \lambda_{reg} λreg为正则化因子,过大会趋于0解,过小结果发散; λ s p e \lambda_{spe} λspe为稀疏因子,效果等效于稀疏解的范数约束。
迭代次数超过最大给定次数,或误差小于误差限制 λ e r r \lambda_{err} λerr(即 ∥ s k + 1 − s k ∣ 2 ∥ s k ∥ < λ e r r \frac {\|s_{k+1}-s_k |_2}{\| s_k \|}<\lambda_{err} sksk+1sk2<λerr)时,结束迭代。

OMP~正交匹配追踪法

该方法的迭代步骤如:

  1. 初始化,令标签集 Ω m a s k \Omega_{mask} Ωmask为空集并初始化残差向量 r 0 = y r_0=y r0=y
  2. 辨识,求取传感器矩阵 a a a中与残差向量 r k r_k rk最强相关的原子,即 j k ∈ a r g   m a x ∣ < r k , ϕ j > ∣ j_k\in \mathrm{arg\, max|<r_k,\phi_j>|} jkargmax∣<rk,ϕj>,往 Ω m a s k \Omega_{mask} Ωmask中添加该原子的索引。
  3. 估计,最小化问题 m i n x ∥ y − Φ Ω k x ∥ 2 2 min_x \| y-\Phi_{\Omega_k}x \|_2^2 minxyΦΩkx22的最小二乘解为 x k = i n v ( Φ Ω k H Φ Ω k ) ∗ Φ Ω k H y x_k=\mathrm{inv}(\Phi_{\Omega_k}^H\Phi_{\Omega_k})*\Phi_{\Omega_k}^Hy xk=inv(ΦΩkHΦΩk)ΦΩkHy
  4. 更新残差, r k + 1 = [ I − Φ Ω k ( Φ Ω k T Φ Ω k ) − 1 Φ Ω k T ] y r_{k+1}=[I-\Phi_{\Omega_k}(\Phi_{\Omega_k}^T\Phi_{\Omega_k})^{-1}\Phi_{\Omega_k}^T]y rk+1=[IΦΩk(ΦΩkTΦΩk)1ΦΩkT]y
  5. 重复步骤2~4直到满足迭代停止条件,退出条件包括迭代次数达到字典的栅格数,或者 a ( : , Ω m a s k ) ′ ∗ a ( : , Ω m a s k ) a(:,\Omega_{mask})'*a(:,\Omega_{mask}) a(:,Ωmask)a(:,Ωmask)为奇异矩阵。
  6. 输出结果,
    x ( i ) = { x k ( i ) , i ∈ Ω m a s k 0 , 其它 x(i)=\left\{\begin{matrix} &x_k(i) &,& i \in \Omega_{mask} \\ &0 &, & 其它 \end{matrix}\right. x(i)={xk(i)0,,iΩmask其它

伪逆法

对于方程: y = a s y=as y=as,令解s为:
s = y H ∗ p i n v ( a ) H s=y^H*{\mathrm {pinv}(a)}^H s=yHpinv(a)H
该方法因为运算量较大且产生的不是稀疏解,在实际工程中很少使用,在仿真中仅用于效果对比。

EM-SBL~最大期望-稀疏贝叶斯学习法

SBL算法是稀疏信号重构的重要算法,涉及高斯分布、最大似然估计、贝叶斯公式等数学理论,由于推导过程比较复杂,主要是我懒得敲了,后续如果读者有强烈需要我再更新一下吧^_^,这里直接介绍推导结果。该方法迭代的步骤为:

  1. 初始化,令 Γ 0 = 0.1 ∗ I \Gamma_0=0.1*I Γ0=0.1I
  2. E-step,令 σ x = p i n v ( σ ( a H a + p i n v ( Γ k ) ) \sigma_x=\mathrm {pinv}(\sigma(a^Ha+\mathrm {pinv}(\Gamma_k)) σx=pinv(σ(aHa+pinv(Γk)),令 μ x = σ x σ − 1 a H R x x \mu_x=\sigma_x\sigma^{-1}a^HR_{xx} μx=σxσ1aHRxx,其中 σ \sigma σ表示阵列接收信号的估计噪声方差, R x x R_{xx} Rxx为接收信号的自相关矩阵。
  3. M-step,令 Γ k + 1 = μ x ( θ ) ∗ μ x ( θ ) H / N + σ x ( θ ) \Gamma_{k+1}=\mu_x(\theta)*\mu_x(\theta)^H/N+\sigma_x(\theta) Γk+1=μx(θ)μx(θ)H/N+σx(θ)
  4. 重复步骤2和3,直到达到最大迭代次数或 ∥ Γ k + 1 − Γ k ∥ 1 < 误差限 \|\Gamma_{k+1}-\Gamma_{k}\|_1<误差限 Γk+1Γk1<误差限

CVX~凸优化法

由于方程“ y = a s y=as y=as”的求解可以转化为凸优化问题:
a r g   m i n s ∥ s ∥ p   ,   s . t . ∥ y − a s ∥ 2 < λ l i m arg \, min_s \| s\|_p \, , \, \mathrm{s.t.} \|y-as\|_2<\lambda_{lim} argminssp,s.t.yas2<λlim
因此可以使用凸优化工具箱进行求解,并且还可以根据需要调整用于约束稀疏解 s s s的范数,当使用 p 1 p_1 p1范数时,上述优化将产生稀疏解,当范数 p p p增大时,相当于增加了松弛量,解密度会越来越大,从而变得越来越不稀疏。
λ l i m \lambda_{lim} λlim为收敛控制量,过小可能产生发散的结果,过大则可能产生非稀疏解。

仿真实现

代码下载

代码已上传到GitHub:https://github.com/highskyno1/MIMO_DOA

可修改的参数

  1. 载波频率 f 0 f_0 f0:信源发射信号的中心频率。
  2. 系统全局采样率 f g f_g fg:由于仿真是数字系统,该采样率为仿真所使用的全局采样率。
  3. 信号带宽 B W BW BW:信源发射信号的总带宽,当存在多个信源时,如果使用非相干生成模式,会根据总带宽为每个信源划分不重合的等长信号频段;否则所有信源使用整个带宽的频段。
  4. 目标来向角度 s r c a n g l e src_{angle} srcangle:目标真实的相对于阵元平面法线的入射角度,内部元素数量被计算为目标数。考虑到实际的MIMIO阵列的扫描角度一般只有120°,取值范围为[-60°,60°],如果要在这个范围外取值,请连同 s c a n a n g l e scan_{angle} scanangle一起修改。
  5. 阵元数量 M M M:MIMO阵列阵元数量。
  6. 快拍数 L L L:每个阵元的采样点个数。
  7. 信噪比snr:信源发出的信号被收到时的信噪比。
  8. 扫描角度 s c a n a n g l e scan_{angle} scanangle:控制波束形成矩阵的角度,也称为完备字典或DOA栅格,可以改变间隔以提高空域采样率,注意空域分辨率不因空域采样率的改变而改变。
  9. 是否使用空间平滑滤波is_space_smooth:逻辑变量,置为ture时使能空间平滑滤波以解决信源的相干性问题。
  10. 是否产生相干的信源is_coherent:逻辑变量,置为true时将产生频域重叠的相干信源。

仿真结果

常规情况

在信源不相干,信噪比达到20dB,阵元数和快拍数分别为32和128的情况下,DOA结果如下图所示,可见CBF法主瓣最宽、旁瓣最高,其次为EM-SBL方法。CBF、EM-SBL、Capon、MUSIC的主瓣宽度依次减少。在稀疏恢复类型的算法中,FOCUSS算法效果最佳,OMP算法产生了过多的假峰,PINV法和ML法则出现了与传统方法相当的主瓣宽度。CVX方法则没有得到正确的来向角估计。两种准则下的ESPRIT算法均估计出了正确的来向角。
尽管CVX算法的结果不太理想,但仍可以发现在p1范数约束下将产生较为稀疏的解,随着范数的增加,稀疏恢复结果变得越来越不稀疏。

常规情况下多种DOA评估算法的仿真结果

低信噪比情况

修改信噪比为0dB,仿真结果如下图所示,可见此时常规方法和MUSIC法仍然可以正常工作;ESPRIT算法估计的DOA角度出现偏差;稀疏恢复部分,FOCUSS方法仍然表现出良好的性能,OMP法的假峰消失,CVX方法的零陷刚好落在真实来波方向上。

低信噪比(0dB)情况下多种DOA评估算法的仿真结果

修改信噪比为-10dB,仿真结果如下图所示,此时大部分算法都只能找到其中的一个来向角。

低信噪比(-10dB)情况下多种DOA评估算法的仿真结果

相干信源情况

信源发射信号相干且使用平滑滤波时,仿真结果如下图所示,可见子空间类型算法和Capon法只能发现一个来向的角度,但稀疏恢复算法和CBF

信源发射信号相干且不使用平滑滤波时多种DOA评估算法的仿真结果

信源发射信号相干且使用平滑滤波时,设置等效阵元数量为14,仿真结果如下图所示,此时Capon法、MUSIC法变得正常,可以分辨两个来向的信号,但ESPRIT仍然无法使用。但由于等效阵元数的降低,DOA结果的主瓣变换,降低了空域分辨率,这与理论是符合的。

信源发射信号相干且使用平滑滤波时多种DOA评估算法的仿真结果

少快拍情况

基于正常情况设置快拍数为32个(刚好等于阵元数)时,仿真结果如下图所示,可见此时算法仍然可以正常工作。

少快拍(32个)情况下多种DOA评估算法的仿真结果

观察更极限的情况,设置快拍数为2,仿真结果如下图所示,可见此时CBF法仍然可以正常工作,Capon法出现了相当多的假峰,ESPRIT算法已无法正常工作。稀疏恢复类型的算法在此种情况下表现出了极佳的性能,FOCUSS算法可以准确地估计出来向角,CVX法可以正常工作但有一定误差,OMP算法在真实来向附近产生了多个假峰。

少快拍(2个)情况下多种DOA评估算法的仿真结果

仿真小结

  1. CBF算法是万精油,可以用在低信噪比、低快拍和信源相干情况下,低时间复杂度,少空间占用使得它时至今天仍然是DOA的主流算法之一,在你不知道使用什么算法时,不妨先试试CBF吧。
  2. 稀疏恢复算法是概率类型的算法,每次执行都可能产生不一样的结果,这种算法优点在于可以获得很高的分辨率(超分辨率识别),并且可以在低快拍和信源相干情况下使用,是当前除了机器学习算法外的研究主流,稀疏算法唯一的缺点在于它的鲁棒性欠佳,且只能在高信噪比下使用,高信噪比也对应了空域“稀疏”。

后语

心里话:终于写完了!!!这篇长文从代码重构,到撰写与敲公式前前后后画了差不多一个星期,文中的所有公式、符号和矩阵等都是用 L a t e x \mathcal{Latex} Latex手敲的,通过撰写这篇文章我的Latex技术又得到了精进。
这是三年后复出的第二弹,后面还有,敬请期待。
看到这里了,点个赞再走吧,让我知道有人把文章看完也是我写下去的动力!

附录代码

仅附录DOA主要部分的代码,完整代码的下载请前往GitHub。

DOA_CBF.m

function P_cbf = DOA_CBF(scan_a, R)
% DOA_CBF 基于常规波束形成法实现DOA估计
%   scan_a  需要估计的来波方向
%   R       快拍的协方差矩阵,L*L维,L为快拍数
%   P_cbf   各个scan_a栅格上的来波归一化强度

scan_len = size(scan_a,2);
P_cbf = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_cbf(i) = foo' * R * foo / (foo' * foo)^2;
end
P_cbf = abs(P_cbf);
P_cbf = P_cbf ./ max(P_cbf);
end

DOA_Capon.m

function P_capon = DOA_Capon(scan_a, R)
% DOA_Capon 基于Capon法实现DOA估计
%   scan_a  需要估计的来波方向
%   R       快拍的协方差矩阵,L*L维,L为快拍数
%   P_capon 各个scan_a栅格上的来波归一化强度

scan_len = size(scan_a,2);
P_capon = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_capon(i) = 1 / (foo' * pinv(R) * foo);
end
P_capon = abs(P_capon);
P_capon = P_capon ./ max(P_capon);
end

DOA_MUSIC

function P_music = DOA_MUSIC(U, target_len, scan_a)
% DOA_MUSIC 基于多重信号分类法实现DOA估计
%   U           对接收信号的自相关矩阵做酉对角化分解后的左酉矩阵
%   target_len  目标数量
%   rec_len     阵元数量
%   scan_a      DOA估计栅格

% 计算阵元数和栅格数
[rec_len,scan_len] = size(scan_a);
W = fliplr(U);
% 已知只有两个信源,用信号子空间法
U_s = W(:,1:target_len);
U_music = eye(rec_len) - U_s * U_s';
P_music = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_music(i) = 1 / (foo' * U_music * foo);
end
P_music = abs(P_music);
P_music = P_music ./ max(P_music);
end

DOA_ESPRIT.m

function [DOA_esp_ml, DOA_esp_tls] = DOA_ESPRIT(x_sig, target_len, lamda, d)
% DOA_ESPRIT 基于旋转不变子空间法实现DOA
%   x_sig       每个阵元接收到的信号矩阵,阵元数*快拍数
%   target_len  目标数量
%   lamda       载波波长
%   d           阵元间隔
%   DOA_esp_ml  基于最大似然估计准则得到的估计结果
%   DOA_esp_tls 基于最小二乘准则得到的估计结果

% 计算阵元数
rec_len = size(x_sig,1);
% 回波子阵列合并
x_esp = [x_sig(1:rec_len-1,:);x_sig(2:rec_len,:)];
% 计算协方差
R_esp = cov(x_esp');
% 特征分解
[~,~,W] = eig(R_esp);
% 获取信号子空间
W = fliplr(W);
U_s = W(:,1:target_len);
% 拆分
U_s1 = U_s(1:rec_len-1,:);
U_s2 = U_s(rec_len:end,:);

%% LS-ESPRIT法
mat_esp_ml = pinv(U_s1) * U_s2;
% 获取对角线元素并解算来向角
DOA_esp_ml = -angle(eig(mat_esp_ml));
DOA_esp_ml = asin(DOA_esp_ml .* lamda ./ 2 ./ pi ./ d);
DOA_esp_ml = rad2deg(DOA_esp_ml);

%% TLS-ESPRIT
V = [U_s1,U_s2];
[~,~,V] = svd(V);
% 提取E12和E22
E12 = V(1:target_len,target_len+1:end);
E22 = V(target_len+1:end,target_len+1:end);
mat_esp_tls = - E12 / E22;
% 获取对角线元素并解算来向角
DOA_esp_tls = -angle(eig(mat_esp_tls));
DOA_esp_tls = asin(DOA_esp_tls .* lamda ./ 2 ./ pi ./ d);
DOA_esp_tls = rad2deg(DOA_esp_tls);
end

DOA_ML.m

function P_ml = DOA_ML(scan_a, R_sig)
% DOA_ML 基于最大似然估计法得到DOA估计
%   scan_a  DOA估计栅格矩阵
%   R_sig   接收信号的自相关矩阵,阵元数*阵元数
%   P_ml    通过ML法得到的归一化估计结果

% 计算阵元数和栅格数
[rec_len,scan_len] = size(scan_a);
P_ml = zeros(1,scan_len);
for i = 1:scan_len
    scan = scan_a(:,i);
    Pa = scan / (scan'*scan) * scan';
    P_ml(i) = trace(Pa*R_sig) / rec_len;
end
P_ml = abs(P_ml);
P_ml = P_ml ./ max(P_ml);
end

DOA_FOCUSS.m

function P_focuss = DOA_FOCUSS(scan_a, u, lamda_spe, lamda_reg, lamda_err)
% DOA_FOCUSS 基于欠定系统局灶解法(Focal Under determinedSystem Solver)
% 实现稀疏恢复获得DOA估计结果
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   u           对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   lamda_spe   稀疏因子,效果类似于结果的范数约束
%   lamda_reg   正则化因子,过大会趋于0解,过小结果发散
%   lamda_err   迭代结束误差
%   P_focuss    通过FOCUSS法得到的归一化来波方向功率估计

% 计算阵元数
rec_len = size(u,1);
% 确定s的初始值
Dg = scan_a;
s0 = Dg' / (Dg * Dg') * u;
for i = 1:1000
    W = diag(s0.^(1-lamda_spe/2));
    s = W * W' * Dg' / (Dg * (W * W') * Dg' + lamda_reg .* eye(rec_len)) * u;
    if norm(s - s0,2) / norm(s0,2) < lamda_err
        break;
    end
    s0 = s;
end
P_focuss = abs(s);
% 数据饱和钳制
P_focuss = P_focuss ./ max(P_focuss);
P_focuss(P_focuss < 1e-4) = 1e-4;
end

DOA_OMP.m

function P_omp = DOA_OMP(u, scan_a, omp_toler)
% 基于正交匹配追踪法实现来波的DOA估计
%   u           对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   omp_toler   容许的最小误差,低于此误差时结束迭代
%   P_omp       基于OMP法得到的不同方向来波功率估计

% 计算阵元数量和栅格数量
[rec_len,scan_len] = size(scan_a);
% 初始化标签集合
omp_omiga_mask = zeros(1,scan_len,'logical');
% 初始化初始向量
omp_r = u;
for i = 1:scan_len
    % 求字典矩阵中与残差向量rk-1最强相关的原子
    foo = abs(omp_r' * scan_a);
    [~,idx] = max(foo);
    % 往omiga中添加该列索引
    omp_omiga_mask(idx) = true;
    % 依据索引从字典中选出需要的列向量
    omp_omiga_foo = scan_a(:,omp_omiga_mask);
    % 奇异判断
    rms = det(omp_omiga_foo' * omp_omiga_foo);
    % 退出条件
    if rms < omp_toler
        break;
    end
    % 最小化min(x) ||y-fa*x|| L2范数的平方最小
    omp_xk = (omp_omiga_foo' * omp_omiga_foo) \ omp_omiga_foo' * u;
    % 更新残差
    omp_r = (eye(rec_len) - omp_omiga_foo / (omp_omiga_foo.'*omp_omiga_foo) * omp_omiga_foo.') * u;
end
P_omp = zeros(1,scan_len);
% 提取结果
foo = find(omp_omiga_mask==true);
P_omp(foo(1:length(omp_xk))) = abs(omp_xk)';
% 归一化
P_omp = P_omp ./ max(P_omp);
P_omp(P_omp < 1e-4) = 1e-4;
end

DOA_PINV.m

function s_pinv = DOA_PINV(u, scan_a)
% DOA_PINV 基于伪逆法实现稀疏恢复,效果等同于最大似然估计法
%   u       对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a  DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   s_pinv  基于PINV法得到的不同来波方向的归一化功率

s_pinv = u' * pinv(scan_a)';
s_pinv = abs(s_pinv);
s_pinv = s_pinv ./ max(s_pinv);
end

DOA_EM_SBL.m

function s_sbl = DOA_EM_SBL(sigma, scan_a, R_sig, shot_len, err_lim, times_lim)
% 基于期望最大化-稀疏贝叶斯学习方法实现DOA估计
%   sigma       估计的噪声方差
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   R_sig       回波自相关矩阵
%   shot_len    快拍数
%   err_lim     迭代误差限,迭代退出的条件之一
%   times_lim   迭代次数限制,迭代退出的条件之二

% 计算DOA栅格数量
scan_len = size(scan_a,2);
times_cnt = 0;
Gamma = eye(scan_len)*0.1;  % 初始Gamma矩阵
while true 
    times_cnt = times_cnt + 1;
    % E-step
    Sigma_x = pinv(sigma * (scan_a'*scan_a) + pinv(Gamma));
    Mu_x = Sigma_x / sigma * scan_a' * R_sig;
    % M-step
    Gamma_new = Gamma;
    for i = 1:scan_len
        mu_xn = Mu_x(i,:); 
        Gamma_new(i,i) = mu_xn*mu_xn'/shot_len + Sigma_x(i,i);
    end
    if sum(abs(diag(Gamma_new - Gamma))) < err_lim || times_cnt > times_lim
        break;
    end
    Gamma = Gamma_new;
end
Gamma_new = abs(diag(Gamma_new));
s_sbl = Gamma_new ./ max(Gamma_new);
end

DOA_CVX.m

function s_cvx = DOA_CVX(u, scan_a, p_norm, tor_lim)
% DOA_CVX 尝试利用凸优化方法实现稀疏恢复,获得DOA估计
%   !!使用前必须先安装CVX凸优化工具箱,下载地址为:http://cvxr.com/cvx/download/
%   u       对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a  DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   s_cvx   基于CVX法得到的不同方向来波功率估计
%   p_norm  约束结果的P范数
%   tor_lim 对稀疏恢复整体(u - scan_a * s_cvx)的容许限度
%           如果结果为+inf,说明发散了,请增大该值
% 注意在CVX工具箱的scope中
% 尽量调用工具箱自己的函数(定义在CVX解压目录/functions 文件夹下)
% 使用MATLAB定义的函数可能会有问题

% 计算DOA栅格数量
scan_len = size(scan_a,2);
%% CVX工具箱调用语法~开始
cvx_begin
variable s_cvx(scan_len,1)
minimize(  sum(pow_abs(s_cvx, p_norm)) );
subject to
    sum(pow_abs(u - scan_a * s_cvx,2)) <= tor_lim;
cvx_end
% CVX工具箱调用语法~结束
s_cvx = abs(s_cvx);
s_cvx = s_cvx ./ max(s_cvx);
end

space_smooth.m

function R_sig = space_smooth(rec_len, equ_l, x_sig)
% 基于空间平滑法解决相干信源问题
%   rec_len 真实阵元数量
%   equ_l   等效阵元数量
%   x_sig   回波矩阵,真实阵元数量*快拍数

% 计算平滑阵元数量
rec_len_equ = rec_len - equ_l + 1;
% 计算子阵的自相关
R_sig = zeros(equ_l,equ_l);
for i = 1:rec_len_equ
    % 第i个子阵
    foo = x_sig(i:equ_l+i-1,:);
    % 计算协方差
    R_sig = R_sig + (foo * foo')./rec_len;
end
R_sig = R_sig ./ rec_len_equ;
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1421701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓主板_紫光展锐T820安卓主板方案定制

安卓主板采用了性能强劲的紫光展锐T820八核处理器&#xff0c;搭载了Android 13系统&#xff0c;为用户带来更加顺畅的操作体验。该主板不仅采用了6nm工艺&#xff0c;更加强大的算力和优越的性能&#xff0c;能够轻松实现多任务运行&#xff0c;不会出现卡顿现象。 此外&#…

04:容器技术概述|镜像与容器|docker配置管理

容器技术概述&#xff5c;镜像与容器&#xff5c;docker配置管理 什么是容器优点缺点 docker与容器跳板机yum源添加docker软件在node节点验证软件包开启路由转发 镜像管理&容器管理如何获取镜像镜像备份与恢复运行容器查看镜像的启动信息镜像管理命令容器管理命令容器内部署…

用C#实现最小二乘法(用OxyPlot绘图)

最小二乘法介绍✨ 最小二乘法&#xff08;Least Squares Method&#xff09;是一种常见的数学优化技术&#xff0c;广泛应用于数据拟合、回归分析和参数估计等领域。其目标是通过最小化残差平方和来找到一组参数&#xff0c;使得模型预测值与观测值之间的差异最小化。 最小二…

2023年春秋杯网络安全联赛冬季赛_做题记录

可信计算 基于挑战码的双向认证1 可信计算赛题-双向认证挑战模式.docx 使用命令进行SSH登录上去 ssh player8.147.131.156 -p 18341 # 记得加上-p参数指定端口&#xff0c;不然默认的是22端口看见word文档的提示&#xff0c;先尝试一下 直接获得了flag1 web 魔术方…

public class和class的区别

不用public修饰的类 一个Java源文件中可以定义多个不用public修饰的class&#xff0c;且类名不用和java源文件名一致。public修饰的类可以没有。编译之后&#xff0c;一个class就会对应生成一个class字节码文件 对于用public修饰的类 如果一个类用了public修饰&#xff0c;那…

成功解决Error:AttributeError: module ‘numpy‘ has no attribute ‘long‘.

成功解决Error&#xff1a;AttributeError: module ‘numpy‘ has no attribute ‘long‘. &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;报错分析&#x1f333;&#x1f333;解决方案1&#xff1a;降低NumPy版本&#x1f333;&#x1f333…

Github 上传项目(个人令牌token)

1.点击 github头像 &#xff1a; setting -> Developer Settings -> Personal access tokens 2.在要上传的文件夹下运行以下命令&#xff1a; git init git commit -m "first commit" git branch -M main 利用以下命令模…

使用流服务器m7s对接gb28181

优&#xff1a;sip品牌兼容性比较好&#xff0c;大华&#xff0c;海康都稳定可以&#xff0c;srs的5.0 sip品牌兼容性大华没反应&#xff0c;akstream-sip 大华也有问题&#xff0c;wvp也还可以 缺&#xff1a;目前最新的4.7.4版本&#xff0c;&#xff0c;sip协议用udp正常&a…

IP 层转发分组的过程

目录 IP 层转发分组的过程 1.1 基于终点的转发 1.2 最长前缀匹配 转发表中的 2 种特殊的路由 主机路由 (host route) 默认路由 (default route) 路由器分组转发算法 1.3 使用二叉线索查找转发表 IP 层转发分组的过程 1.1 基于终点的转发 分组在互联网中是逐跳转发的。…

Angular组件(二) 分割面板ShrinkSplitter

Angular组件(二) 分割面板ShrinkSplitter 前言 在Angular组件(一) 分割面板ShrinkSplitter文章中我们实现了Splitter组件&#xff0c;后来在业务场景中发现在开关右侧容器和底部容器时&#xff0c;使用起来不方便&#xff0c;ngModel绑定的值始终是左侧容器和顶部容器的大小&…

电路分享 —— 单片机 1个IO口检测多路按键

一、设计要求 设计要求&#xff1a;因为单片机的IO口数量较少&#xff0c;要求使用1路IO口检测4路按键。 二、设计思路 设计思路&#xff1a;单片机的IO口数量较少的情况下&#xff0c;使用1路IO口检测4路按键&#xff0c;可以通过检测电压值来进行区分&#xff0c;即使用IO口…

如何纯前端实现文件下载

业务场景 有一个下载文件的功能&#xff0c;不引入后端资源&#xff0c;纯前端应该如何实现&#xff1f; 解决方案 在vue2或者vue3项目中&#xff0c;可以把文件放在 public 文件夹下&#xff0c;然后使用a标签进行文件下载。 如&#xff1a;我要下载的文件是模版.xlsx 。首…

STM32学习笔记二——STM32时钟源时钟树

目录 STM32芯片内部系统架构详细讲解&#xff1a; 1.芯片内部混乱电信号解决方案&#xff1a; 2.时钟树&#xff1a; 1.内部RC振荡器与外部晶振的选择 2. STM32 时钟源 3.STM32中几个与时钟相关的概念 4.时钟输出的使能及其流程 5.时钟设置的基本流程 时钟源——单片机…

应用下载页源码简洁高大尚下载单页

首先可以设置多个下载源 软件截图可以滚动 暗夜主题交换 图片都可以自定义配置 精美的页面会让你眼前一亮的 源代码学习资料&#xff1a;https://pan.baidu.com/s/1ulE9zde2XMs-6E7eF3D3kg?pwdfhxq 密码&#xff1a;123

1178:单词数

题目描述 统计一篇文章里不同单词的总数。 输入 有多组数据&#xff0c;每组一行&#xff0c;每组就是一篇小文章。每篇小文章都是由大小写字母和空格组成&#xff0c;没有标点符号&#xff0c;遇到#时表示输入结束。每篇文章的单词数小于1000&#xff0c;每个单词最多由30个…

系统分析师-22年-下午题目

系统分析师-22年-下午题目 更多软考知识请访问 https://ruankao.blog.csdn.net/ 试题一必答&#xff0c;二、三、四、五题中任选其中两题作答 试题一 (25分) 说明 某软件公司拟开发一套博客系统&#xff0c;要求能够向用户提供一个便捷发布自已心得&#xff0c;及时有效的…

Cmake编译Opencv3.3.1遇到有些文件无法下载的错误解决:

前言&#xff1a; 对于&#xff0c;opencv有些配置文件错误并未致命&#xff0c;所以&#xff0c;有错误也不影响后续的编译&#xff1a;但是&#xff0c;后引用如果要用&#xff0c;在回过头来还是要解决的。 问题表述&#xff1a; 比如&#xff0c;有些文件下载的错误&am…

穷游网酒店数据采集与可视化分析与实现

摘 要 穷游网酒店数据采集与可视化分析大屏的背景是为了满足用户对酒店数据的需求以及提供数据洞察和决策支持。随着旅游业的快速发展&#xff0c;人们对酒店信息的需求日益增加&#xff0c;而穷游网作为一家专注于旅游信息的网站&#xff0c;拥有丰富的酒店数据资源。 这个大…

JS基础 - 遍历对象方法(6种)

初始值&#xff1a; var obj {a: 1,b: 2,c: 3,d: 4,e: 5,}; 第一种&#xff1a;for in for (let key in obj) {console.log(key ":" obj[key]);} 第二种&#xff1a;Object.keys 获取key Object.keys(obj).forEach((key) > {console.log(key ":" …

【乳腺肿瘤诊断分类及预测】基于Elman神经网络

课题名称&#xff1a;基于Elman神经网络的乳腺肿瘤诊断分类及预测 版本日期&#xff1a;2023-05-15 运行方式: 直接运行Elman0501.m 文件即可 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 威斯康辛大学医学院经过多年的收集和整理&a…